[FFmpeg-devel] [BUG] h264 picture reordering fails

Haruhiko Yamagata h.yamagata
Sat May 30 14:01:41 CEST 2009


>On Sat, May 30, 2009 at 07:34:32PM +0900, Haruhiko Yamagata wrote:
>> I found picture reordering fails in
>> http://x264.nl/h.264.samples/premiere-paff.ts
>>
>> Outputted pictures have POC {-4, -2, 4, 0, 2, 6}.
>> Are negative POCs allowed?
>>
>> If yes, zero as POC is valid as well.
>>
>> But, in h264.c decode_frame,
>>            for(i=1; h->delayed_pic[i] && (h->delayed_pic[i]->poc &&
>> !h->delayed_pic[i]->key_frame); i++)
>> This code assume poc zero is special. The case above is not supported.
>> If I comment out /* h->delayed_pic[i]->poc && */, then it works for the
>> sample.
>>
>> This is just a bug report, but if you give me a hint, I'm willing to work
>> on this.
>
>is has_b_frames set to the correct value?

Yes, it is 1.

>about POCs, IIRC the spec requires POC=0 to be true and only true for
>IDR pictures, but i might misremember (would have to check the spec)
>What i do know is that the POC or frame number == 0 rules in the spec
>are not followed by some encoders.

Yes, I think POC=0 means IDR. In that case, negative values as POC are
not allowed.

In the stream, h->sps.poc_type is 0. Just after seeking, in decode_slice_header,

>    if(h->sps.poc_type==0){
>        h->poc_lsb= get_bits(&s->gb, h->sps.log2_max_poc_lsb);

h->poc_lsb is 434 now. And then, in init_poc,

>        if     (h->poc_lsb < h->prev_poc_lsb && h->prev_poc_lsb - h->poc_lsb >= max_poc_lsb/2)
>            h->poc_msb = h->prev_poc_msb + max_poc_lsb;
>        else if(h->poc_lsb > h->prev_poc_lsb && h->prev_poc_lsb - h->poc_lsb < -max_poc_lsb/2){
>            h->poc_msb = h->prev_poc_msb - max_poc_lsb;
>            av_log(NULL,AV_LOG_DEBUG,
>                "h->poc_lsb %d h->poc_msb %d h->prev_poc_lsb %d h->prev_poc_msb %d max_poc_lsb %d",
>                h->poc_lsb, h->poc_msb, h->prev_poc_lsb, h->prev_poc_msb, max_poc_lsb);
>        }
>        else
>            h->poc_msb = h->prev_poc_msb;
>//printf("poc: %d %d\n", h->poc_msb, h->poc_lsb);
>        field_poc[0] =
>        field_poc[1] = h->poc_msb + h->poc_lsb;

I added av_log. The output is
h->poc_lsb 434 h->poc_msb -512 h->prev_poc_lsb 0 h->prev_poc_msb 0 max_poc_lsb 512

As I don't understand the logic and calculation for now, I don't know how to fix.

Best regards,
Haruhiko Yamagata




More information about the ffmpeg-devel mailing list