diff mbox

[FFmpeg-devel] lavf/mov.c: Guess video codec delay based on PTS while parsing MOV header.

Message ID 20171114021505.27490-1-isasi@google.com
State Superseded
Headers show

Commit Message

Sasi Inguva Nov. 14, 2017, 2:15 a.m. UTC
Signed-off-by: Sasi Inguva <isasi@google.com>
---
 libavformat/mov.c                | 48 ++++++++++++++++++++++++++++++++++++++++
 tests/fate/mov.mak               |  5 +++++
 tests/ref/fate/mov-guess-delay-1 |  3 +++
 tests/ref/fate/mov-guess-delay-2 |  3 +++
 4 files changed, 59 insertions(+)
 create mode 100644 tests/ref/fate/mov-guess-delay-1
 create mode 100644 tests/ref/fate/mov-guess-delay-2

Comments

Michael Niedermayer Nov. 14, 2017, 4:11 p.m. UTC | #1
On Mon, Nov 13, 2017 at 06:15:05PM -0800, Sasi Inguva wrote:
[...]
> +fate-mov-guess-delay-1: CMD = run ffprobe$(PROGSSUF)$(EXESUF) -show_entries stream=has_b_frames -select_streams v $(TARGET_SAMPLES)/h264/h264_3bf_nopyramid_nobsrestriction.mp4
> +fate-mov-guess-delay-2: CMD = run ffprobe$(PROGSSUF)$(EXESUF) -show_entries stream=has_b_frames -select_streams v $(TARGET_SAMPLES)/h264/h264_3bf_pyramid_nobsrestriction.mp4

fate-suite//h264/h264_3bf_nopyramid_nobsrestriction.mp4: No such file or directory

where are these files ?


[...]
Sasi Inguva Nov. 14, 2017, 5:39 p.m. UTC | #2
Sorry forgot to attach the fate samples. Pls find them attached.

On Tue, Nov 14, 2017 at 8:11 AM, Michael Niedermayer <michael@niedermayer.cc
> wrote:

> On Mon, Nov 13, 2017 at 06:15:05PM -0800, Sasi Inguva wrote:
> [...]
> > +fate-mov-guess-delay-1: CMD = run ffprobe$(PROGSSUF)$(EXESUF)
> -show_entries stream=has_b_frames -select_streams v
> $(TARGET_SAMPLES)/h264/h264_3bf_nopyramid_nobsrestriction.mp4
> > +fate-mov-guess-delay-2: CMD = run ffprobe$(PROGSSUF)$(EXESUF)
> -show_entries stream=has_b_frames -select_streams v
> $(TARGET_SAMPLES)/h264/h264_3bf_pyramid_nobsrestriction.mp4
>
> fate-suite//h264/h264_3bf_nopyramid_nobsrestriction.mp4: No such file or
> directory
>
> where are these files ?
>
>
> [...]
> --
> Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
>
> I do not agree with what you have to say, but I'll defend to the death your
> right to say it. -- Voltaire
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
>
Derek Buitenhuis Nov. 14, 2017, 6:06 p.m. UTC | #3
On 11/14/2017 2:15 AM, Sasi Inguva wrote:
> Signed-off-by: Sasi Inguva <isasi@google.com>
> ---
>  libavformat/mov.c                | 48 ++++++++++++++++++++++++++++++++++++++++
>  tests/fate/mov.mak               |  5 +++++
>  tests/ref/fate/mov-guess-delay-1 |  3 +++
>  tests/ref/fate/mov-guess-delay-2 |  3 +++
>  4 files changed, 59 insertions(+)
>  create mode 100644 tests/ref/fate/mov-guess-delay-1
>  create mode 100644 tests/ref/fate/mov-guess-delay-2

Going to play the part of wm4 here.

This seems like one giant hack to me (and potentially yet more slowness
during init/index).

Should we *really* be populating codecpar with a heuristic guess and
should we *really* be putting this in one specific demuxer?

Seems pretty gross to me.

