[FFmpeg-devel] [PATCH] AVCHD/H.264 parser: determination of frame type, question about timestamps

Ivan Schreter schreter
Fri Jan 23 22:46:39 CET 2009


Hi,

Michael Niedermayer wrote:
> On Mon, Jan 19, 2009 at 09:22:27PM +0100, Ivan Schreter wrote
>> +    s->pict_type= FF_I_TYPE;
>>     
> useless?
>   
Most probably. Each (ffmpeg) frame will have at least one (H.264) slice.
>> +    while(buf<buf_end){
>> +        buf= ff_find_start_code(buf, buf_end, &state);
>> +        init_get_bits(&h->s.gb, buf, 8*(buf_end - buf));
>> +        switch(state & 0x1F){
>> [...]
>> +        case NAL_IDR_SLICE:
>> +        case NAL_SLICE:
>> +            get_ue_golomb(&h->s.gb);
>> +            s->pict_type= golomb_to_pict_type[get_ue_golomb(&h->s.gb) % 5];
>>     
> IIRC that should be get_ue_golomb_31() also its missing some check against
> negative values
>   
I don't believe so. First, slice_type is defined in H.264 standard in 
7.3.3 (Slice header syntax) being ue(v), so not limited to 31. If I 
understand golomb.h correctly, this corresponds to get_ue_golomb(). Of 
course, since there are just 5 slice types, this value should be small, 
but some broken encoder could write something else in there. Do we want 
to live with it (and save just a single if per picture)? Further, it is 
unsigned, so it can't be negative. And modulo 5 makes it always being in 
the range 0..4, as in the array.

I now dived a little more into H.264 standard in the search how to 
correctly get key frames for seeking.

As I see, just getting type of one slice is not quite correct. Although 
the AVCHD/H.264 files I have at hand all use one slice per field, in 
H.264, it seems to be allowed to have also several slices. And even if 
the slice is an I-slice, it doesn't mean it is going to be a key frame 
in ffmpeg sense.

In H.264, the only "sure" key frames (in the sense of AVPacket::flags) 
are IDR pictures. However, in the sample files I have, there are 
actually no IDR pictures (save the very first one)... So even misusing 
pict_type by filling it with FF_I_TYPE only for IDR pictures would not 
help to compute key frames correctly.

I believe the only way is to use recovery point SEI message as 
documented in H.264 spec Chapter D.2.7 and count down recovery_frame_cnt 
frames before issuing a "key frame" in order for seeking to work 
properly (well, it's a prerequisite, not a solution). But again, how to 
communicate this to avformat, so it can correctly set key frame? 
Currenty, compute_pkt_fields() does this:

    /* update flags */
    if(is_intra_only(st->codec))
        pkt->flags |= PKT_FLAG_KEY;
    else if (pc) {
        pkt->flags = 0;
        /* keyframe computation */
            if (pc->pict_type == FF_I_TYPE)
                pkt->flags |= PKT_FLAG_KEY;
    }

which is IMHO broken. Of course, we could communicate with it by setting 
pict_type to FF_I_TYPE for keyframes only (IDR frames and frames after 
recovery point), for other frames containing I- and P-slices to 
FF_P_TYPE and for B-frames to FF_B_TYPE. But I don't like it much. Any 
idea, how to do it correctly without the need to touch other codecs?

Further, I found out that av_read_frame() sometimes reads only one field 
of a frame (especially in interlaced mpegts AVCHD files), which confuses 
the rest of ffmpeg. I suppose, this is a bug in h264_parse(), which 
returns a single field instead of whole frame (when a frame is coded as 
two fields in two pictures), but I didn't find a way yet, how to address 
the problem. Any idea?

>> Index: libavformat/mpegts.c
>>     
> doesnt belong in this patch
>   
OK, separated it into another patch (e-mail was already sent and if it 
won't get applied now, I'll probably start a new thread for it).

Regards,

Ivan




More information about the ffmpeg-devel mailing list