[FFmpeg-devel] [PATCH] H.264 timestamps in h264_parser - complete set
Michael Niedermayer
michaelni
Wed Feb 18 13:18:24 CET 2009
On Wed, Feb 18, 2009 at 12:33:57PM +0100, Ivan Schreter wrote:
> Michael Niedermayer wrote:
>> On Tue, Feb 17, 2009 at 09:57:32PM +0100, Ivan Schreter wrote:
>> [...]
>>
>>> Index: libavcodec/h264.c
>>> ===================================================================
>>> --- libavcodec/h264.c (revision 17130)
>>> +++ libavcodec/h264.c (working copy)
>>> @@ -6920,6 +6959,7 @@
>>> sps->cpb_removal_delay_length = get_bits(&s->gb, 5) + 1;
>>> sps->dpb_output_delay_length = get_bits(&s->gb, 5) + 1;
>>> sps->time_offset_length = get_bits(&s->gb, 5);
>>> + h->cpb_cnt = cpb_count;
>>> return 0;
>>> }
>>>
>>
>> are you sure this belongs in h instead of sps ?
>>
>>
> You are right, it should go to SPS. Moved there, updated patch #4 attached.
> OK now?
yes "#4" is ok now
[...]
>> [...]
>>
>>
>>> @@ -6859,6 +6860,37 @@
>>> return 0;
>>> }
>>>
>>> +static int decode_buffering_period(H264Context *h){
>>> + MpegEncContext * const s = &h->s;
>>> + int sps_id;
>>> + int sched_sel_idx;
>>> + SPS *sps;
>>> +
>>> + sps_id = get_ue_golomb_31(&s->gb);
>>>
>>
>> this is missing a validity check (<32 i suspect but didnt check)
>> also as this would have been possibly exploitable, please be carefull not
>> to
>> miss such checks
>>
> According to docs of get_ue_golomb_31(), it can only return value in range
> 0..31. SPS ID can be in range 0..31 as well, so no check required. However,
> looking at get_ue_golomb_31() code, the lookup table contains also return
> value of 32! So either doc is wrong or the lookup table is wrong. I've
> added the check to be on the safe side.
fixed doc, and you need to make the check unsigned
>
>> [...]
>> also initial_cpb_removal_delay_offset is unused in your patchset thus
>> there seems no need to store it
>>
> Yes. I stored it for completeness. Removed again.
no initial_cpb_removal_delay_offset is still there
>
>> [...]
>>> @@ -516,5 +520,8 @@
>>> // Timestamp stuff
>>> int cpb_cnt; ///< See H.264 E.1.2
>>> + int sei_buffering_period_present_flag; ///< Buffering period SEI
>>> flag
>>>
>>
>> i think sei_buffering_period_present is a better name but that can be
>> done after all patches are in svn (together with renaming the other _flag
>> fields)
>>
> Renamed.
>
> Attached updated patch #6. OK now?
see above
>
>>
>> [...]
>>
>>> Index: libavcodec/avcodec.h
>>> ===================================================================
>>> --- libavcodec/avcodec.h (revision 17392)
>>> +++ libavcodec/avcodec.h (working copy)
>>> @@ -3022,6 +3022,15 @@
>>> int flags;
>>> #define PARSER_FLAG_COMPLETE_FRAMES 0x0001
>>> +/*!
>>> + * Set by parser initialization routine to indicate presence of key
>>> frame flag.
>>> + * By default, I-frames are considered key frames. E.g., for H.264, this
>>> is not
>>> + * always the case. If this flag is set, lavf will use
>>> PARSER_FLAG_KEY_FRAME
>>> + * flag to detect if the current frame is a key frame or not.
>>> + */
>>> +#define PARSER_FLAG_KEY_FRAME_FLG_PRESENT 0x0002
>>> +/// Key frame flag
>>> +#define PARSER_FLAG_KEY_FRAME 0x0004
>>> int64_t offset; ///< byte offset from starting packet start
>>> int64_t cur_frame_end[AV_PARSER_PTS_NB];
>>> Index: libavformat/utils.c
>>> ===================================================================
>>> --- libavformat/utils.c (revision 17392)
>>> +++ libavformat/utils.c (working copy)
>>> @@ -904,8 +904,15 @@
>>> else if (pc) {
>>> pkt->flags = 0;
>>> /* keyframe computation */
>>> + if (pc->flags & PARSER_FLAG_KEY_FRAME_FLG_PRESENT) {
>>> + // use key flag
>>> + if (pc->flags & PARSER_FLAG_KEY_FRAME)
>>> + pkt->flags |= PKT_FLAG_KEY;
>>> + } else {
>>> + // use I-type picture as key flag
>>> if (pc->pict_type == FF_I_TYPE)
>>> pkt->flags |= PKT_FLAG_KEY;
>>> + }
>>> }
>>> }
>>>
>>
>> I do not like this implementation
>> its not hard to add a keyframe field and set that to -1 by default
>> and treat that default as I_TYPE == keyframe
>>
> I can do that easily (also wanted originally), but what about binary
> compatibility? If I add a field, minor version must be bumped up, right?
> How do I do that?
you increase minor by 1 and rest micro to 0
>
> Furthermore, lavf must check version of lavc whether the field exists at
> all.
>
> Again, no problem to go this way, but I simply don't know how to do it
> correctly. Please explain in more detail (and maybe a howto on FFmpeg
> website would be also a good investition :-).
>
> Or do we expect to have same SVN revision of lavf and lavc on the system
> (at least under same major/minor)?
lets assume we now have
lavc 1.2.3
lavf 2.3.4
then when keyframe is added
lavc 1.3.0
lavf 2.3.5 would depend on lavc >= 1.3.0
the old 2.3.4 would work with 1.3.0 as well
>
>>
>> [...]
>>
>>> Index: libavcodec/h264_parser.c
>>> ===================================================================
>>> --- libavcodec/h264_parser.c (revision 17392)
>>> +++ libavcodec/h264_parser.c (working copy)
>>> @@ -171,6 +171,33 @@
>>> /* key frame, since recovery_frame_cnt is set */
>>> s->flags |= PARSER_FLAG_KEY_FRAME;
>>> }
>>> + pps_id= get_ue_golomb(&h->s.gb);
>>> + if(pps_id>=MAX_PPS_COUNT) {
>>> + av_log(h->s.avctx, AV_LOG_ERROR, "pps_id out of
>>> range\n");
>>> + return -1;
>>> + }
>>> + if(!h->pps_buffers[pps_id]) {
>>> + av_log(h->s.avctx, AV_LOG_ERROR, "non-existing PPS
>>> referenced\n");
>>> + return -1;
>>> + }
>>> + h->pps= *h->pps_buffers[pps_id];
>>> + if(!h->sps_buffers[h->pps.sps_id]) {
>>> + av_log(h->s.avctx, AV_LOG_ERROR, "non-existing SPS
>>> referenced\n");
>>> + return -1;
>>> + }
>>> + h->sps = *h->sps_buffers[h->pps.sps_id];
>>> + h->frame_num = get_bits(&h->s.gb,
>>> h->sps.log2_max_frame_num);
>>> +
>>> + if (h->sps.frame_mbs_only_flag) {
>>> + /* single picture for a frame */
>>> + h->field_pic_flag = 0;
>>> + } else {
>>> + h->field_pic_flag = get_bits1(&h->s.gb);
>>> + if (h->field_pic_flag) {
>>> + h->bottom_field_flag = get_bits1(&h->s.gb);
>>> + }
>>> + }
>>> +
>>> return 0; /* no need to evaluate the rest */
>>> }
>>> buf += consumed;
>>>
>>
>> this maybe can be factored with h264.c
>>
> Yes. I was thinking about creating additional function like
> ff_h264_decode_slice_header_0(), which would contain the first part of
> decode_slice_header(), which is relevant for parser. Do you have a better
> name suggestion?
not at the moment but maybe i come up with something later
[...]
--
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/20090218/f2c996d8/attachment.pgp>
More information about the ffmpeg-devel
mailing list