- Derek
Sasi Inguva Nov. 14, 2017, 8:28 p.m. UTC | #4
For H264 files with no bitstream restriction flag, we aren't able to guess
the delay correctly. Especially if it's MOV container, because for MOV
container we just probe the 1st frame and stop in avformat_find_streaminfo .

When we are decoding , we increase the has_b_frames value from zero to 1 or
2, when we eventually encounter B-frames in H264 decoder, but that is too
late and we have already dropped 1 or 2 frames. Lot of other fields in
codecpar are being set from the demuxer like channel_layout, sample_rate
etc.

On Tue, Nov 14, 2017 at 10:06 AM, Derek Buitenhuis <
derek.buitenhuis@gmail.com> wrote:

> On 11/14/2017 2:15 AM, Sasi Inguva wrote:
> > Signed-off-by: Sasi Inguva <isasi@google.com>
> > ---
> >  libavformat/mov.c                | 48 ++++++++++++++++++++++++++++++
> ++++++++++
> >  tests/fate/mov.mak               |  5 +++++
> >  tests/ref/fate/mov-guess-delay-1 |  3 +++
> >  tests/ref/fate/mov-guess-delay-2 |  3 +++
> >  4 files changed, 59 insertions(+)
> >  create mode 100644 tests/ref/fate/mov-guess-delay-1
> >  create mode 100644 tests/ref/fate/mov-guess-delay-2
>
> Going to play the part of wm4 here.
>
> This seems like one giant hack to me (and potentially yet more slowness
> during init/index).
>
> Should we *really* be populating codecpar with a heuristic guess and
> should we *really* be putting this in one specific demuxer?
>
> Seems pretty gross to me.
>
> - Derek
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
Michael Niedermayer Nov. 14, 2017, 8:32 p.m. UTC | #5
On Tue, Nov 14, 2017 at 09:39:33AM -0800, Sasi Inguva wrote:
> Sorry forgot to attach the fate samples. Pls find them attached.

uploaded

thx

[...]
Hendrik Leppkes Nov. 14, 2017, 8:39 p.m. UTC | #6
On Tue, Nov 14, 2017 at 9:28 PM, Sasi Inguva
<isasi-at-google.com@ffmpeg.org> wrote:
> For H264 files with no bitstream restriction flag, we aren't able to guess
> the delay correctly. Especially if it's MOV container, because for MOV
> container we just probe the 1st frame and stop in avformat_find_streaminfo .
>
> When we are decoding , we increase the has_b_frames value from zero to 1 or
> 2, when we eventually encounter B-frames in H264 decoder, but that is too
> late and we have already dropped 1 or 2 frames. Lot of other fields in
> codecpar are being set from the demuxer like channel_layout, sample_rate
> etc.
>

It was not the usefulness that was questioned, but the implementation.
Maybe this should be more generic?

- Hendrik
Derek Buitenhuis Nov. 14, 2017, 8:40 p.m. UTC | #7
On 11/14/2017 8:28 PM, Sasi Inguva wrote:
> For H264 files with no bitstream restriction flag, we aren't able to guess
> the delay correctly. Especially if it's MOV container, because for MOV
> container we just probe the 1st frame and stop in avformat_find_streaminfo .

You do not appear to be restricting this to one specific codec, or even codecs
with B-frames.

> When we are decoding , we increase the has_b_frames value from zero to 1 or
> 2, when we eventually encounter B-frames in H264 decoder, but that is too
> late and we have already dropped 1 or 2 frames. Lot of other fields in
> codecpar are being set from the demuxer like channel_layout, sample_rate
> etc.

I am aware of the intend, however...

