diff --git a/src/plumbing/globalheaders.c b/src/plumbing/globalheaders.c index 6311b236..b948c61a 100644 --- a/src/plumbing/globalheaders.c +++ b/src/plumbing/globalheaders.c @@ -175,6 +175,11 @@ gh_queue_delay(globalheaders_t *gh, int index) diff = (l->pr_pkt->pkt_dts & PTS_MASK) - (f->pr_pkt->pkt_dts & PTS_MASK); if (diff < 0) diff += PTS_MASK; + + /* special noop packet from transcoder, increase decision limit */ + if (l == f && l->pr_pkt->pkt_payload == NULL) + return 1; + return diff; } @@ -290,9 +295,12 @@ gh_hold(globalheaders_t *gh, streaming_message_t *sm) // Send all pending packets while((pr = TAILQ_FIRST(&gh->gh_holdq)) != NULL) { TAILQ_REMOVE(&gh->gh_holdq, pr, pr_link); - sm = streaming_msg_create_pkt(pr->pr_pkt); - streaming_target_deliver2(gh->gh_output, sm); - pkt_ref_dec(pr->pr_pkt); + pkt = pr->pr_pkt; + if (pkt->pkt_payload) { + sm = streaming_msg_create_pkt(pkt); + streaming_target_deliver2(gh->gh_output, sm); + } + pkt_ref_dec(pkt); free(pr); } gh->gh_passthru = 1; @@ -329,6 +337,7 @@ gh_hold(globalheaders_t *gh, streaming_message_t *sm) static void gh_pass(globalheaders_t *gh, streaming_message_t *sm) { + th_pkt_t *pkt; switch(sm->sm_type) { case SMT_START: /* stop */ @@ -347,13 +356,19 @@ gh_pass(globalheaders_t *gh, streaming_message_t *sm) case SMT_SERVICE_STATUS: case SMT_SIGNAL_STATUS: case SMT_NOSTART: - case SMT_PACKET: case SMT_MPEGTS: case SMT_SKIP: case SMT_SPEED: case SMT_TIMESHIFT_STATUS: streaming_target_deliver2(gh->gh_output, sm); break; + case SMT_PACKET: + pkt = sm->sm_data; + if (pkt->pkt_payload) + streaming_target_deliver2(gh->gh_output, sm); + else + streaming_msg_free(sm); + break; } } diff --git a/src/plumbing/transcoding.c b/src/plumbing/transcoding.c index 1448d617..e1fc55e7 100644 --- a/src/plumbing/transcoding.c +++ b/src/plumbing/transcoding.c @@ -96,6 +96,8 @@ typedef struct video_stream { int16_t vid_width; int16_t vid_height; + + int vid_first_sent; } video_stream_t; @@ -329,10 +331,10 @@ create_adts_header(pktbuf_t *pb, int sri, int channels) init_wbits(&bs, pktbuf_ptr(pb), 56); put_bits(&bs, 0xfff, 12); // Sync marker - put_bits(&bs, 0, 1); // ID 0 = MPEG 4 + put_bits(&bs, 1, 1); // ID 0 = MPEG 4, 1 = MPEG 2 put_bits(&bs, 0, 2); // Layer put_bits(&bs, 1, 1); // Protection absent - put_bits(&bs, 2, 2); // AOT + put_bits(&bs, 1, 2); // AOT, 1 = AAC Main put_bits(&bs, sri, 4); put_bits(&bs, 1, 1); // Private bit put_bits(&bs, channels, 3); @@ -341,7 +343,7 @@ create_adts_header(pktbuf_t *pb, int sri, int channels) put_bits(&bs, 1, 1); // Copyright identification bit put_bits(&bs, 1, 1); // Copyright identification start - put_bits(&bs, pktbuf_len(pb), 13); + put_bits(&bs, pktbuf_len(pb) + 7, 13); put_bits(&bs, 0, 11); // Buffer fullness put_bits(&bs, 0, 2); // RDB in frame } @@ -941,6 +943,8 @@ transcoder_stream_video(transcoder_t *t, transcoder_stream_t *ts, th_pkt_t *pkt) uint8_t *buf, *deint; int length, len, ret, got_picture, got_output, got_ref; video_stream_t *vs = (video_stream_t*)ts; + streaming_message_t *sm; + th_pkt_t *pkt2; av_init_packet(&packet); av_init_packet(&packet2); @@ -969,6 +973,17 @@ transcoder_stream_video(transcoder_t *t, transcoder_stream_t *ts, th_pkt_t *pkt) } } + if (!vs->vid_first_sent) { + /* notify global headers that we're live */ + /* the video packets might be delayed */ + pkt2 = pkt_alloc(NULL, 0, pkt->pkt_pts, pkt->pkt_dts); + pkt2->pkt_componentindex = pkt->pkt_componentindex; + sm = streaming_msg_create_pkt(pkt2); + streaming_target_deliver2(ts->ts_target, sm); + pkt_ref_dec(pkt); + vs->vid_first_sent = 1; + } + packet.data = pktbuf_ptr(pkt->pkt_payload); packet.size = pktbuf_len(pkt->pkt_payload); packet.pts = pkt->pkt_pts;