Opened 7 months ago

Last modified 7 months ago

#6305 new defect

Negative AVIndexEntry::timestamp value

Reported by: s0m3 Owned by:
Priority: normal Component: undetermined
Version: unspecified Keywords:
Cc: Blocked By:
Blocking: Reproduced by developer: yes
Analyzed by developer: no

Description

I'm developping a multimedia player based on FFmpeg library.

To do frame stepping, I need to associate frame numbers and frame times (timecodes).
If AVStream::nb_index_entries is != 0, I use AVIndexEntry structure, otherwise, I build an "index" manually.

I have a sample video (25fps, 60s, with timecode) where AVIndex entries are wrong.
index_entries[0].timestamp and index_entries[1].timestamp are negative. In fact, all following timestamps are correct except there's an offset of 2 so index_entries[10].timestamp is the correct timestamp of frame 8 not 10.

I checked timestamp values with another dedicated software (elecard StreamEye?) so ffmpeg is buggy here.

Let me know if you need any information.

Attachments (3)

BugTestCase.c (3.0 KB) - added by s0m3 7 months ago.
Test case to trigger the bug
sample h264 with timecode.mp4 (413.8 KB) - added by s0m3 7 months ago.
Sample video file (generated with ffmpeg)
logs.7z (120.1 KB) - added by s0m3 7 months ago.
logs compressed from comment 5

Download all attachments as: .zip

Change History (8)

Changed 7 months ago by s0m3

Test case to trigger the bug

Changed 7 months ago by s0m3

Sample video file (generated with ffmpeg)

comment:1 Changed 7 months ago by s0m3

I forgot to say I tested it on windows with ffmpeg win32 build v3.2.4 and git snapshot 21070404-1229007.

When running the sample, each AVIndexEntry::timestamp will be printed.
You should see timestamp=-1024 for index entry 1 and timestamp=-512 for entry 2 which is, obviously wrong.

comment:2 Changed 7 months ago by cehoyos

Why do you believe that negative time stamps are wrong?
Or to say it differently: Since you created the input file with ffmpeg it should be trivial to know what time stamps are correct for this file, no need to use a third-party tool.

comment:3 follow-up: Changed 7 months ago by s0m3

I don't see how a (presentation) time stamp can be negative. Time can't be negative.
Or maybe it means "too late" but first frame(s) cannot be late.

I know what correct timestamps are since (as you said) I created it.
But that's not the point. My goal is to know if I can trust AVIndex entries for any file (where nb_index_entries != 0).

I found a sample file (no matter how I got it) where first entries are not valid so it means I shouldn't use it (= not reliable).
But since decoding each frame to build an index myself can be very long, I'd like ffmpeg to be fixed so that I can use AVIndex feature.

If media file is malformed, ffmpeg has to be fixed to generate a good one AND to set nb_index_entries to 0 in this case.
If file is ok, ffmpeg has to be fixed so that each timestamp is valid and not negative.

comment:4 in reply to: ↑ 3 Changed 7 months ago by cehoyos

Replying to s0m3:

I don't see how a (presentation) time stamp can be negative. Time can't be negative.
Or maybe it means "too late" but first frame(s) cannot be late.

I suspect this makes no sense.

I know what correct timestamps are since (as you said) I created it.

Then please provide the ffmpeg command line that creates the input file you used with -debug_ts and the complete, uncut console output as attachment to prove your point.

comment:5 Changed 7 months ago by s0m3

It's rather obvious for me but I guess we don't talk about the same thing.
For me, "PTS" is a timestamp that specifies when I should display the frame on the screen.
Its value is the elapsed time from the beginning of the stream.
I convert it (from stream time unit) to 100ns unit for practical reason.

Suppose we have a stream at 25fps, each frame lasts 40ms = 400000 100ns.
So if I decode the 3 first frames, I should get pts 400000, 800000 and 120000.

When I start playing, I start my clock and I compute the remaining time before the next frame to display.
I sleep the amount of time I computed and when I wake up, I ask the clock what the current time is and test it against the next frame time.
If it's in my error margin, I display the frame, otherwise, I drop the frame and wait for the next frame.
My clock start at 0 100ns and run at realtime if playback rate is 100%.

I know frames are not stored (in the stream) in display order but it doesn't matter for me since it's decoder role to deliver me in the right order.

To answer your question, here are the steps to get the sample file attached to this bug:

1) create a 640x400 px white picture (I used Gimp) and save it as white.png
2) D:\>D:\ffmpeg-3.2.4-win32-shared\bin\ffmpeg.exe -loop 1 -i D:\white.png -t 60 D:\tmp.mp4 -debug_ts 2> logA.log
3) D:\>d:\ffmpeg-3.2.4-win32-shared\bin\ffmpeg.exe -i D:\tmp.mp4 -filter_complex "drawtext=fontfile=C\\:/Windows/Fonts/Tahoma.ttf: text='frame %{n} %{pict_type} %{pts}': x=100: y=50: fontsize=24" "D:\sample h264 with timecode.mp4" -debug_ts 2>
 D:\logB.log

The resulting file has the following md5 sum: a0d782eaa08bc4670baabdc2709d606d.
I compressed logA.log and logB.log into logs.7z and attached it to this bug.

Changed 7 months ago by s0m3

logs compressed from comment 5

Note: See TracTickets for help on using tickets.