[FFmpeg-devel] [PATCH] Fix failure in av_read_frame on timestamp rollover

Michael Niedermayer michaelni
Thu Jun 10 11:11:46 CEST 2010


On Thu, Jun 10, 2010 at 12:19:19PM +1000, Stephen Dredge i wrote:
> On 06/10/2010 03:25 AM, Michael Niedermayer wrote:
>> On Wed, Jun 09, 2010 at 03:02:52PM +1000, Stephen Dredge i wrote:
>>    
>>> av_read_frame can fail on some (TS) files at timestamp rollover, reading 
>>> to
>>> eof before returning a frame.
>>>
>>> The attached patch adds some utility functions for rollover aware 
>>> timestamp
>>> comparison  and uses them in av_read_frame to avoid problems at timestamp
>>> rollover.
>>>
>>> The utility functions provide normal comparisons if pts_wrap_bits is 0 or
>>>      
>>>> = 63 so behaviour on formats without timestamp wrapping should be
>>>>        
>>> unaffected.
>>>
>>> -- 
>>>    Stephen Dredge                        sdredge at tpg.com.au
>>> _______________________________________________________________
>>>   System Administrator
>>>   +61 2 9850 0979
>>>
>>>    TPG Internet
>>>   www.tpg.com.au
>>>
>>>
>>>
>>>      
>>    
>>>   libavformat/utils.c     |    9 ++++---
>>>   libavutil/mathematics.c |   59 
>>> ++++++++++++++++++++++++++++++++++++++++++++++++
>>>   libavutil/mathematics.h |   25 ++++++++++++++++++++
>>>   3 files changed, 89 insertions(+), 4 deletions(-)
>>> a5af48c8203ac3261e2c383073a131c64ca0d294  rollover_fix.patch
>>> diff --git a/libavformat/utils.c b/libavformat/utils.c
>>> index 6365f3e..02ffce1 100644
>>> --- a/libavformat/utils.c
>>> +++ b/libavformat/utils.c
>>> @@ -1152,18 +1152,19 @@ int av_read_frame(AVFormatContext *s, AVPacket 
>>> *pkt)
>>>       AVPacketList *pktl;
>>>       int eof=0;
>>>       const int genpts= s->flags&  AVFMT_FLAG_GENPTS;
>>> +    int wrap_bits;	
>>>
>>>       for(;;){
>>>           pktl = s->packet_buffer;
>>>           if (pktl) {
>>>               AVPacket *next_pkt=&pktl->pkt;
>>> -
>>> +            wrap_bits = 
>>> s->streams[next_pkt->stream_index]->pts_wrap_bits;		
>>>               if(genpts&&  next_pkt->dts != AV_NOPTS_VALUE){
>>>                   while(pktl&&  next_pkt->pts == AV_NOPTS_VALUE){
>>>                       if(   pktl->pkt.stream_index == 
>>> next_pkt->stream_index
>>> -&&  next_pkt->dts<  pktl->pkt.dts
>>>      
>>    
>>> -&&  pktl->pkt.pts != pktl->pkt.dts //not b frame
>>>      
>> a != check should
>>    
> dts can be negative and pts positive for the same time (compute_pkt_fields 
> can emit negative dts), so a mod comparison is required.
>> [...]
>>    
>>> +int64_t av_mod_wrap_bits(int64_t x, int wrap_bits){
>>> +	int64_t result;
>>> +	int64_t modulo;
>>> +	if(!wrap_bits || wrap_bits>= 63) {
>>> +		return x;
>>> +	}
>>> +	modulo = 1LL<<  wrap_bits;
>>> +	result = x % modulo;
>>> +	if(result<  0) {
>>> +		result += modulo;
>>> +	}
>>> +	return result;
>>> +}
>>> +
>>> +int av_gt_mod_wrap_bits(int64_t x, int64_t y, int wrap_bits){
>>> +	int64_t modulo;
>>> +	int64_t result;
>>> +	if(!wrap_bits || wrap_bits>= 63) {
>>> +		return x>y?1:0;
>>> +	}	
>>> +	modulo = 1LL<<  wrap_bits;
>>> +	result = av_mod_wrap_bits(x - y, wrap_bits);
>>> +	if(result<  modulo/2) {
>>> +		return 1;
>>> +	}
>>> +	return 0;
>>> +}
>>>      
>> this is a mess, ive added a much simpler av_compare_mod() that could be 
>> used
>>    
> Agreed it's clunky. I was going for clarity and simplicity of use over 
> elegance.
>
> av_compare_mod is not much help here. It can't be used for negative numbers 

a&(m-1) makes an argument positiv
but maybe the code messing with dts could be changed too, i dont know


> or where pts_wrap_bits = 64.

i dont see that problem

[...]
-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

Breaking DRM is a little like attempting to break through a door even
though the window is wide open and the only thing in the house is a bunch
of things you dont want and which you would get tomorrow for free anyway
-------------- 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/20100610/f5ec56e4/attachment.pgp>



More information about the ffmpeg-devel mailing list