]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
transcode: ffmpeg fixes, VP8 & VORBIS works
authorJaroslav Kysela <perex@perex.cz>
Fri, 10 Oct 2014 17:43:55 +0000 (19:43 +0200)
committerJaroslav Kysela <perex@perex.cz>
Fri, 10 Oct 2014 17:45:44 +0000 (19:45 +0200)
Does not work (for me):
 - H264
 - Audio sync for vorbis..

src/plumbing/transcoding.c
src/profile.c

index 092adcd23f4e8fb7868442f6ac7b2cf324a67362..f20092d60f0978a7b7da136146e568952c713fce 100644 (file)
@@ -131,6 +131,26 @@ typedef struct transcoder {
 /**
  * 
  */
+static AVCodecContext *
+avcodec_alloc_context3_tvh(const AVCodec *codec)
+{
+  AVCodecContext *ctx = avcodec_alloc_context3(codec);
+  if (ctx)
+    ctx->codec_id = AV_CODEC_ID_NONE;
+  return ctx;
+}
+
+static char *const
+get_error_text(const int error)
+{
+  static char __thread error_buffer[255];
+  av_strerror(error, error_buffer, sizeof(error_buffer));
+  return error_buffer;
+}
+
+/**
+ *
+ */
 static AVCodec *
 transcoder_get_decoder(streaming_component_type_t ty)
 {
@@ -200,6 +220,7 @@ transcoder_stream_packet(transcoder_stream_t *ts, th_pkt_t *pkt)
 {
   streaming_message_t *sm;
 
+  tvhtrace("transcode", "deliver copy (pts = %" PRIu64 ")", pkt->pkt_pts);
   sm = streaming_msg_create_pkt(pkt);
   streaming_target_deliver2(ts->ts_target, sm);
   pkt_ref_dec(pkt);
@@ -246,8 +267,8 @@ transcoder_stream_subtitle(transcoder_stream_t *ts, th_pkt_t *pkt)
 
   length = avcodec_decode_subtitle2(ictx,  &sub, &got_subtitle, &packet);
   if (length <= 0) {
-    tvhlog(LOG_ERR, "transcode", "Unable to decode subtitle (%d)", length);
-    ts->ts_index = 0;
+    if (length == AVERROR_INVALIDDATA) goto cleanup;
+    tvhlog(LOG_ERR, "transcode", "Unable to decode subtitle (%d, %s)", length, get_error_text(length));
     goto cleanup;
   }
 
@@ -321,8 +342,8 @@ transcoder_stream_audio(transcoder_stream_t *ts, th_pkt_t *pkt)
 
   samples = (short*)(as->aud_dec_sample + as->aud_dec_offset);
   if ((length = avcodec_decode_audio3(ictx, samples, &len, &packet)) <= 0) {
-    tvhlog(LOG_ERR, "transcode", "Unable to decode audio (%d)", length);
-    ts->ts_index = 0;
+    if (length == AVERROR_INVALIDDATA) goto cleanup;
+    tvhlog(LOG_ERR, "transcode", "Unable to decode audio (%d, %s)", length, get_error_text(length));
     goto cleanup;
   }
 
@@ -407,6 +428,7 @@ transcoder_stream_audio(transcoder_stream_t *ts, th_pkt_t *pkt)
   }
 
   if (octx->codec_id == AV_CODEC_ID_NONE) {
+    as->aud_enc_pts = pkt->pkt_pts;
     octx->codec_id = ocodec->id;
 
     if (avcodec_open2(octx, ocodec, NULL) < 0) {
@@ -449,6 +471,7 @@ transcoder_stream_audio(transcoder_stream_t *ts, th_pkt_t *pkt)
       if (octx->extradata_size)
        n->pkt_header = pktbuf_alloc(octx->extradata, octx->extradata_size);
 
+      tvhtrace("transcode", "deliver audio (pts = %" PRIu64 ")", pkt->pkt_pts);
       sm = streaming_msg_create_pkt(n);
       streaming_target_deliver2(ts->ts_target, sm);
       pkt_ref_dec(n);
@@ -467,13 +490,6 @@ transcoder_stream_audio(transcoder_stream_t *ts, th_pkt_t *pkt)
 }
 #else
 
-static char *const get_error_text(const int error)
-{
-  static char error_buffer[255];
-  av_strerror(error, error_buffer, sizeof(error_buffer));
-  return error_buffer;
-}
-
 /**
  *
  */
@@ -543,7 +559,8 @@ transcoder_stream_audio(transcoder_stream_t *ts, th_pkt_t *pkt)
     tvhtrace("transcode", "Did not have a full frame in the packet");
 
   if (length < 0) {
-    tvhlog(LOG_ERR, "transcode", "Unable to decode audio (%d)", length);
+    if (length == AVERROR_INVALIDDATA) goto cleanup;
+    tvhlog(LOG_ERR, "transcode", "Unable to decode audio (%d, %s)", length, get_error_text(length));
     ts->ts_index = 0;
     goto cleanup;
   }
@@ -558,6 +575,7 @@ transcoder_stream_audio(transcoder_stream_t *ts, th_pkt_t *pkt)
   }
 
   if (octx->codec_id == AV_CODEC_ID_NONE) {
+    as->aud_enc_pts       = pkt->pkt_pts;
     octx->sample_rate     = ictx->sample_rate;
     octx->sample_fmt      = ictx->sample_fmt;
     if (ocodec->sample_fmts) {
@@ -565,13 +583,15 @@ transcoder_stream_audio(transcoder_stream_t *ts, th_pkt_t *pkt)
       int acount = 0;
       octx->sample_fmt = -1;
       while ((octx->sample_fmt == -1) && (ocodec->sample_fmts[acount] > -1)) {
-        if (ocodec->sample_fmts[acount] == ictx->sample_fmt)
+        if (ocodec->sample_fmts[acount] == ictx->sample_fmt) {
           octx->sample_fmt = ictx->sample_fmt;
+          break;
+        }
         acount++;
       }
       if (octx->sample_fmt == -1) {
         if (acount > 0) {
-          tvhlog(LOG_DEBUG, "transcode", "Did not find matching sample_fmt for encoder. Will use first supported: %d.", ocodec->sample_fmts[acount-1]);
+          tvhtrace("transcode", "Did not find matching sample_fmt for encoder. Will use first supported: %d", ocodec->sample_fmts[acount-1]);
           octx->sample_fmt = ocodec->sample_fmts[acount-1];
         }
         else {
@@ -581,7 +601,7 @@ transcoder_stream_audio(transcoder_stream_t *ts, th_pkt_t *pkt)
         }
       }
       else {
-        tvhlog(LOG_DEBUG, "transcode", "Encoder supports same sample_fmt as decoder");
+        tvhtrace("transcode", "Encoder supports same sample_fmt as decoder");
       }
     }
 
@@ -852,6 +872,7 @@ transcoder_stream_audio(transcoder_stream_t *ts, th_pkt_t *pkt)
     frame = av_frame_alloc();
     frame->nb_samples = octx->frame_size;
     frame->format = octx->sample_fmt;
+    frame->channels = octx->channels;
     frame->channel_layout = octx->channel_layout;
     frame->sample_rate = octx->sample_rate;
     if (av_frame_get_buffer(frame, 0) < 0) {
@@ -885,7 +906,6 @@ transcoder_stream_audio(transcoder_stream_t *ts, th_pkt_t *pkt)
 
     } else if (got_packet_ptr) {
       length = packet.size;
-      tvhtrace("transcode", "encoded: packet.pts=%" PRIu64 ", packet.dts=%" PRIu64 ", as->aud_enc_pts=%lu", packet.pts, packet.dts, as->aud_enc_pts);
       n = pkt_alloc(packet.data, packet.size, as->aud_enc_pts, as->aud_enc_pts);
       n->pkt_componentindex = ts->ts_index;
       n->pkt_frametype      = pkt->pkt_frametype;
@@ -902,6 +922,7 @@ transcoder_stream_audio(transcoder_stream_t *ts, th_pkt_t *pkt)
       if (octx->extradata_size)
        n->pkt_header = pktbuf_alloc(octx->extradata, octx->extradata_size);
 
+      tvhtrace("transcode", "deliver audio (pts = %" PRIu64 ")", pkt->pkt_pts);
       sm = streaming_msg_create_pkt(n);
       streaming_target_deliver2(ts->ts_target, sm);
       pkt_ref_dec(n);
@@ -1043,6 +1064,7 @@ Minimal of 12 bytes.
     }
   }
 
+  tvhtrace("transcode", "deliver video (pts = %" PRIu64 ")", pkt->pkt_pts);
   sm = streaming_msg_create_pkt(n);
   streaming_target_deliver2(ts->ts_target, sm);
   pkt_ref_dec(n);
@@ -1104,8 +1126,8 @@ transcoder_stream_video(transcoder_stream_t *ts, th_pkt_t *pkt)
 
   length = avcodec_decode_video2(ictx, vs->vid_dec_frame, &got_picture, &packet);
   if (length <= 0) {
-    tvhlog(LOG_ERR, "transcode", "Unable to decode video (%d)", length);
-    ts->ts_index = 0;
+    if (length == AVERROR_INVALIDDATA) goto cleanup;
+    tvhlog(LOG_ERR, "transcode", "Unable to decode video (%d, %s)", length, get_error_text(length));
     goto cleanup;
   }
 
@@ -1426,8 +1448,8 @@ transcoder_init_subtitle(transcoder_t *t, streaming_start_component_t *ssc)
   ss->sub_icodec = icodec;
   ss->sub_ocodec = ocodec;
 
-  ss->sub_ictx = avcodec_alloc_context3(icodec);
-  ss->sub_octx = avcodec_alloc_context3(ocodec);
+  ss->sub_ictx = avcodec_alloc_context3_tvh(icodec);
+  ss->sub_octx = avcodec_alloc_context3_tvh(ocodec);
 
   LIST_INSERT_HEAD(&t->t_stream_list, (transcoder_stream_t*)ss, ts_link);
 
@@ -1520,8 +1542,8 @@ transcoder_init_audio(transcoder_t *t, streaming_start_component_t *ssc)
   as->aud_icodec = icodec;
   as->aud_ocodec = ocodec;
 
-  as->aud_ictx = avcodec_alloc_context3(icodec);
-  as->aud_octx = avcodec_alloc_context3(ocodec);
+  as->aud_ictx = avcodec_alloc_context3_tvh(icodec);
+  as->aud_octx = avcodec_alloc_context3_tvh(ocodec);
 
   as->aud_ictx->thread_count = sysconf(_SC_NPROCESSORS_ONLN);
   as->aud_octx->thread_count = sysconf(_SC_NPROCESSORS_ONLN);
@@ -1628,8 +1650,8 @@ transcoder_init_video(transcoder_t *t, streaming_start_component_t *ssc)
   vs->vid_icodec = icodec;
   vs->vid_ocodec = ocodec;
 
-  vs->vid_ictx = avcodec_alloc_context3(icodec);
-  vs->vid_octx = avcodec_alloc_context3(ocodec);
+  vs->vid_ictx = avcodec_alloc_context3_tvh(icodec);
+  vs->vid_octx = avcodec_alloc_context3_tvh(ocodec);
 
   vs->vid_ictx->thread_count = sysconf(_SC_NPROCESSORS_ONLN);
   vs->vid_octx->thread_count = sysconf(_SC_NPROCESSORS_ONLN);
index 66533148324f3d26e6093afab5f157a4203b7d0e..b604aaa9c9b7b9b0816fe7b10351eec850b4fcf5 100644 (file)
@@ -793,11 +793,11 @@ profile_transcode_open(profile_t *_pro, profile_chain_t *prch,
 
   memset(prch, 0, sizeof(*prch));
   streaming_queue_init(&prch->prch_sq, 0, qsize);
-  prch->prch_transcoder = profile_transcode_work(_pro, &prch->prch_sq.sq_st, NULL);
-  prch->prch_gh         = globalheaders_create(prch->prch_transcoder);
-  prch->prch_tsfix      = tsfix_create(prch->prch_gh);
+  prch->prch_gh         = globalheaders_create(&prch->prch_sq.sq_st);
+  prch->prch_transcoder = profile_transcode_work(_pro, prch->prch_gh, NULL);
+  prch->prch_tsfix      = tsfix_create(prch->prch_transcoder);
   prch->prch_muxer      = muxer_create(&c);
-  prch->prch_st         = prch->prch_transcoder;
+  prch->prch_st         = prch->prch_tsfix;
   return 0;
 }