Merge remote-tracking branch 'qatar/master'
authorMichael Niedermayer <michaelni@gmx.at>
Fri, 6 Jan 2012 01:45:12 +0000 (02:45 +0100)
committerMichael Niedermayer <michaelni@gmx.at>
Fri, 6 Jan 2012 01:45:12 +0000 (02:45 +0100)
* qatar/master: (21 commits)
  ipmovie: do not read audio packets before the codec is known
  truemotion2: check size before GetBitContext initialisation
  avio: Only do implicit network initialization for network protocols
  avio: Add an URLProtocol flag for indicating that a protocol uses network
  adpcm: ADPCM Electronic Arts has always two channels
  matroskadec: Fix a bug where a pointer was cached to an array that might later move due to a realloc()
  fate: Add missing reference file from 9b4767e4.
  mov: Support MOV_CH_LAYOUT_USE_DESCRIPTIONS for labeled descriptions.
  4xm: Prevent buffer overreads.
  mjpegdec: parse RSTn to prevent skipping other data in mjpeg_decode_scan
  vp3: add fate test for non-zero last coefficient
  vp3: fix streams with non-zero last coefficient
  swscale: remove unused U/V arguments from yuv2rgb_write().
  timer: K&R formatting cosmetics
  lavf: cosmetics, reformat av_read_frame().
  lavf: refactor av_read_frame() to make it easier to understand.
  Report an error if pitch_lag is zero in AMR-NB decoder.
  Revert "4xm: Prevent buffer overreads."
  4xm: Prevent buffer overreads.
  4xm: pass the correct remaining buffer size to decode_i2_frame().
  ...

Conflicts:
libavcodec/4xm.c
libavcodec/mjpegdec.c
libavcodec/truemotion2.c
libavformat/ipmovie.c
libavformat/mov_chan.c

Merged-by: Michael Niedermayer <michaelni@gmx.at>
28 files changed:
libavcodec/4xm.c
libavcodec/adpcm.c
libavcodec/amrnbdec.c
libavcodec/mjpegdec.c
libavcodec/truemotion2.c
libavcodec/vp3.c
libavformat/avio.c
libavformat/avio.h
libavformat/gopher.c
libavformat/http.c
libavformat/ipmovie.c
libavformat/librtmp.c
libavformat/mmsh.c
libavformat/mmst.c
libavformat/mov.c
libavformat/mov_chan.c
libavformat/mov_chan.h
libavformat/rtmpproto.c
libavformat/rtpproto.c
libavformat/tcp.c
libavformat/tls.c
libavformat/udp.c
libavformat/url.h
libavformat/utils.c
libavutil/timer.h
libswscale/swscale.c
tests/fate/vpx.mak
tests/ref/fate/vp3-coeff-level64 [new file with mode: 0644]

