[FFmpeg-devel] [PATCH] Fix failure in av_read_frame on timestamp rollover
Michael Niedermayer
michaelni
Wed Jun 9 19:25:14 CEST 2010
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 work
[...]
> +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
[...]
--
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
When you are offended at any man's fault, turn to yourself and study your
own failings. Then you will forget your anger. -- Epictetus
-------------- 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/20100609/18f172fd/attachment.pgp>
More information about the ffmpeg-devel
mailing list