From: lekma Date: Mon, 12 Sep 2016 15:41:18 +0000 (+0200) Subject: [transcode]: fix pict_type for libtheora (and others), drop invalid video packet... X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=0efc13b2d4c551052cfb0f7cacfa9a46d60a955e;p=thirdparty%2Ftvheadend.git [transcode]: fix pict_type for libtheora (and others), drop invalid video packet (pts <= last) --- diff --git a/src/transcoding/transcode/internals.h b/src/transcoding/transcode/internals.h index 41f5842f0..2c5675405 100644 --- a/src/transcoding/transcode/internals.h +++ b/src/transcoding/transcode/internals.h @@ -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; diff --git a/src/transcoding/transcode/video.c b/src/transcoding/transcode/video.c index a3cf6feec..ad35a01a7 100644 --- a/src/transcoding/transcode/video.c +++ b/src/transcoding/transcode/video.c @@ -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,