index e57ce90..d665436 100644 (file)
@@ -643,9 +643,17 @@ static int decode_i2_frame(FourXContext *f, const uint8_t *buf, int length){
     int x, y, x2, y2;
     const int width= f->avctx->width;
     const int height= f->avctx->height;
+    const int mbs = (FFALIGN(width, 16) >> 4) * (FFALIGN(height, 16) >> 4);
     uint16_t *dst= (uint16_t*)f->current_picture.data[0];
     const int stride= f->current_picture.linesize[0]>>1;
     const uint8_t *buf_end = buf + length;
+    GetByteContext g3;
+
+    if(length < mbs * 8) {
+        av_log(f->avctx, AV_LOG_ERROR, "packet size too small\n");
+        return AVERROR_INVALIDDATA;
+    }
+    bytestream2_init(&g3, buf, length);
 
     for(y=0; y<height; y+=16){
         for(x=0; x<width; x+=16){
@@ -654,8 +662,8 @@ static int decode_i2_frame(FourXContext *f, const uint8_t *buf, int length){
                 return -1;
             memset(color, 0, sizeof(color));
 //warning following is purely guessed ...
-            color[0]= bytestream_get_le16(&buf);
-            color[1]= bytestream_get_le16(&buf);
+            color[0]= bytestream2_get_le16u(&g3);
+            color[1]= bytestream2_get_le16u(&g3);
 
             if(color[0]&0x8000) av_log(NULL, AV_LOG_ERROR, "unk bit 1\n");
             if(color[1]&0x8000) av_log(NULL, AV_LOG_ERROR, "unk bit 2\n");
@@ -663,7 +671,7 @@ static int decode_i2_frame(FourXContext *f, const uint8_t *buf, int length){
             color[2]= mix(color[0], color[1]);
             color[3]= mix(color[1], color[0]);
 
-            bits= bytestream_get_le32(&buf);
+            bits= bytestream2_get_le32u(&g3);
             for(y2=0; y2<16; y2++){
                 for(x2=0; x2<16; x2++){
                     int index= 2*(x2>>2) + 8*(y2>>2);
@@ -672,7 +680,7 @@ static int decode_i2_frame(FourXContext *f, const uint8_t *buf, int length){
             }
             dst+=16;
         }
-        dst += 16*stride - width;
+        dst += 16 * stride - x;
     }
 
     return 0;
@@ -823,7 +831,7 @@ static int decode_frame(AVCodecContext *avctx,
 
     if(frame_4cc == AV_RL32("ifr2")){
         p->pict_type= AV_PICTURE_TYPE_I;
-        if(decode_i2_frame(f, buf-4, frame_size+4) < 0){
+        if(decode_i2_frame(f, buf-4, frame_size + 4) < 0) {
             av_log(f->avctx, AV_LOG_ERROR, "decode i2 frame failed\n");
             return -1;
         }
index 688fba4..c176b5e 100644 (file)
@@ -91,9 +91,13 @@ typedef struct ADPCMDecodeContext {
 static av_cold int adpcm_decode_init(AVCodecContext * avctx)
 {
     ADPCMDecodeContext *c = avctx->priv_data;
+    unsigned int min_channels = 1;
     unsigned int max_channels = 2;
 
     switch(avctx->codec->id) {
+    case CODEC_ID_ADPCM_EA:
+        min_channels = 2;
+        break;
     case CODEC_ID_ADPCM_EA_R1:
     case CODEC_ID_ADPCM_EA_R2:
     case CODEC_ID_ADPCM_EA_R3:
@@ -101,7 +105,7 @@ static av_cold int adpcm_decode_init(AVCodecContext * avctx)
         max_channels = 6;
         break;
     }
-    if (avctx->channels <= 0 || avctx->channels > max_channels) {
+    if (avctx->channels < min_channels || avctx->channels > max_channels) {
         av_log(avctx, AV_LOG_ERROR, "Invalid number of channels\n");
         return AVERROR(EINVAL);
     }
index 57c8ae9..c560d69 100644 (file)
@@ -978,6 +978,10 @@ static int amrnb_decode_frame(AVCodecContext *avctx, void *data,
 
         pitch_sharpening(p, subframe, p->cur_frame_mode, &fixed_sparse);
 
+        if (fixed_sparse.pitch_lag == 0) {
+            av_log(avctx, AV_LOG_ERROR, "The file is corrupted, pitch_lag = 0 is not allowed\n");
+            return AVERROR_INVALIDDATA;
+        }
         ff_set_fixed_vector(p->fixed_vector, &fixed_sparse, 1.0,
                             AMR_SUBFRAME_SIZE);
 
index b1c3aed..7c27f5d 100644 (file)
@@ -985,18 +985,21 @@ static int mjpeg_decode_scan(MJpegDecodeContext *s, int nb_components, int Ah, i
                 }
             }
 
-            if (s->restart_interval) --s->restart_count;
-            i= 8+((-get_bits_count(&s->gb))&7);
-            if (s->restart_interval && show_bits(&s->gb, i)  == (1<<i)-1){ /* skip RSTn */
-                int pos= get_bits_count(&s->gb);
-                align_get_bits(&s->gb);
-                while(get_bits_count(&s->gb) < s->gb.size_in_bits && show_bits(&s->gb, 8) == 0xFF)
-                    skip_bits(&s->gb, 8);
-                if(get_bits_count(&s->gb) < s->gb.size_in_bits && (get_bits(&s->gb, 8)&0xF8) == 0xD0){
-                    for (i=0; i<nb_components; i++) /* reset dc */
-                        s->last_dc[i] = 1024;
-                }else{
-                    skip_bits_long(&s->gb, pos - get_bits_count(&s->gb));
+            if (s->restart_interval) {
+                s->restart_count--;
+                i = 8 + ((-get_bits_count(&s->gb)) & 7);
+                /* skip RSTn */
+                if (show_bits(&s->gb, i) == (1 << i) - 1) {
+                    int pos = get_bits_count(&s->gb);
+                    align_get_bits(&s->gb);
+                    while (get_bits_left(&s->gb) >= 8 && show_bits(&s->gb, 8) == 0xFF)
+                        skip_bits(&s->gb, 8);
+                    if (get_bits_left(&s->gb) >= 8 && (get_bits(&s->gb, 8) & 0xF8) == 0xD0) {
+                        for (i = 0; i < nb_components; i++) /* reset dc */
+                            s->last_dc[i] = 1024;
+                    } else {
+                        skip_bits_long(&s->gb, pos - get_bits_count(&s->gb));
+                    }
                 }
             }
         }
index 95487d9..5673834 100644 (file)
@@ -272,6 +272,8 @@ static int tm2_read_stream(TM2Context *ctx, const uint8_t *buf, int stream_id, i
             len = AV_RB32(buf); buf += 4; cur += 4;
         }
         if(len > 0) {
+            if (skip <= cur)
+                return -1;
             init_get_bits(&ctx->gb, buf, (skip - cur) * 8);
             if(tm2_read_deltas(ctx, stream_id) == -1)
                 return -1;
@@ -286,7 +288,7 @@ static int tm2_read_stream(TM2Context *ctx, const uint8_t *buf, int stream_id, i
     buf += 4; cur += 4;
     buf += 4; cur += 4; /* unused by decoder */
 
-    if(skip < cur)
+    if (skip <= cur)
         return -1;
     init_get_bits(&ctx->gb, buf, (skip - cur) * 8);
     if(tm2_build_huff_table(ctx, &codes) == -1)
@@ -305,6 +307,8 @@ static int tm2_read_stream(TM2Context *ctx, const uint8_t *buf, int stream_id, i
     ctx->tok_lens[stream_id] = toks;
     len = AV_RB32(buf); buf += 4; cur += 4;
     if(len > 0) {
+        if (skip <= cur)
+            return -1;
         init_get_bits(&ctx->gb, buf, (skip - cur) * 8);
         for(i = 0; i < toks; i++) {
             if (get_bits_left(&ctx->gb) <= 0) {
index 80e7130..738ae9f 100644 (file)
@@ -1378,6 +1378,8 @@ static inline int vp3_dequant(Vp3DecodeContext *s, Vp3Fragment *frag,
             return i;
         }
     } while (i < 64);
+    // return value is expected to be a valid level
+    i--;
 end:
     // the actual DC+prediction is in the fragment structure
     block[0] = frag->dc * s->qmat[0][inter][plane][0];
index 67005e3..418a8a7 100644 (file)
@@ -127,7 +127,7 @@ static int url_alloc_for_protocol (URLContext **puc, struct URLProtocol *up,
     int err;
 
 #if CONFIG_NETWORK
-    if (!ff_network_init())
+    if (up->flags & URL_PROTOCOL_FLAG_NETWORK && !ff_network_init())
         return AVERROR(EIO);
 #endif
     uc = av_mallocz(sizeof(URLContext) + strlen(filename) + 1);
@@ -181,7 +181,8 @@ static int url_alloc_for_protocol (URLContext **puc, struct URLProtocol *up,
  fail:
     *puc = NULL;
 #if CONFIG_NETWORK
-    ff_network_close();
+    if (up->flags & URL_PROTOCOL_FLAG_NETWORK)
+        ff_network_close();
 #endif
     return err;
 }
@@ -409,7 +410,8 @@ int ffurl_close(URLContext *h)
     if (h->is_connected && h->prot->url_close)
         ret = h->prot->url_close(h);
 #if CONFIG_NETWORK
-    ff_network_close();
+    if (h->prot->flags & URL_PROTOCOL_FLAG_NETWORK)
+        ff_network_close();
 #endif
     if (h->prot->priv_data_size) {
         if (h->prot->priv_data_class)
index 1621681..9570f00 100644 (file)
@@ -152,6 +152,7 @@ typedef struct URLContext {
 } URLContext;
 
 #define URL_PROTOCOL_FLAG_NESTED_SCHEME 1 /*< The protocol name can be the first part of a nested protocol scheme */
+#define URL_PROTOCOL_FLAG_NETWORK       2 /*< The protocol uses network */
 
 /**
  * @deprecated This struct is to be made private. Use the higher-level
index e1acf50..9dc155a 100644 (file)
@@ -121,4 +121,5 @@ URLProtocol ff_gopher_protocol = {
     .url_write      = gopher_write,
     .url_close      = gopher_close,
     .priv_data_size = sizeof(GopherContext),
+    .flags          = URL_PROTOCOL_FLAG_NETWORK,
 };
index 5d19c6e..8922a74 100644 (file)
@@ -569,6 +569,7 @@ URLProtocol ff_http_protocol = {
     .url_get_file_handle = http_get_file_handle,
     .priv_data_size      = sizeof(HTTPContext),
     .priv_data_class     = &http_context_class,
+    .flags               = URL_PROTOCOL_FLAG_NETWORK,
 };
 #endif
 #if CONFIG_HTTPS_PROTOCOL
@@ -582,6 +583,7 @@ URLProtocol ff_https_protocol = {
     .url_get_file_handle = http_get_file_handle,
     .priv_data_size      = sizeof(HTTPContext),
     .priv_data_class     = &https_context_class,
+    .flags               = URL_PROTOCOL_FLAG_NETWORK,
 };
 #endif
 
@@ -697,5 +699,6 @@ URLProtocol ff_httpproxy_protocol = {
     .url_close           = http_proxy_close,
     .url_get_file_handle = http_get_file_handle,
     .priv_data_size      = sizeof(HTTPContext),
+    .flags               = URL_PROTOCOL_FLAG_NETWORK,
 };
 #endif
index bb42a12..6ebafb6 100644 (file)
@@ -116,6 +116,11 @@ static int load_ipmovie_packet(IPMVEContext *s, AVIOContext *pb,
     int chunk_type;
 
     if (s->audio_chunk_offset && s->audio_channels && s->audio_bits) {
+        if (s->audio_type == CODEC_ID_NONE) {
+            av_log(NULL, AV_LOG_ERROR, "Can not read audio packet before"
+                   "audio codec is known\n");
+                return CHUNK_BAD;
+        }
 
         /* adjust for PCM audio by skipping chunk header */
         if (s->audio_type != CODEC_ID_INTERPLAY_DPCM) {
index 018ea0f..e433860 100644 (file)
@@ -162,6 +162,7 @@ URLProtocol ff_rtmp_protocol = {
     .url_read_seek       = rtmp_read_seek,
     .url_get_file_handle = rtmp_get_file_handle,
     .priv_data_size      = sizeof(RTMP),
+    .flags               = URL_PROTOCOL_FLAG_NETWORK,
 };
 
 URLProtocol ff_rtmpt_protocol = {
@@ -174,6 +175,7 @@ URLProtocol ff_rtmpt_protocol = {
     .url_read_seek       = rtmp_read_seek,
     .url_get_file_handle = rtmp_get_file_handle,
     .priv_data_size      = sizeof(RTMP),
+    .flags               = URL_PROTOCOL_FLAG_NETWORK,
 };
 
 URLProtocol ff_rtmpe_protocol = {
@@ -186,6 +188,7 @@ URLProtocol ff_rtmpe_protocol = {
     .url_read_seek       = rtmp_read_seek,
     .url_get_file_handle = rtmp_get_file_handle,
     .priv_data_size      = sizeof(RTMP),
+    .flags               = URL_PROTOCOL_FLAG_NETWORK,
 };
 
 URLProtocol ff_rtmpte_protocol = {
@@ -198,6 +201,7 @@ URLProtocol ff_rtmpte_protocol = {
     .url_read_seek       = rtmp_read_seek,
     .url_get_file_handle = rtmp_get_file_handle,
     .priv_data_size      = sizeof(RTMP),
+    .flags               = URL_PROTOCOL_FLAG_NETWORK,
 };
 
 URLProtocol ff_rtmps_protocol = {
@@ -210,4 +214,5 @@ URLProtocol ff_rtmps_protocol = {
     .url_read_seek       = rtmp_read_seek,
     .url_get_file_handle = rtmp_get_file_handle,
     .priv_data_size      = sizeof(RTMP),
+    .flags               = URL_PROTOCOL_FLAG_NETWORK,
 };
index e92b74f..d6e3982 100644 (file)
@@ -406,4 +406,5 @@ URLProtocol ff_mmsh_protocol = {
     .url_close      = mmsh_close,
     .url_read_seek  = mmsh_read_seek,
     .priv_data_size = sizeof(MMSHContext),
+    .flags          = URL_PROTOCOL_FLAG_NETWORK,
 };
index 8d6f8a3..e3515b6 100644 (file)
@@ -625,4 +625,5 @@ URLProtocol ff_mmst_protocol = {
     .url_read       = mms_read,
     .url_close      = mms_close,
     .priv_data_size = sizeof(MMSTContext),
+    .flags          = URL_PROTOCOL_FLAG_NETWORK,
 };
index 6698b6a..05521fd 100644 (file)
@@ -576,7 +576,8 @@ static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom)
 {
     AVStream *st;
     uint8_t version;
-    uint32_t flags, layout_tag, bitmap, num_descr;
+    uint32_t flags, layout_tag, bitmap, num_descr, label_mask;
+    int i;
 
     if (c->fc->nb_streams < 1)
         return 0;
@@ -598,9 +599,7 @@ static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom)
     av_dlog(c->fc, "chan: size=%" PRId64 " version=%u flags=%u layout=%u bitmap=%u num_descr=%u\n",
             atom.size, version, flags, layout_tag, bitmap, num_descr);
 
-#if 0
-    /* TODO: use the channel descriptions if the layout tag is 0 */
-    int i;
+    label_mask = 0;
     for (i = 0; i < num_descr; i++) {
         uint32_t label, cflags;
         float coords[3];
@@ -609,10 +608,19 @@ static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom)
         AV_WN32(&coords[0], avio_rl32(pb)); // mCoordinates[0]
         AV_WN32(&coords[1], avio_rl32(pb)); // mCoordinates[1]
         AV_WN32(&coords[2], avio_rl32(pb)); // mCoordinates[2]
+        if (layout_tag == 0) {
+            uint32_t mask_incr = ff_mov_get_channel_label(label);
+            if (mask_incr == 0) {
+                label_mask = 0;
+                break;
+            }
+            label_mask |= mask_incr;
+        }
     }
-#endif
-
-    st->codec->channel_layout = ff_mov_get_channel_layout(layout_tag, bitmap);
+    if (layout_tag == 0)
+        st->codec->channel_layout = label_mask;
+    else
+        st->codec->channel_layout = ff_mov_get_channel_layout(layout_tag, bitmap);
 
     return 0;
 }
index a8e6b94..5728ebd 100644 (file)
@@ -428,8 +428,7 @@ uint64_t ff_mov_get_channel_layout(uint32_t tag, uint32_t bitmap)
     int i, channels;
     const struct MovChannelLayoutMap *layout_map;
 
-    /* handle the use of the channel descriptions */
-    /* TODO: map MOV channel labels to FFmpeg channels */
+    /* use ff_mov_get_channel_label() to build a layout instead */
     if (tag == MOV_CH_LAYOUT_USE_DESCRIPTIONS)
         return 0;
 
@@ -451,6 +450,19 @@ uint64_t ff_mov_get_channel_layout(uint32_t tag, uint32_t bitmap)
     return layout_map[i].layout;
 }
 
+uint32_t ff_mov_get_channel_label(uint32_t label)
+{
+    if (label == 0)
+        return 0;
+    if (label <= 18)
+        return 1U << (label - 1);
+    if (label == 38)
+        return AV_CH_STEREO_LEFT;
+    if (label == 39)
+        return AV_CH_STEREO_RIGHT;
+    return 0;
+}
+
 uint32_t ff_mov_get_channel_layout_tag(enum CodecID codec_id,
                                        uint64_t channel_layout,
                                        uint32_t *bitmap)
index 9723340..abb6916 100644 (file)
 uint64_t ff_mov_get_channel_layout(uint32_t tag, uint32_t bitmap);
 
 /**
+ * Get the channel layout for the specified channel layout tag.
+ *
+ * @param[in]  tag     channel label
+ * @return             channel layout mask fragment
+ */
+uint32_t ff_mov_get_channel_label(uint32_t label);
+
+/**
  * Get the channel layout tag for the specified codec id and channel layout.
  * If the layout tag was not found, use a channel bitmap if possible.
  *
index 4fe1d33..a2c7b5d 100644 (file)
@@ -1000,4 +1000,5 @@ URLProtocol ff_rtmp_protocol = {
     .url_write      = rtmp_write,
     .url_close      = rtmp_close,
     .priv_data_size = sizeof(RTMPContext),
+    .flags          = URL_PROTOCOL_FLAG_NETWORK,
 };
index b6f2a56..4ce1d6b 100644 (file)
@@ -331,4 +331,5 @@ URLProtocol ff_rtp_protocol = {
     .url_close           = rtp_close,
     .url_get_file_handle = rtp_get_file_handle,
     .priv_data_size      = sizeof(RTPContext),
+    .flags               = URL_PROTOCOL_FLAG_NETWORK,
 };
index 1aeceb9..4eaf0a0 100644 (file)
@@ -204,4 +204,5 @@ URLProtocol ff_tcp_protocol = {
     .url_close           = tcp_close,
     .url_get_file_handle = tcp_get_file_handle,
     .priv_data_size      = sizeof(TCPContext),
+    .flags               = URL_PROTOCOL_FLAG_NETWORK,
 };
index 26f5ee5..fb84fa8 100644 (file)
@@ -248,4 +248,5 @@ URLProtocol ff_tls_protocol = {
     .url_write      = tls_write,
     .url_close      = tls_close,
     .priv_data_size = sizeof(TLSContext),
+    .flags          = URL_PROTOCOL_FLAG_NETWORK,
 };
index 5bf7d82..cdcd136 100644 (file)
@@ -637,4 +637,5 @@ URLProtocol ff_udp_protocol = {
     .url_close           = udp_close,
     .url_get_file_handle = udp_get_file_handle,
     .priv_data_size      = sizeof(UDPContext),
+    .flags               = URL_PROTOCOL_FLAG_NETWORK,
 };
index dbcf470..3a80f21 100644 (file)
@@ -33,6 +33,7 @@
 
 #if !FF_API_OLD_AVIO
 #define URL_PROTOCOL_FLAG_NESTED_SCHEME 1 /*< The protocol name can be the first part of a nested protocol scheme */
+#define URL_PROTOCOL_FLAG_NETWORK       2 /*< The protocol uses network */
 
 extern int (*url_interrupt_cb)(void);
 
index 84dfd6a..795ecb7 100644 (file)
@@ -33,6 +33,7 @@
 #include "libavutil/pixdesc.h"
 #include "metadata.h"
 #include "id3v2.h"
+#include "libavutil/avassert.h"
 #include "libavutil/avstring.h"
 #include "libavutil/mathematics.h"
 #include "libavutil/parseutils.h"
@@ -1318,57 +1319,63 @@ static int read_frame_internal(AVFormatContext *s, AVPacket *pkt)
     return 0;
 }
 
+static int read_from_packet_buffer(AVFormatContext *s, AVPacket *pkt)
+{
+    AVPacketList *pktl = s->packet_buffer;
+    av_assert0(pktl);
+    *pkt = pktl->pkt;
+    s->packet_buffer = pktl->next;
+    av_freep(&pktl);
+    return 0;
+}
+
 int av_read_frame(AVFormatContext *s, AVPacket *pkt)
 {
-    AVPacketList *pktl;
-    int eof=0;
-    const int genpts= s->flags & AVFMT_FLAG_GENPTS;
+    const int genpts = s->flags & AVFMT_FLAG_GENPTS;
+    int          eof = 0;
+
+    if (!genpts)
+        return s->packet_buffer ? read_from_packet_buffer(s, pkt) :
+                                  read_frame_internal(s, pkt);
+
+    for (;;) {
+        int ret;
+        AVPacketList *pktl = s->packet_buffer;
 
-    for(;;){
-        pktl = s->packet_buffer;
         if (pktl) {
-            AVPacket *next_pkt= &pktl->pkt;
+            AVPacket *next_pkt = &pktl->pkt;
 
-            if(genpts && next_pkt->dts != AV_NOPTS_VALUE){
+            if (next_pkt->dts != AV_NOPTS_VALUE) {
                 int wrap_bits = s->streams[next_pkt->stream_index]->pts_wrap_bits;
-                while(pktl && next_pkt->pts == AV_NOPTS_VALUE){
-                    if(   pktl->pkt.stream_index == next_pkt->stream_index
-                       && (0 > av_compare_mod(next_pkt->dts, pktl->pkt.dts, 2LL << (wrap_bits - 1)))
-                       && av_compare_mod(pktl->pkt.pts, pktl->pkt.dts, 2LL << (wrap_bits - 1))) { //not b frame
-                        next_pkt->pts= pktl->pkt.dts;
+                while (pktl && next_pkt->pts == AV_NOPTS_VALUE) {
+                    if (pktl->pkt.stream_index == next_pkt->stream_index &&
+                        (av_compare_mod(next_pkt->dts, pktl->pkt.dts, 2LL << (wrap_bits - 1)) < 0) &&
+                         av_compare_mod(pktl->pkt.pts, pktl->pkt.dts, 2LL << (wrap_bits - 1))) { //not b frame
+                        next_pkt->pts = pktl->pkt.dts;
                     }
-                    pktl= pktl->next;
+                    pktl = pktl->next;
                 }
                 pktl = s->packet_buffer;
             }
 
-            if(   next_pkt->pts != AV_NOPTS_VALUE
-               || next_pkt->dts == AV_NOPTS_VALUE
-               || !genpts || eof){
-                /* read packet from packet buffer, if there is data */
-                *pkt = *next_pkt;
-                s->packet_buffer = pktl->next;
-                av_free(pktl);
-                return 0;
-            }
+            /* read packet from packet buffer, if there is data */
+            if (!(next_pkt->pts == AV_NOPTS_VALUE &&
+                  next_pkt->dts != AV_NOPTS_VALUE && !eof))
+                return read_from_packet_buffer(s, pkt);
         }
-        if(genpts){
-            int ret= read_frame_internal(s, pkt);
-            if(ret<0){
-                if(pktl && ret != AVERROR(EAGAIN)){
-                    eof=1;
-                    continue;
-                }else
-                    return ret;
-            }
 
-            if(av_dup_packet(add_to_pktbuf(&s->packet_buffer, pkt,
-                                           &s->packet_buffer_end)) < 0)
-                return AVERROR(ENOMEM);
-        }else{
-            assert(!s->packet_buffer);
-            return read_frame_internal(s, pkt);
+        ret = read_frame_internal(s, pkt);
+        if (ret < 0) {
+            if (pktl && ret != AVERROR(EAGAIN)) {
+                eof = 1;
+                continue;
+            } else
+                return ret;
         }
+
+        if (av_dup_packet(add_to_pktbuf(&s->packet_buffer, pkt,
+                          &s->packet_buffer_end)) < 0)
+            return AVERROR(ENOMEM);
     }
 }
 
index 63576c9..8a5caec 100644 (file)
@@ -28,6 +28,7 @@
 
 #include <stdlib.h>
 #include <stdint.h>
+
 #include "config.h"
 
 #if   ARCH_ARM
 #endif
 
 #ifdef AV_READ_TIME
-#define START_TIMER \
-uint64_t tend;\
-uint64_t tstart= AV_READ_TIME();\
+#define START_TIMER                             \
+    uint64_t tend;                              \
+    uint64_t tstart = AV_READ_TIME();           \
 
-#define STOP_TIMER(id) \
-tend= AV_READ_TIME();\
-{\
-    static uint64_t tsum=0;\
-    static int tcount=0;\
-    static int tskip_count=0;\
-    if(tcount<2 || tend - tstart < 8*tsum/tcount || tend - tstart < 2000){\
-        tsum+= tend - tstart;\
-        tcount++;\
-    }else\
-        tskip_count++;\
-    if(((tcount+tskip_count)&(tcount+tskip_count-1))==0){\
-        av_log(NULL, AV_LOG_ERROR, "%"PRIu64" decicycles in %s, %d runs, %d skips\n",\
-               tsum*10/tcount, id, tcount, tskip_count);\
-    }\
-}
+#define STOP_TIMER(id)                                                    \
+    tend = AV_READ_TIME();                                                \
+    {                                                                     \
+        static uint64_t tsum   = 0;                                       \
+        static int tcount      = 0;                                       \
+        static int tskip_count = 0;                                       \
+        if (tcount < 2                        ||                          \
+            tend - tstart < 8 * tsum / tcount ||                          \
+            tend - tstart < 2000) {                                       \
+            tsum+= tend - tstart;                                         \
+            tcount++;                                                     \
+        } else                                                            \
+            tskip_count++;                                                \
+        if (((tcount + tskip_count) & (tcount + tskip_count - 1)) == 0) { \
+            av_log(NULL, AV_LOG_ERROR,                                    \
+                   "%"PRIu64" decicycles in %s, %d runs, %d skips\n",     \
+                   tsum * 10 / tcount, id, tcount, tskip_count);          \
+        }                                                                 \
+    }
 #else
 #define START_TIMER
-#define STOP_TIMER(id) {}
+#define STOP_TIMER(id) { }
 #endif
 
 #endif /* AVUTIL_TIMER_H */
index ff0656e..dca6b07 100644 (file)
@@ -981,9 +981,17 @@ YUV2PACKED16WRAPPER(yuv2, rgb48, rgb48le, PIX_FMT_RGB48LE)
 YUV2PACKED16WRAPPER(yuv2, rgb48, bgr48be, PIX_FMT_BGR48BE)
 YUV2PACKED16WRAPPER(yuv2, rgb48, bgr48le, PIX_FMT_BGR48LE)
 
+/*
+ * Write out 2 RGB pixels in the target pixel format. This function takes a
+ * R/G/B LUT as generated by ff_yuv2rgb_c_init_tables(), which takes care of
+ * things like endianness conversion and shifting. The caller takes care of
+ * setting the correct offset in these tables from the chroma (U/V) values.
+ * This function then uses the luminance (Y1/Y2) values to write out the
+ * correct RGB values into the destination buffer.
+ */
 static av_always_inline void
 yuv2rgb_write(uint8_t *_dest, int i, unsigned Y1, unsigned Y2,
-              unsigned U, unsigned V, unsigned A1, unsigned A2,
+              unsigned A1, unsigned A2,
               const void *_r, const void *_g, const void *_b, int y,
               enum PixelFormat target, int hasAlpha)
 {
@@ -1151,7 +1159,7 @@ yuv2rgb_X_c_template(SwsContext *c, const int16_t *lumFilter,
         g = (c->table_gU[U] + c->table_gV[V]);
         b =  c->table_bU[U];
 
-        yuv2rgb_write(dest, i, Y1, Y2, U, V, hasAlpha ? A1 : 0, hasAlpha ? A2 : 0,
+        yuv2rgb_write(dest, i, Y1, Y2, hasAlpha ? A1 : 0, hasAlpha ? A2 : 0,
                       r, g, b, y, target, hasAlpha);
     }
 }
@@ -1187,7 +1195,7 @@ yuv2rgb_2_c_template(SwsContext *c, const int16_t *buf[2],
             A2 = (abuf0[i * 2 + 1] * yalpha1 + abuf1[i * 2 + 1] * yalpha) >> 19;
         }
 
-        yuv2rgb_write(dest, i, Y1, Y2, U, V, hasAlpha ? A1 : 0, hasAlpha ? A2 : 0,
+        yuv2rgb_write(dest, i, Y1, Y2, hasAlpha ? A1 : 0, hasAlpha ? A2 : 0,
                       r, g, b, y, target, hasAlpha);
     }
 }
@@ -1219,7 +1227,7 @@ yuv2rgb_1_c_template(SwsContext *c, const int16_t *buf0,
                 A2 = abuf0[i * 2 + 1] >> 7;
             }
 
-            yuv2rgb_write(dest, i, Y1, Y2, U, V, hasAlpha ? A1 : 0, hasAlpha ? A2 : 0,
+            yuv2rgb_write(dest, i, Y1, Y2, hasAlpha ? A1 : 0, hasAlpha ? A2 : 0,
                           r, g, b, y, target, hasAlpha);
         }
     } else {
@@ -1238,7 +1246,7 @@ yuv2rgb_1_c_template(SwsContext *c, const int16_t *buf0,
                 A2 = abuf0[i * 2 + 1] >> 7;
             }
 
-            yuv2rgb_write(dest, i, Y1, Y2, U, V, hasAlpha ? A1 : 0, hasAlpha ? A2 : 0,
+            yuv2rgb_write(dest, i, Y1, Y2, hasAlpha ? A1 : 0, hasAlpha ? A2 : 0,
                           r, g, b, y, target, hasAlpha);
         }
     }
index 85749f0..2d1c8fd 100644 (file)
@@ -7,6 +7,9 @@ fate-ea-vp61: CMD = framecrc -i $(SAMPLES)/ea-vp6/MovieSkirmishGondor.vp6 -t 4
 FATE_TESTS += fate-vp3
 fate-vp3: CMD = framecrc -i $(SAMPLES)/vp3/vp31.avi
 
+FATE_TESTS += fate-vp3-coeff-level64
+fate-vp3-coeff-level64: CMD = framecrc -i $(SAMPLES)/vp3/coeff_level64.mkv
+
 FATE_TESTS += fate-vp5
 fate-vp5: CMD = framecrc -i $(SAMPLES)/vp5/potter512-400-partial.avi -an
 
diff --git a/tests/ref/fate/vp3-coeff-level64 b/tests/ref/fate/vp3-coeff-level64
new file mode 100644 (file)
index 0000000..31a49aa
--- /dev/null
@@ -0,0 +1,8 @@
+0, 0, 4617600, 0x4ba6df50
+0, 6000, 4617600, 0x419fdeaf
+0, 12000, 4617600, 0xeb2edced
+0, 18000, 4617600, 0xa2bb3a1a
+0, 24000, 4617600, 0x411cfb36
+0, 30000, 4617600, 0xb2dc22ed
+0, 36000, 4617600, 0x236d23b5
+0, 42000, 4617600, 0x7fef275e