The difference between filling those fields in and this patch, is that we can
read those values directly, generally. This is a guess; a heuristic. A heuristic
based on the GOP structure of a single codec. Where we guess where a GOP even
starts. Nor does it seem to take into account non-friendly files, with oddly
ordered and/or invalid timestamps (which it can't, based solely on PTS).

I'm pretty tired of hitting insane edge cases in other types of files due to
hacks added for some other specific set of file, but used for *everything*.
This is a recurring theme in FFmpeg, so I'm trying to fight hard to keep
more out...

- Derek
Sasi Inguva Nov. 14, 2017, 10:11 p.m. UTC | #8
I don't know if the patch can be made more generic to work for all
demuxers, because this patch requires that PTS of all packets be available
in the header.  The other route is to make it very specific to codecs with
B-frames.

On Tue, Nov 14, 2017 at 12:40 PM, Derek Buitenhuis <
derek.buitenhuis@gmail.com> wrote:

> On 11/14/2017 8:28 PM, Sasi Inguva wrote:
> > For H264 files with no bitstream restriction flag, we aren't able to
> guess
> > the delay correctly. Especially if it's MOV container, because for MOV
> > container we just probe the 1st frame and stop in
> avformat_find_streaminfo .
>
> You do not appear to be restricting this to one specific codec, or even
> codecs
> with B-frames.
>
> I can make it specific to only H264 / H265.


> > When we are decoding , we increase the has_b_frames value from zero to 1
> or
> > 2, when we eventually encounter B-frames in H264 decoder, but that is too
> > late and we have already dropped 1 or 2 frames. Lot of other fields in
> > codecpar are being set from the demuxer like channel_layout, sample_rate
> > etc.
>
> I am aware of the intend, however...
>
> The difference between filling those fields in and this patch, is that we
> can
> read those values directly, generally. This is a guess; a heuristic. A
> heuristic
> based on the GOP structure of a single codec. Where we guess where a GOP
> even
> starts. Nor does it seem to take into account non-friendly files, with
> oddly
> ordered and/or invalid timestamps (which it can't, based solely on PTS).
>
> I'm pretty tired of hitting insane edge cases in other types of files due
> to
> hacks added for some other specific set of file, but used for *everything*.
> This is a recurring theme in FFmpeg, so I'm trying to fight hard to keep
> more out...
>
It is true that the patch will fail to compute the correct delay in lots of
cases. However the consequence of wrongly computing the has_b_frames is
pretty benign. It only increases the buffer size held for PTS  reordering.
I can put a max-value check on the computed video_delay here. So in my
opinion, we won't see fatal regressions where a file is not able to be
decoded / played.


>
> - Derek
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
Derek Buitenhuis Nov. 14, 2017, 11:23 p.m. UTC | #9
On 11/14/2017 10:11 PM, Sasi Inguva wrote:
> I don't know if the patch can be made more generic to work for all
> demuxers, because this patch requires that PTS of all packets be available
> in the header.  The other route is to make it very specific to codecs with
> B-frames.

All PTS may not be available in MP4 either, in the live profile fragmented
MP4 case, no? I am not familiar enough with the fragmented MP4 demuxing code
say whether we seek to each fragment and make it available or not. I assume
you've tested such a case, or can (or know the fragment code)?

It's feasible to restrict it to codecs, I suppose.

>> You do not appear to be restricting this to one specific codec, or even
>> codecs
>> with B-frames.
>>
>> I can make it specific to only H264 / H265.

The GOP structure should be applicable to most MPEG codecs, I think.

> It is true that the patch will fail to compute the correct delay in lots of
> cases. However the consequence of wrongly computing the has_b_frames is
> pretty benign. It only increases the buffer size held for PTS  reordering.
> I can put a max-value check on the computed video_delay here. So in my
> opinion, we won't see fatal regressions where a file is not able to be
> decoded / played.

It's true it's likely benign, but it's not exactly a "fix" either...

From a user perspective, it's kinda possible to work around it "properly"
(I use that term loosely here) by decoding enough frames to fill the max
DPB for a given codec (e.g. 16 for H.264) in avformat_find_stream_info
(or in a user's code if they don't use that function), isn't it? Though,
I feel that particular fix won't be welcomed with open arms, due to a
~16x 'slow down' in probing.

Does anyone else have an opinion™ on this? I guess it's "OK enough" if
restricted by codec...? :V

- Derek
Thierry Foucu Nov. 14, 2017, 11:36 p.m. UTC | #10
On Tue, Nov 14, 2017 at 3:23 PM, Derek Buitenhuis <
derek.buitenhuis@gmail.com> wrote:

> On 11/14/2017 10:11 PM, Sasi Inguva wrote:
> > I don't know if the patch can be made more generic to work for all
> > demuxers, because this patch requires that PTS of all packets be
> available
> > in the header.  The other route is to make it very specific to codecs
> with
> > B-frames.
>
> All PTS may not be available in MP4 either, in the live profile fragmented
> MP4 case, no? I am not familiar enough with the fragmented MP4 demuxing
> code
> say whether we seek to each fragment and make it available or not. I assume
> you've tested such a case, or can (or know the fragment code)?
>
> It's feasible to restrict it to codecs, I suppose.
>
> >> You do not appear to be restricting this to one specific codec, or even
> >> codecs
> >> with B-frames.
> >>
> >> I can make it specific to only H264 / H265.
>
> The GOP structure should be applicable to most MPEG codecs, I think.
>
> > It is true that the patch will fail to compute the correct delay in lots
> of
> > cases. However the consequence of wrongly computing the has_b_frames is
> > pretty benign. It only increases the buffer size held for PTS
> reordering.
> > I can put a max-value check on the computed video_delay here. So in my
> > opinion, we won't see fatal regressions where a file is not able to be
> > decoded / played.
>
> It's true it's likely benign, but it's not exactly a "fix" either...
>
> From a user perspective, it's kinda possible to work around it "properly"
> (I use that term loosely here) by decoding enough frames to fill the max
> DPB for a given codec (e.g. 16 for H.264) in avformat_find_stream_info
> (or in a user's code if they don't use that function), isn't it? Though,
> I feel that particular fix won't be welcomed with open arms, due to a
> ~16x 'slow down' in probing.
>
>
One option i asked on IRC was to use the spec for max DPB when the bitstream
restriction flag was not set.
But people were worry about low latency usage.
Normally, if the  bitstream restriction flag is not set, the DPB should be
set based on the spec, even if there is no B frames.
But in some case, it will be 16 frame and this could increase then the low
latency.



> Does anyone else have an opinion™ on this? I guess it's "OK enough" if
> restricted by codec...? :V
>
> - Derek
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
Derek Buitenhuis Nov. 14, 2017, 11:59 p.m. UTC | #11
On 11/14/2017 11:36 PM, Thierry Foucu wrote:
> One option i asked on IRC was to use the spec for max DPB when the bitstream
> restriction flag was not set.
> But people were worry about low latency usage.
> Normally, if the  bitstream restriction flag is not set, the DPB should be
> set based on the spec, even if there is no B frames.
> But in some case, it will be 16 frame and this could increase then the low
> latency.

I guess that's a problem inherent to a generic API that tries to satisfy all
use cases - you can't please everyone.

I don't really have a /good/ solution given the use-case constraints, as
per previous email. :/

- Derek
Carl Eugen Hoyos Nov. 15, 2017, 12:12 a.m. UTC | #12
2017-11-15 0:36 GMT+01:00 Thierry Foucu <tfoucu@gmail.com>:
> On Tue, Nov 14, 2017 at 3:23 PM, Derek Buitenhuis <
> derek.buitenhuis@gmail.com> wrote:
>
>> On 11/14/2017 10:11 PM, Sasi Inguva wrote:
>> > I don't know if the patch can be made more generic to work for all
>> > demuxers, because this patch requires that PTS of all packets be
>> available
>> > in the header.  The other route is to make it very specific to codecs
>> with
>> > B-frames.
>>
>> All PTS may not be available in MP4 either, in the live profile fragmented
>> MP4 case, no? I am not familiar enough with the fragmented MP4 demuxing
>> code
>> say whether we seek to each fragment and make it available or not. I assume
>> you've tested such a case, or can (or know the fragment code)?
>>
>> It's feasible to restrict it to codecs, I suppose.
>>
>> >> You do not appear to be restricting this to one specific codec, or even
>> >> codecs
>> >> with B-frames.
>> >>
>> >> I can make it specific to only H264 / H265.
>>
>> The GOP structure should be applicable to most MPEG codecs, I think.
>>
>> > It is true that the patch will fail to compute the correct delay in lots
>> of
>> > cases. However the consequence of wrongly computing the has_b_frames is
>> > pretty benign. It only increases the buffer size held for PTS
>> reordering.
>> > I can put a max-value check on the computed video_delay here. So in my
>> > opinion, we won't see fatal regressions where a file is not able to be
>> > decoded / played.
>>
>> It's true it's likely benign, but it's not exactly a "fix" either...
>>
>> From a user perspective, it's kinda possible to work around it "properly"
>> (I use that term loosely here) by decoding enough frames to fill the max
>> DPB for a given codec (e.g. 16 for H.264) in avformat_find_stream_info
>> (or in a user's code if they don't use that function), isn't it? Though,
>> I feel that particular fix won't be welcomed with open arms, due to a
>> ~16x 'slow down' in probing.
>>
> One option i asked on IRC was to use the spec for max DPB when the
> bitstream restriction flag was not set.

I believe this should be done if the user had set -strict 1

Carl Eugen
Michael Niedermayer Nov. 15, 2017, 12:25 a.m. UTC | #13
On Tue, Nov 14, 2017 at 03:36:49PM -0800, Thierry Foucu wrote:
> On Tue, Nov 14, 2017 at 3:23 PM, Derek Buitenhuis <
> derek.buitenhuis@gmail.com> wrote:
> 
> > On 11/14/2017 10:11 PM, Sasi Inguva wrote:
> > > I don't know if the patch can be made more generic to work for all
> > > demuxers, because this patch requires that PTS of all packets be
> > available
> > > in the header.  The other route is to make it very specific to codecs
> > with
> > > B-frames.
> >
> > All PTS may not be available in MP4 either, in the live profile fragmented
> > MP4 case, no? I am not familiar enough with the fragmented MP4 demuxing
> > code
> > say whether we seek to each fragment and make it available or not. I assume
> > you've tested such a case, or can (or know the fragment code)?
> >
> > It's feasible to restrict it to codecs, I suppose.
> >
> > >> You do not appear to be restricting this to one specific codec, or even
> > >> codecs
> > >> with B-frames.
> > >>
> > >> I can make it specific to only H264 / H265.
> >
> > The GOP structure should be applicable to most MPEG codecs, I think.
> >
> > > It is true that the patch will fail to compute the correct delay in lots
> > of
> > > cases. However the consequence of wrongly computing the has_b_frames is
> > > pretty benign. It only increases the buffer size held for PTS
> > reordering.
> > > I can put a max-value check on the computed video_delay here. So in my
> > > opinion, we won't see fatal regressions where a file is not able to be
> > > decoded / played.
> >
> > It's true it's likely benign, but it's not exactly a "fix" either...
> >
> > From a user perspective, it's kinda possible to work around it "properly"
> > (I use that term loosely here) by decoding enough frames to fill the max
> > DPB for a given codec (e.g. 16 for H.264) in avformat_find_stream_info
> > (or in a user's code if they don't use that function), isn't it? Though,
> > I feel that particular fix won't be welcomed with open arms, due to a
> > ~16x 'slow down' in probing.
> >
> >
> One option i asked on IRC was to use the spec for max DPB when the bitstream
> restriction flag was not set.
> But people were worry about low latency usage.
> Normally, if the  bitstream restriction flag is not set, the DPB should be
> set based on the spec, even if there is no B frames.
> But in some case, it will be 16 frame and this could increase then the low
> latency.

it could also increase memory requirements substantially


[...]
Sasi Inguva Nov. 18, 2017, 6:12 a.m. UTC | #14
restricted the patch to MPEG based codecs. Also, setting the delay only if
it's not set already and capping the max. value to 16.

On Wed, Nov 15, 2017 at 5:55 AM, Michael Niedermayer <michael@niedermayer.cc
> wrote:

> On Tue, Nov 14, 2017 at 03:36:49PM -0800, Thierry Foucu wrote:
> > On Tue, Nov 14, 2017 at 3:23 PM, Derek Buitenhuis <
> > derek.buitenhuis@gmail.com> wrote:
> >
> > > On 11/14/2017 10:11 PM, Sasi Inguva wrote:
> > > > I don't know if the patch can be made more generic to work for all
> > > > demuxers, because this patch requires that PTS of all packets be
> > > available
> > > > in the header.  The other route is to make it very specific to codecs
> > > with
> > > > B-frames.
> > >
> > > All PTS may not be available in MP4 either, in the live profile
> fragmented
> > > MP4 case, no? I am not familiar enough with the fragmented MP4 demuxing
> > > code
> > > say whether we seek to each fragment and make it available or not. I
> assume
> > > you've tested such a case, or can (or know the fragment code)?
> > >
> > > It's feasible to restrict it to codecs, I suppose.
> > >
> > > >> You do not appear to be restricting this to one specific codec, or
> even
> > > >> codecs
> > > >> with B-frames.
> > > >>
> > > >> I can make it specific to only H264 / H265.
> > >
> > > The GOP structure should be applicable to most MPEG codecs, I think.
> > >
> > > > It is true that the patch will fail to compute the correct delay in
> lots
> > > of
> > > > cases. However the consequence of wrongly computing the has_b_frames
> is
> > > > pretty benign. It only increases the buffer size held for PTS
> > > reordering.
> > > > I can put a max-value check on the computed video_delay here. So in
> my
> > > > opinion, we won't see fatal regressions where a file is not able to
> be
> > > > decoded / played.
> > >
> > > It's true it's likely benign, but it's not exactly a "fix" either...
> > >
> > > From a user perspective, it's kinda possible to work around it
> "properly"
> > > (I use that term loosely here) by decoding enough frames to fill the
> max
> > > DPB for a given codec (e.g. 16 for H.264) in avformat_find_stream_info
> > > (or in a user's code if they don't use that function), isn't it?
> Though,
> > > I feel that particular fix won't be welcomed with open arms, due to a
> > > ~16x 'slow down' in probing.
> > >
> > >
> > One option i asked on IRC was to use the spec for max DPB when the
> bitstream
> > restriction flag was not set.
> > But people were worry about low latency usage.
> > Normally, if the  bitstream restriction flag is not set, the DPB should
> be
> > set based on the spec, even if there is no B frames.
> > But in some case, it will be 16 frame and this could increase then the
> low
> > latency.
>
> it could also increase memory requirements substantially
>
>
> [...]
> --
> Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
>
> Avoid a single point of failure, be that a person or equipment.
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
>
diff mbox

Patch

diff --git a/libavformat/mov.c b/libavformat/mov.c
index fd170baa57..91c6987a96 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -3213,6 +3213,52 @@  static int64_t add_ctts_entry(MOVStts** ctts_data, unsigned int* ctts_count, uns
     return *ctts_count;
 }
 
+static void mov_guess_video_delay(MOVContext *c, AVStream* st) {
+    MOVStreamContext *msc = st->priv_data;
+    int ind;
+    int ctts_ind = 0;
+    int ctts_sample = 0;
+    int64_t curr_pts = AV_NOPTS_VALUE;
+    int64_t prev_pts = AV_NOPTS_VALUE;
+    int64_t prev_max_pts = AV_NOPTS_VALUE;
+    int num_swaps = 0;
+
+    if (msc->ctts_data) {
+        st->codecpar->video_delay = 0;
+        for(ind = 0; ind < st->nb_index_entries && ctts_ind < msc->ctts_count; ++ind) {
+            curr_pts = st->index_entries[ind].timestamp + msc->ctts_data[ctts_ind].duration;
+
+            // This is used as an indication that the previous GOP has ended and a
+            // new GOP has started.
+            if (curr_pts > prev_max_pts) {
+                st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);
+                num_swaps = 0;
+                prev_max_pts = curr_pts;
+            }
+
+            // Compute delay as the no. of "drop"s in PTS inside a GOP.
+            // Frames: I0 I1 B0 B1 B2
+            // PTS:     0  4  1  2  3 -> num_swaps = delay = 1 (4->1)
+            //
+            // Frames: I0 I1 B1 B0 B2
+            // PTS:     0  4  2  1  3 -> num_swaps = delay = 2 (4->2, 2->1)
+            if (prev_pts != AV_NOPTS_VALUE) {
+                if (curr_pts < prev_pts)
+                    ++num_swaps;
+            }
+
+            prev_pts = curr_pts;
+            ctts_sample++;
+            if (ctts_sample == msc->ctts_data[ctts_ind].count) {
+                ctts_ind++;
+                ctts_sample = 0;
+            }
+        }
+        av_log(c->fc, AV_LOG_DEBUG, "Setting codecpar->delay to %d for stream st: %d\n",
+               st->codecpar->video_delay, st->index);
+    }
+}
+
 static void mov_current_sample_inc(MOVStreamContext *sc)
 {
     sc->current_sample++;
@@ -3846,6 +3892,8 @@  static void mov_build_index(MOVContext *mov, AVStream *st)
         // Fix index according to edit lists.
         mov_fix_index(mov, st);
     }
+
+    mov_guess_video_delay(mov, st);
 }
 
 static int test_same_origin(const char *src, const char *ref) {
diff --git a/tests/fate/mov.mak b/tests/fate/mov.mak
index 76f66ff498..ef89e62096 100644
--- a/tests/fate/mov.mak
+++ b/tests/fate/mov.mak
@@ -11,6 +11,8 @@  FATE_MOV = fate-mov-3elist \
            fate-mov-440hz-10ms \
            fate-mov-ibi-elst-starts-b \
            fate-mov-elst-ends-betn-b-and-i \
+           fate-mov-guess-delay-1 \
+           fate-mov-guess-delay-2 \
 
 FATE_MOV_FFPROBE = fate-mov-aac-2048-priming \
                    fate-mov-zombie \
@@ -72,3 +74,6 @@  fate-mov-spherical-mono: CMD = run ffprobe$(PROGSSUF)$(EXESUF) -show_entries str
 fate-mov-gpmf-remux: CMD = md5 -i $(TARGET_SAMPLES)/mov/fake-gp-media-with-real-gpmf.mp4 -map 0 -c copy -fflags +bitexact -f mp4
 fate-mov-gpmf-remux: CMP = oneline
 fate-mov-gpmf-remux: REF = 8f48e435ee1f6b7e173ea756141eabf3
+
+fate-mov-guess-delay-1: CMD = run ffprobe$(PROGSSUF)$(EXESUF) -show_entries stream=has_b_frames -select_streams v $(TARGET_SAMPLES)/h264/h264_3bf_nopyramid_nobsrestriction.mp4
+fate-mov-guess-delay-2: CMD = run ffprobe$(PROGSSUF)$(EXESUF) -show_entries stream=has_b_frames -select_streams v $(TARGET_SAMPLES)/h264/h264_3bf_pyramid_nobsrestriction.mp4
\ No newline at end of file
diff --git a/tests/ref/fate/mov-guess-delay-1 b/tests/ref/fate/mov-guess-delay-1
new file mode 100644
index 0000000000..96cb67be0c
--- /dev/null
+++ b/tests/ref/fate/mov-guess-delay-1
@@ -0,0 +1,3 @@ 
+[STREAM]
+has_b_frames=1
+[/STREAM]
diff --git a/tests/ref/fate/mov-guess-delay-2 b/tests/ref/fate/mov-guess-delay-2
new file mode 100644
index 0000000000..248de1c3ea
--- /dev/null
+++ b/tests/ref/fate/mov-guess-delay-2
@@ -0,0 +1,3 @@ 
+[STREAM]
+has_b_frames=2
+[/STREAM]