TT#28163 pass encoded packets back to processing for sending out

Change-Id: Icdd49d174336277dae0c2c79854fc4e3b42a5c44
changes/22/18622/9
Richard Fuchs 8 years ago
parent dc80c27af7
commit df537b98c3

@ -12,10 +12,13 @@
struct codec_ssrc_handler {
struct ssrc_entry h; // must be first
struct codec_handler *handler;
mutex_t lock;
packet_sequencer_t sequencer;
decoder_t *decoder;
encoder_t *encoder;
unsigned long ts_offset;
u_int16_t seq_out;
};
struct transcode_packet {
seq_packet_t p; // must be first
@ -302,8 +305,11 @@ static void __transcode_packet_free(struct transcode_packet *p) {
static struct ssrc_entry *__ssrc_handler_new(void *p) {
struct codec_handler *h = p;
struct codec_ssrc_handler *ch = g_slice_alloc0(sizeof(*ch));
ch->handler = h;
mutex_init(&ch->lock);
packet_sequencer_init(&ch->sequencer, (GDestroyNotify) __transcode_packet_free);
ch->seq_out = random();
ch->ts_offset = random();
ch->decoder = decoder_new_fmt(h->source_pt.codec_def, h->source_pt.clock_rate, 1, 0);
if (!ch->decoder)
goto err;
@ -329,8 +335,33 @@ static void __ssrc_handler_free(struct codec_ssrc_handler *ch) {
}
static int __packet_encoded(encoder_t *enc, void *u1, void *u2) {
struct codec_ssrc_handler *ch = u1;
GQueue *out_q = u2;
ilog(LOG_DEBUG, "RTP media successfully encoded: TS %llu, len %i",
(unsigned long long) enc->avpkt.pts, enc->avpkt.size);
// reconstruct RTP header
unsigned int pkt_len = enc->avpkt.size + sizeof(struct rtp_header);
char *buf = malloc(pkt_len);
struct rtp_header *rh = (void *) buf;
ZERO(*rh);
rh->v_p_x_cc = 0x80;
rh->m_pt = ch->handler->dest_pt.payload_type;
rh->seq_num = htons(ch->seq_out++);
rh->timestamp = htonl(enc->avpkt.pts + ch->ts_offset);
rh->ssrc = ch->h.ssrc;
// XXX use writev() for output? would make sense if enc->avpkt.data can be stolen
memcpy(buf + sizeof(struct rtp_header), enc->avpkt.data, enc->avpkt.size);
struct codec_packet *p = g_slice_alloc(sizeof(*p));
p->s.s = buf;
p->s.len = pkt_len;
p->free_func = free;
g_queue_push_tail(out_q, p);
return 0;
}
@ -342,7 +373,7 @@ static int __packet_decoded(decoder_t *decoder, AVFrame *frame, void *u1, void *
// XXX resample...
encoder_input_data(ch->encoder, frame, __packet_encoded, ch, NULL);
encoder_input_data(ch->encoder, frame, __packet_encoded, ch, u2);
av_frame_free(&frame);
return 0;
@ -391,7 +422,7 @@ static int handler_func_transcode(struct codec_handler *h, struct call_media *me
ilog(LOG_DEBUG, "Decoding RTP packet: seq %u, TS %lu",
packet->p.seq, packet->ts);
if (decoder_input_data(ch->decoder, packet->payload, packet->ts, __packet_decoded, ch, NULL))
if (decoder_input_data(ch->decoder, packet->payload, packet->ts, __packet_decoded, ch, out))
ilog(LOG_WARN, "Decoder error while processing RTP packet");
__transcode_packet_free(packet);
}

@ -368,7 +368,9 @@ sub _input {
# must be RTP or RTCP input
my $exp = shift(@{$self->{media_receive_queues}->[$component]}) or die;
$$input eq $exp or die;
if (!$self->{args}->{no_data_check}) {
$$input eq $exp or die;
}
$self->{media_packets_received}->[$component]++;
$$input = '';

@ -7,8 +7,8 @@ use IO::Socket;
my $r = NGCP::Rtpengine::Test->new();
my ($a, $b) = $r->client_pair(
{sockdomain => &Socket::AF_INET, codecs => [qw(PCMA)]},
{sockdomain => &Socket::AF_INET, codecs => [qw(PCMU)]}
{sockdomain => &Socket::AF_INET, codecs => [qw(PCMA)], no_data_check => 1},
{sockdomain => &Socket::AF_INET, codecs => [qw(PCMU)], no_data_check => 1}
);
$r->timer_once(3, sub {

Loading…
Cancel
Save