Opened 6 years ago

Closed 5 years ago

#7083 closed defect (fixed)

Decoder playing out frames at double speed

Reported by: baudouin0 Owned by:
Priority: normal Component: avcodec
Version: git-master Keywords: h264
Cc: Blocked By:
Blocking: Reproduced by developer: no
Analyzed by developer: no

Description

Summary of the bug:

sps->time_scale is being doubled on h264_slice_header_init().
After second frame h->x264_build is set to zero rather than -1 causing frame rate to be doubled.

How to reproduce:

ffmpeg -i test.264 out%d.bmp

Added printf to check:
static int h264_slice_header_init(H264Context *h)
{

const SPS *sps = h->ps.sps;
int i, ret;

ff_set_sar(h->avctx, sps->sar);
av_pix_fmt_get_chroma_sub_sample(h->avctx->pix_fmt,

&h->chroma_x_shift, &h->chroma_y_shift);

if (sps->timing_info_present_flag) {

int64_t den = sps->time_scale;
printf("h264_slice_header_init() build=%d time_scale=%d ticks_per_frame=%d num_units_in_tick=%d\n", h->x264_build, sps->time_scale, h->avctx->ticks_per_frame, sps->num_units_in_tick);
if (h->x264_build < 44U)

den *= 2;

av_reduce(&h->avctx->framerate.den, &h->avctx->framerate.num,

sps->num_units_in_tick * h->avctx->ticks_per_frame, den, 1 << 30);

}

Output from decoder is:ffmpeg version N-90264-g80798e3 Copyright (c) 2000-2018 the FFmpeg developers

built with gcc 4.8 (Ubuntu 4.8.4-2ubuntu1~14.04.4)
configuration:
libavutil 56. 8.100 / 56. 8.100
libavcodec 58. 14.100 / 58. 14.100
libavformat 58. 10.100 / 58. 10.100
libavdevice 58. 2.100 / 58. 2.100
libavfilter 7. 12.100 / 7. 12.100
libswscale 5. 0.102 / 5. 0.102
libswresample 3. 0.101 / 3. 0.101

h264_slice_header_init() build=-1 time_scale=50000 ticks_per_frame=2 num_units_in_tick=1000
Input #0, h264, from 'test.264':

Duration: N/A, bitrate: N/A

Stream #0:0: Video: h264 (High), yuv420p(progressive), 704x576 [SAR 12:11 DAR 4:3], 25 fps, 25 tbr, 1200k tbn, 50 tbc

Stream mapping:

Stream #0:0 -> #0:0 (h264 (native) -> bmp (native))

Press [q] to stop, ? for help
h264_slice_header_init() build=-1 time_scale=50000 ticks_per_frame=2 num_units_in_tick=1000
h264_slice_header_init() build=0 time_scale=50000 ticks_per_frame=2 num_units_in_tick=1000
h264_slice_header_init() build=0 time_scale=50000 ticks_per_frame=2 num_units_in_tick=1000
h264_slice_header_init() build=0 time_scale=50000 ticks_per_frame=2 num_units_in_tick=1000
h264_slice_header_init() build=0 time_scale=50000 ticks_per_frame=2 num_units_in_tick=1000
h264_slice_header_init() build=0 time_scale=50000 ticks_per_frame=2 num_units_in_tick=1000
h264_slice_header_init() build=0 time_scale=50000 ticks_per_frame=2 num_units_in_tick=1000
h264_slice_header_init() build=0 time_scale=50000 ticks_per_frame=2 num_units_in_tick=1000
h264_slice_header_init() build=0 time_scale=50000 ticks_per_frame=2 num_units_in_tick=1000
Output #0, image2, to 'xxx%d.bmp':

Metadata:

encoder : Lavf58.10.100
Stream #0:0: Video: bmp, bgr24, 704x576 [SAR 12:11 DAR 4:3], q=2-31, 200 kb/s, 25 fps, 25 tbn, 25 tbc
Metadata:

encoder : Lavc58.14.100 bmp

Note x264_build becomes zero.
Built ob x64 linux with gcc 4.8.4

Attachments (1)

test.264 (1.9 MB ) - added by baudouin0 6 years ago.
H264 test file

Download all attachments as: .zip

Change History (10)

by baudouin0, 6 years ago

Attachment: test.264 added

H264 test file

comment:1 by baudouin0, 6 years ago

I can fix the issue by adding

h264_init_context(AVCodecContext *avctx, H264Context *h) {

+ h->x264_build = -1;

}

but don't think this is correct fix.

comment:2 by Carl Eugen Hoyos, 6 years ago

Keywords: h264 added; double playout rate removed

You put a complete analysis into your description (which usually indicates you could fix the issue instead of filing a bug report) but I wonder how I can reproduce the original issue: How can I get double speed output, how does your fix change timestamps?

comment:3 by baudouin0, 6 years ago

Many thanks for the quick response.

When we play a mpeg transport stream into the decoder (ffplay or VLC 3.0.1) we see the I-frame (which has a PTS time stamp in the ts before the SPS) played out followed by the P-frames at double speed then a gap before the next I-frame (and PTS) comes along. This does not happen on VLC 2.2.8 but I have not found which version of ffmpeg these are built with. In trying to find out the cause of this problem we discovered the bug that the h->x264_build becomes zero rather than -1. So I added printf into the code as I have shown into h264_slice_header_init(). You can then see this with the bitstream I have sent. We can also fix the issue be setting time_scale in the h264 bitstream to 25000 rather than 50000 but this is not correct as H264 ticks are always in fields regardless of the picture structure.

in reply to:  3 comment:4 by Carl Eugen Hoyos, 6 years ago

Replying to baudouin0:

You can then see this with the bitstream I have sent.

How?
What do I have to do to see the double speed issue?

comment:5 by baudouin0, 6 years ago

What I am saying is if you rebuild the ffmpeg code with the line

printf("h264_slice_header_init() build=%d time_scale=%d ticks_per_frame=%d num_units_in_tick=%d\n", h->x264_build, sps->time_scale, h->avctx->ticks_per_frame, sps->num_units_in_tick);

and run it on the bitstream I sent.

You will see that the variable x264_build becomes zero. This is a bug as it affects the way your decoder operates including the way in which the ticks and time scale are interpreted.

Its up to you then to get to the bottom of it.

in reply to:  5 comment:6 by Carl Eugen Hoyos, 6 years ago

Replying to baudouin0:

What I am saying is if you rebuild the ffmpeg code with the line

printf("h264_slice_header_init() build=%d time_scale=%d ticks_per_frame=%d num_units_in_tick=%d\n", h->x264_build, sps->time_scale, h->avctx->ticks_per_frame, sps->num_units_in_tick);

and run it on the bitstream I sent.

You will see that the variable x264_build becomes zero.

Yes, I saw this and I wrote above that I read this analysis that you sent.

This is a bug as it affects the way your decoder operates including the way in which the ticks and time scale are interpreted.

My question is: How does it affect the way the decoder operates? How can I see a difference (be it in playback speed or something else) if I fix the issue with the poc you posted?

comment:7 by baudouin0, 6 years ago

Ok I understand - when I played the ts steam in VLC media player or our own player (using ffmpeg) we saw the issue in that the picture would stutter with the P-frames comming out twice as fast and then a pause before the next I-frame. As that is quite complicated we looked into just compiling ffmpeg on its own and found this. Your right that it could be another issue we have not yet found. However that variable being set to zero is not correct. I may be able to use ffplay to see what the fix does. My understanding of what was intended in the code is limited so I not sure on the correct fix.

I will try ffplay and get back to you.

comment:8 by baudouin0, 6 years ago

You are correct in that is does not appear to have any affect on the playout.
You can close this case if you wish.

comment:9 by Carl Eugen Hoyos, 5 years ago

Resolution: fixed
Status: newclosed

The issue should be fixed by Derek in b1504e7796a420c8748a2dcb12a2b780ecf42c04

Note: See TracTickets for help on using tickets.