]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
transcode: fix the video timeout in globalheaders, including AAC ADTS header fix
authorJaroslav Kysela <perex@perex.cz>
Mon, 12 Jan 2015 21:00:11 +0000 (22:00 +0100)
committerJaroslav Kysela <perex@perex.cz>
Mon, 12 Jan 2015 21:00:44 +0000 (22:00 +0100)
src/plumbing/globalheaders.c
src/plumbing/transcoding.c

index 6311b23651c114e9230b76adb98cadeec1bd21fe..b948c61aa8b3b8873b2eed5b86892dc7784a6881 100644 (file)
@@ -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;
   }
 }
 
index 1448d617109436eaadbed19abc3cb7dfac04155a..e1fc55e73b1112d3b61ffc1e3e13d449720995d3 100644 (file)
@@ -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;