[FFmpeg-devel] [PATCH] H.264/AVCHD interlaced fixes
Michael Niedermayer
michaelni
Tue Feb 3 14:55:11 CET 2009
On Sat, Jan 31, 2009 at 04:30:01PM +0100, Ivan Schreter wrote:
> Hi *,
>
> here the patch to correct some problems when working with interlaced
> H.264/AVCHD files. Two primary problems are addressed:
> - lack of key frame support in H.264 decoder (this is also relevant
> for progressive)
> - proper handling of field pictures for interlaced mode (two fields
> coded as separate pictures instead of one picture per frame)
>
> Please review it and eventually apply it as-is. Note that I won't have
> much time to fix anything in near future, as my first child is going to
> be born in next couple of days. So it would be good to get through with
> this fix before that happens :-)
>
> How it works?
>
> To support key frames, SEI message recovery point is decoded and recovery
> frame count stored on the context. This is then used to set key frame flag
> in decoding process. In the parser, it is used to communicate (synthetic)
> picture type to libavformat's av_read_frame() routine to correctly set key
> flag and compute missing PTS/DTS timestamps. This should be corrected
> by extending appropriate context structure by adding key frame flag and
> recovery frame count, but I didn't want to do this, since a) it would
> potentially break binary compatiblility and b) one has to fix it in all
> parsers.
>
> To support interlaced mode, it was needed to collate two field pictures
> into one buffer to fulfill av_read_frame() contract - i.e., reading one
> whole frame per call. This is done in h264_parser.c by testing picture
> structure and if a field image is detected, by waiting until the rest
> of the frame (second field) comes in, before returning a buffer.
>
> Additionally,
every additionally belongs in a seperate patch
[...]
> Index: libavcodec/h264.c
> ===================================================================
> --- libavcodec/h264.c (revision 16851)
> +++ libavcodec/h264.c (working copy)
> @@ -1359,14 +1359,7 @@
> }
> }
>
> -/**
> - * Decodes a network abstraction layer unit.
> - * @param consumed is the number of bytes used as input
> - * @param length is the length of the array
> - * @param dst_length is the number of decoded bytes FIXME here or a decode rbsp tailing?
> - * @returns decoded bytes, might be src+1 if no escapes
> - */
> -static const uint8_t *decode_nal(H264Context *h, const uint8_t *src, int *dst_length, int *consumed, int length){
> +const uint8_t *ff_h264_decode_nal(H264Context *h, const uint8_t *src, int *dst_length, int *consumed, int length){
> int i, si, di;
> uint8_t *dst;
> int bufidx;
this stuff belongs in a seperate patch
[...]
> @@ -3766,6 +3755,8 @@
> }
> }
>
> + if(h->sps.separate_colour_plane_flag)
> + get_bits(&s->gb, 2); // FIXME: implement support for colour_plane_id
> h->frame_num= get_bits(&s->gb, h->sps.log2_max_frame_num);
>
> h->mb_mbaff = 0;
this too belongs in a sperate patch
> @@ -6836,9 +6827,18 @@
> return 0;
> }
>
> -static int decode_sei(H264Context *h){
> +static int decode_recovery_point(H264Context *h){
> MpegEncContext * const s = &h->s;
>
> + h->sei_recovery_frame_cnt = get_ue_golomb(&s->gb); /* recovery_frame_cnt */
> + skip_bits(&s->gb, 4); /* 1b exact_match_flag, 1b broken_link_flag, 2b changing_slice_group_idc */
> +
> + return 0;
> +}
> +
> +int ff_h264_decode_sei(H264Context *h){
> + MpegEncContext * const s = &h->s;
> +
> while(get_bits_count(&s->gb) + 16 < s->gb.size_in_bits){
> int size, type;
>
so does this
> @@ -6853,14 +6853,18 @@
> }while(get_bits(&s->gb, 8) == 255);
>
> switch(type){
> - case 1: // Picture timing SEI
> + case SEI_TYPE_PIC_TIMING: // Picture timing SEI
> if(decode_picture_timing(h) < 0)
> return -1;
> break;
> - case 5:
> + case SEI_TYPE_USER_DATA_UNREGISTERED:
> if(decode_unregistered_user_data(h, size) < 0)
> return -1;
> break;
replacing litteral numbers by named ones is very welcome but again
seperate patch
[...]
> @@ -49,10 +51,10 @@
> * and there should be FF_INPUT_BUFFER_PADDING_SIZE bytes at the end
> */
> # if HAVE_FAST_64BIT
> - while(i<buf_size && !((~*(uint64_t*)(buf+i) & (*(uint64_t*)(buf+i) - 0x0101010101010101ULL)) & 0x8080808080808080ULL))
> + while(i<buf_size && !((~*(const uint64_t*)(buf+i) & (*(const uint64_t*)(buf+i) - 0x0101010101010101ULL)) & 0x8080808080808080ULL))
> i+=8;
> # else
> - while(i<buf_size && !((~*(uint32_t*)(buf+i) & (*(uint32_t*)(buf+i) - 0x01010101U)) & 0x80808080U))
> + while(i<buf_size && !((~*(const uint32_t*)(buf+i) & (*(const uint32_t*)(buf+i) - 0x01010101U)) & 0x80808080U))
> i+=4;
> # endif
> #endif
again seperate patch
[...]
--
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
The bravest are surely those who have the clearest vision
of what is before them, glory and danger alike, and yet
notwithstanding go out to meet it. -- Thucydides
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20090203/eb2d0d9d/attachment.pgp>
More information about the ffmpeg-devel
mailing list