]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
[transcode]: fix pict_type for libtheora (and others), drop invalid video packet...
authorlekma <lekmalek@gmail.com>
Mon, 12 Sep 2016 15:41:18 +0000 (17:41 +0200)
committerJaroslav Kysela <perex@perex.cz>
Mon, 28 Aug 2017 13:32:48 +0000 (15:32 +0200)
src/transcoding/transcode/internals.h
src/transcoding/transcode/video.c

index 41f5842f015492b258f0d7ee512fe16849f1c38c..2c5675405ce85549356ccd4fa0bd8300df18d09d 100644 (file)
@@ -160,10 +160,10 @@ typedef struct tvh_context_t {
     AVFilterContext *oavfltctx;
     th_pkt_t *src_pkt;
     int require_meta;
+    int64_t pts;
     // only for audio
     int64_t duration;
     int64_t delta;
-    int64_t pts;
     uint8_t sri;
 } TVHContext;
 
index a3cf6feec7b473debf773bf1fda8b9501988d358..ad35a01a71472f00c4479ca2d4289e82d3ff7b60 100644 (file)
@@ -213,17 +213,24 @@ tvh_video_context_open(TVHContext *self, TVHOpenPhase phase, AVDictionary **opts
 }
 
 
+static int
+tvh_video_context_decode(TVHContext *self, AVPacket *avpkt)
+{
+    if (avpkt->pts <= self->pts) {
+        tvh_context_log(self, LOG_WARNING,
+                        "Invalid pts (%"PRId64") <= last (%"PRId64"), dropping packet",
+                        avpkt->pts, self->pts);
+        return AVERROR_INVALIDDATA;
+    }
+    self->pts = avpkt->pts;
+    return 0;
+}
+
+
 static int
 tvh_video_context_encode(TVHContext *self, AVFrame *avframe)
 {
     avframe->pts = av_frame_get_best_effort_timestamp(avframe);
-    /*if (avframe->pts <= self->pts) {
-        tvh_context_log(self, LOG_ERR,
-                        "Invalid pts (%"PRId64") <= last (%"PRId64")",
-                        avframe->pts, self->pts);
-        return -1;
-    }
-    self->pts = avframe->pts;*/
     return 0;
 }
 
@@ -251,9 +258,22 @@ tvh_video_context_wrap(TVHContext *self, AVPacket *avpkt, th_pkt_t *pkt)
     if (qsdata && qsdata_size >= 5) {
         pict_type = qsdata[4];
     }
+    else if (avpkt->flags & AV_PKT_FLAG_KEY) {
+        pict_type = AV_PICTURE_TYPE_I;
+    }
 #if FF_API_CODED_FRAME
     else if (self->oavctx->coded_frame) {
-        pict_type = self->oavctx->coded_frame->pict_type;
+        // some codecs do not set pict_type but set key_frame, in this case,
+        // we assume that when key_frame == 1 the frame is an I-frame
+        // (all the others are assumed to be P-frames)
+        if (!(pict_type = self->oavctx->coded_frame->pict_type)) {
+            if (self->oavctx->coded_frame->key_frame) {
+                pict_type = AV_PICTURE_TYPE_I;
+            }
+            else {
+                pict_type = AV_PICTURE_TYPE_P;
+            }
+        }
     }
 #endif
     switch (pict_type) {
@@ -267,7 +287,7 @@ tvh_video_context_wrap(TVHContext *self, AVPacket *avpkt, th_pkt_t *pkt)
             pkt->v.pkt_frametype = PKT_B_FRAME;
             break;
         default:
-            tvh_context_log(self, LOG_DEBUG, "unknown picture type: %d",
+            tvh_context_log(self, LOG_WARNING, "unknown picture type: %d",
                             pict_type);
             break;
     }
@@ -293,6 +313,7 @@ tvh_video_context_close(TVHContext *self)
 TVHContextType TVHVideoContext = {
     .media_type = AVMEDIA_TYPE_VIDEO,
     .open       = tvh_video_context_open,
+    .decode     = tvh_video_context_decode,
     .encode     = tvh_video_context_encode,
     .ship       = tvh_video_context_ship,
     .wrap       = tvh_video_context_wrap,