diff --git a/lib/ffmpeg/libavformat/avformat.h b/lib/ffmpeg/libavformat/avformat.h index 4432d934727ff..dcdcbb99278b7 100644 --- a/lib/ffmpeg/libavformat/avformat.h +++ b/lib/ffmpeg/libavformat/avformat.h @@ -873,6 +873,13 @@ typedef struct AVStream { */ int pts_wrap_behavior; + /** + * Internal data to analyze DTS and detect faulty mpeg streams + */ + int64_t last_dts_for_order_check; + uint8_t dts_ordered; + uint8_t dts_misordered; + } AVStream; #define AV_PROGRAM_RUNNING 1 diff --git a/lib/ffmpeg/libavformat/mpegts.c b/lib/ffmpeg/libavformat/mpegts.c index 1ae699bcdca6f..70242b11e741d 100644 --- a/lib/ffmpeg/libavformat/mpegts.c +++ b/lib/ffmpeg/libavformat/mpegts.c @@ -972,10 +972,7 @@ static int mpegts_push_data(MpegTSFilter *filter, pes->pts = AV_NOPTS_VALUE; pes->dts = AV_NOPTS_VALUE; if ((flags & 0xc0) == 0x80) { - pes->pts = ff_parse_pes_pts(r); - /* video pts is not monotonic, can't be used for dts */ - if (pes->st->codec->codec_type != AVMEDIA_TYPE_VIDEO) - pes->dts = pes->pts; + pes->dts = pes->pts = ff_parse_pes_pts(r); r += 5; } else if ((flags & 0xc0) == 0xc0) { pes->pts = ff_parse_pes_pts(r); diff --git a/lib/ffmpeg/libavformat/utils.c b/lib/ffmpeg/libavformat/utils.c index 72f59d25d84de..e1b14335ebee4 100644 --- a/lib/ffmpeg/libavformat/utils.c +++ b/lib/ffmpeg/libavformat/utils.c @@ -1104,6 +1104,28 @@ static void compute_pkt_fields(AVFormatContext *s, AVStream *st, if (s->flags & AVFMT_FLAG_NOFILLIN) return; + if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && pkt->dts != AV_NOPTS_VALUE) { + if (pkt->dts == pkt->pts && st->last_dts_for_order_check != AV_NOPTS_VALUE) { + if (st->last_dts_for_order_check <= pkt->dts) { + st->dts_ordered++; + } else { + av_log(s, st->dts_misordered ? AV_LOG_DEBUG : AV_LOG_WARNING, + "DTS %"PRIi64" < %"PRIi64" out of order\n", + pkt->dts, + st->last_dts_for_order_check); + st->dts_misordered++; + } + if (st->dts_ordered + st->dts_misordered > 250) { + st->dts_ordered >>= 1; + st->dts_misordered >>= 1; + } + } + + st->last_dts_for_order_check = pkt->dts; + if (st->dts_ordered < 8*st->dts_misordered && pkt->dts == pkt->pts) + pkt->dts = AV_NOPTS_VALUE; + } + if((s->flags & AVFMT_FLAG_IGNDTS) && pkt->pts != AV_NOPTS_VALUE) pkt->dts= AV_NOPTS_VALUE; @@ -1627,6 +1649,7 @@ void ff_read_frame_flush(AVFormatContext *s) st->parser = NULL; } st->last_IP_pts = AV_NOPTS_VALUE; + st->last_dts_for_order_check = AV_NOPTS_VALUE; if(st->first_dts == AV_NOPTS_VALUE) st->cur_dts = RELATIVE_TS_BASE; else st->cur_dts = AV_NOPTS_VALUE; /* we set the current DTS to an unspecified origin */ st->reference_dts = AV_NOPTS_VALUE; @@ -2407,6 +2430,7 @@ static void estimate_timings_from_pts(AVFormatContext *ic, int64_t old_offset) st= ic->streams[i]; st->cur_dts= st->first_dts; st->last_IP_pts = AV_NOPTS_VALUE; + st->last_dts_for_order_check = AV_NOPTS_VALUE; st->reference_dts = AV_NOPTS_VALUE; } } @@ -3390,6 +3414,7 @@ AVStream *avformat_new_stream(AVFormatContext *s, const AVCodec *c) /* default pts setting is MPEG-like */ avpriv_set_pts_info(st, 33, 1, 90000); st->last_IP_pts = AV_NOPTS_VALUE; + st->last_dts_for_order_check = AV_NOPTS_VALUE; for(i=0; ipts_buffer[i]= AV_NOPTS_VALUE; st->reference_dts = AV_NOPTS_VALUE; diff --git a/lib/ffmpeg/patches/0059-backport-detect-MPEG-streams-faulty-dts.patch b/lib/ffmpeg/patches/0059-backport-detect-MPEG-streams-faulty-dts.patch new file mode 100644 index 0000000000000..1ea599187cf14 --- /dev/null +++ b/lib/ffmpeg/patches/0059-backport-detect-MPEG-streams-faulty-dts.patch @@ -0,0 +1,92 @@ +From 2dcaa1b9d142ae113b28bffdbf7f8f8900b5e770 Mon Sep 17 00:00:00 2001 +From: Michael Niedermayer +Date: Mon, 3 Mar 2014 01:55:18 +0100 +Subject: [PATCH] avformat/utils: detect MPEG streams with faulty DTS and + discard affected DTS + +Fixes issue2.ts + +Signed-off-by: Michael Niedermayer +--- + libavformat/avformat.h | 7 +++++++ + libavformat/utils.c | 25 +++++++++++++++++++++++++ + 2 files changed, 32 insertions(+) + +diff --git a/libavformat/avformat.h b/libavformat/avformat.h +index 52eeb61..e0ec3da 100644 +--- a/libavformat/avformat.h ++++ b/libavformat/avformat.h +@@ -988,6 +988,13 @@ enum AVStreamParseType { + int64_t pts_reorder_error[MAX_REORDER_DELAY+1]; + uint8_t pts_reorder_error_count[MAX_REORDER_DELAY+1]; + ++ /** ++ * Internal data to analyze DTS and detect faulty mpeg streams ++ */ ++ int64_t last_dts_for_order_check; ++ uint8_t dts_ordered; ++ uint8_t dts_misordered; ++ + } AVStream; + + AVRational av_stream_get_r_frame_rate(const AVStream *s); +diff --git a/libavformat/utils.c b/libavformat/utils.c +index 584edd3..4e262b1 100644 +--- a/libavformat/utils.c ++++ b/libavformat/utils.c +@@ -1120,6 +1120,28 @@ static void compute_pkt_fields(AVFormatContext *s, AVStream *st, + if (s->flags & AVFMT_FLAG_NOFILLIN) + return; + ++ if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && pkt->dts != AV_NOPTS_VALUE) { ++ if (pkt->dts == pkt->pts && st->last_dts_for_order_check != AV_NOPTS_VALUE) { ++ if (st->last_dts_for_order_check <= pkt->dts) { ++ st->dts_ordered++; ++ } else { ++ av_log(s, st->dts_misordered ? AV_LOG_DEBUG : AV_LOG_WARNING, ++ "DTS %"PRIi64" < %"PRIi64" out of order\n", ++ pkt->dts, ++ st->last_dts_for_order_check); ++ st->dts_misordered++; ++ } ++ if (st->dts_ordered + st->dts_misordered > 250) { ++ st->dts_ordered >>= 1; ++ st->dts_misordered >>= 1; ++ } ++ } ++ ++ st->last_dts_for_order_check = pkt->dts; ++ if (st->dts_ordered < 8*st->dts_misordered && pkt->dts == pkt->pts) ++ pkt->dts = AV_NOPTS_VALUE; ++ } ++ + if ((s->flags & AVFMT_FLAG_IGNDTS) && pkt->pts != AV_NOPTS_VALUE) + pkt->dts = AV_NOPTS_VALUE; + +@@ -1664,6 +1686,7 @@ void ff_read_frame_flush(AVFormatContext *s) + st->parser = NULL; + } + st->last_IP_pts = AV_NOPTS_VALUE; ++ st->last_dts_for_order_check = AV_NOPTS_VALUE; + if (st->first_dts == AV_NOPTS_VALUE) + st->cur_dts = RELATIVE_TS_BASE; + else +@@ -2488,6 +2511,7 @@ static void estimate_timings_from_pts(AVFormatContext *ic, int64_t old_offset) + st = ic->streams[i]; + st->cur_dts = st->first_dts; + st->last_IP_pts = AV_NOPTS_VALUE; ++ st->last_dts_for_order_check = AV_NOPTS_VALUE; + for (j = 0; j < MAX_REORDER_DELAY + 1; j++) + st->pts_buffer[j] = AV_NOPTS_VALUE; + } +@@ -3623,6 +3647,7 @@ AVStream *avformat_new_stream(AVFormatContext *s, const AVCodec *c) + /* default pts setting is MPEG-like */ + avpriv_set_pts_info(st, 33, 1, 90000); + st->last_IP_pts = AV_NOPTS_VALUE; ++ st->last_dts_for_order_check = AV_NOPTS_VALUE; + for (i = 0; i < MAX_REORDER_DELAY + 1; i++) + st->pts_buffer[i] = AV_NOPTS_VALUE; + +-- +1.8.5.5 + diff --git a/lib/ffmpeg/patches/0059-backport-mpegts-do-not-set-pts-for-missing-dts.patch b/lib/ffmpeg/patches/0059-backport-mpegts-do-not-set-pts-for-missing-dts.patch deleted file mode 100644 index db091707d868b..0000000000000 --- a/lib/ffmpeg/patches/0059-backport-mpegts-do-not-set-pts-for-missing-dts.patch +++ /dev/null @@ -1,29 +0,0 @@ -From f65afef1df49f53e14c8d4173ff960fff8d44ecb Mon Sep 17 00:00:00 2001 -From: Rainer Hochecker -Date: Tue, 3 Dec 2013 10:03:04 +0100 -Subject: [PATCH] mpegts: do not set pts for missing dts in video streams - -Signed-off-by: Michael Niedermayer ---- - libavformat/mpegts.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c -index 59b0058..d67c63a 100644 ---- a/libavformat/mpegts.c -+++ b/libavformat/mpegts.c -@@ -972,7 +972,10 @@ static int mpegts_push_data(MpegTSFilter *filter, - pes->pts = AV_NOPTS_VALUE; - pes->dts = AV_NOPTS_VALUE; - if ((flags & 0xc0) == 0x80) { -- pes->dts = pes->pts = ff_parse_pes_pts(r); -+ pes->pts = ff_parse_pes_pts(r); -+ /* video pts is not monotonic, can't be used for dts */ -+ if (pes->st->codec->codec_type != AVMEDIA_TYPE_VIDEO) -+ pes->dts = pes->pts; - r += 5; - } else if ((flags & 0xc0) == 0xc0) { - pes->pts = ff_parse_pes_pts(r); --- -1.8.5-rc3 -