[FFmpeg-devel] [PATCH] H264 parser fix

John Stebbins stebbins
Tue Sep 28 18:41:03 CEST 2010


 On 05/25/2010 03:26 PM, Michael Niedermayer wrote:
> On Tue, May 25, 2010 at 09:31:51AM -0700, Howard Chu wrote:
>> Michael Niedermayer wrote:
>>> On Tue, May 25, 2010 at 07:29:11AM -0700, Howard Chu wrote:
>>>> Michael Niedermayer wrote:
>>>>> On Mon, May 24, 2010 at 11:25:05AM -0700, Howard Chu wrote:
>>>>>> Michael Niedermayer wrote:
>>>>>>> On Wed, May 19, 2010 at 01:15:17AM -0700, Howard Chu wrote:
>>>>>>>> When decoding an H264 stream that uses global headers, you get an
>>>>>>>> endless
>>>>>>>> stream of "non-existing PPS referenced" messages. This message comes
>>>>>>>> from
>>>>>>>> h264_parser.c, and it happens because it's using an H264Context 
>>>>>>>> hanging
>>>>>>>> off
>>>>>>>> the AVCodecParserContext, which is separate from the H264Context
>>>>>>>> hanging
>>>>>>>> off the AVCodecContext, and only the AVCodecContext contains the
>>>>>>>> extradata
>>>>>>>> that provides the PPS and SPS.
>>>>>>>>
>>>>>>>> This patch is admittedly a hack, but it stops the error. It just 
>>>>>>>> checks
>>>>>>>> in
>>>>>>>> the AVCodecContext if the PPS wasn't found in the 
>>>>>>>> AVCodecParserContext.
>>>>>>> ugly ugly ugly
>>>>>>> if iam not mistaken this would be fixed by making the parser work with
>>>>>>> mov/mkv ("avc") style h264
>>>>>> I read thru mov.c and matroskadec.c and couldn't find anything 
>>>>>> relevant,
>>>>>> so
>>>>>> I don't understand what your suggestion means.
>>>>> i thought that the problem is that the parser is feeded a format it does
>>>>> not
>>>>> support. I did not confirm this but i see no reason that this is a
>>>>> different
>>>>> issue.
>>>> That is not the problem I was reporting. The parser has no trouble with 
>>>> the
>>>> data format. It is simply missing the PPS and SPS because they were not
>>>> available in the AVCodecParserContext. The extradata is only available in
>>>> the AVCodecContext.
>>>>
>>>>> The format difference should be easiest vissible by looking at code
>>>>> surrounding is_avc in h264.c
>>>>>
>>>>> if this is the issue the parser should be improved to suport the slghtly
>>>>> differnt way to pack things and also to look in extradata.
>>>> Before we can tell the parser to look in the extradata, we have to give 
>>>> the
>>>> parser a way to access it, ideally when the parser is initialized. Right
>>>> now there's no reliable way to do that.
>>> The parse function has the AVCodecContext extradata
>>>> It seems odd to me that the parser
>>>> entry points all require an AVCodecContext but av_parser_init() only 
>>>> takes
>>>> a codec_id. If av_parser_init() took an AVCodecContext instead, all of 
>>>> the
>>>> necessary information would be available.
>>> well, yes, its not given during init but just later, i dont see how this
>>> would be a problem
>> This patch works. It just means adding an if (extradata_not_parsed_yet) 
>> test in h264_parse(), instead of handling it unconditionally at init time. 
>> Probably a trivial overhead. I've just taken the extradata parsing code 
>> from ff_h264_decode_init() and broken it out into its own function so that 
>> h264_parse can use it too.
>>
>> -- 
>>   -- Howard Chu
>>   CTO, Symas Corp.           http://www.symas.com
>>   Director, Highland Sun     http://highlandsun.com/hyc/
>>   Chief Architect, OpenLDAP  http://www.openldap.org/project/
>> Index: libavcodec/h264_parser.c
>> ===================================================================
>> --- libavcodec/h264_parser.c	(revision 23295)
>> +++ libavcodec/h264_parser.c	(working copy)
>> @@ -245,6 +245,12 @@
>>      ParseContext *pc = &h->s.parse_context;
>>      int next;
>>  
>> +    /* Should a failure here cause the entire parse to fail? */
> no
>
>
>> +    if (!h->sps_buffers[0] && avctx->extradata_size) {
> that looks wrong, i dont think anything gurantees that there is a sps
> with sps_id=0
>
>
>
>> +        h->s.avctx = avctx;
>> +        ff_h264_decode_extradata(avctx, h);
>> +    }
>> +
>>      if(s->flags & PARSER_FLAG_COMPLETE_FRAMES){
>>          next= buf_size;
>>      }else{
>> Index: libavcodec/h264.c
>> ===================================================================
>> --- libavcodec/h264.c	(revision 23295)
>> +++ libavcodec/h264.c	(working copy)
>> @@ -844,41 +844,9 @@
>>      memset(h->pps.scaling_matrix8, 16, 2*64*sizeof(uint8_t));
>>  }
>>  
>> -av_cold int ff_h264_decode_init(AVCodecContext *avctx){
>> -    H264Context *h= avctx->priv_data;
>> -    MpegEncContext * const s = &h->s;
>> -
>> -    MPV_decode_defaults(s);
>> -
>> -    s->avctx = avctx;
>> -    common_init(h);
>> -
>> -    s->out_format = FMT_H264;
>> -    s->workaround_bugs= avctx->workaround_bugs;
>> -
>> -    // set defaults
>> -//    s->decode_mb= ff_h263_decode_mb;
>> -    s->quarter_sample = 1;
>> -    if(!avctx->has_b_frames)
>> -    s->low_delay= 1;
>> -
>> -    avctx->chroma_sample_location = AVCHROMA_LOC_LEFT;
>> -
>> -    ff_h264_decode_init_vlc();
>> -
>> -    h->thread_context[0] = h;
>> -    h->outputed_poc = INT_MIN;
>> -    h->prev_poc_msb= 1<<16;
>> -    h->x264_build = -1;
>> -    ff_h264_reset_sei(h);
>> -    if(avctx->codec_id == CODEC_ID_H264){
>> -        if(avctx->ticks_per_frame == 1){
>> -            s->avctx->time_base.den *=2;
>> -        }
>> -        avctx->ticks_per_frame = 2;
>> -    }
>> -
>> -    if(avctx->extradata_size > 0 && avctx->extradata && *(char *)avctx->extradata == 1){
>> +int ff_h264_decode_extradata(AVCodecContext *avctx, H264Context *h)
> no need to pass AVCodecContext if its in h->s.avctx
>
> also the factorization should be a seperate patch
>
> [...]
>
Any movement on this issue? Still seeing it in svn 25249.  Avatar BD m2ts is a good example of the problem.




More information about the ffmpeg-devel mailing list