Merge remote-tracking branch 'qatar/master'
authorMichael Niedermayer <michaelni@gmx.at>
Thu, 15 Mar 2012 00:21:16 +0000 (01:21 +0100)
committerMichael Niedermayer <michaelni@gmx.at>
Thu, 15 Mar 2012 00:27:10 +0000 (01:27 +0100)
* qatar/master:
  h264: stricter reference limit enforcement.
  h264: increase reference poc list from 16 to 32.
  xa_adpcm: limit filter to prevent xa_adpcm_table[] array bounds overruns.
  snow: check reference frame indices.
  snow: reject unsupported chroma shifts.
  Add ffvhuff encoding and decoding regression test
  anm: convert to bytestream2 API
  bytestream: add more unchecked variants for bytestream2 API
  jvdec: unbreak video decoding
  jv demux: set video stream duration
  fate: add pam image regression test

Conflicts:
libavcodec/adpcm.c
libavcodec/anm.c
libavcodec/h264.c
libavcodec/mpegvideo.h
libavcodec/snowdec.c

Merged-by: Michael Niedermayer <michaelni@gmx.at>
12 files changed:
libavcodec/adpcm.c
libavcodec/anm.c
libavcodec/bytestream.h
libavcodec/h264.c
libavcodec/jvdec.c
libavcodec/snowdec.c
libavformat/jvdec.c
tests/codec-regression.sh
tests/lavf-regression.sh
tests/ref/lavf/pam [new file with mode: 0644]
tests/ref/vsynth1/ffvhuff [new file with mode: 0644]
tests/ref/vsynth2/ffvhuff [new file with mode: 0644]

index 559eb29..dec23a3 100644 (file)
@@ -265,8 +265,9 @@ static inline short adpcm_yamaha_expand_nibble(ADPCMChannelStatus *c, unsigned c
     return c->predictor;
 }
 
-static void xa_decode(short *out, const unsigned char *in,
-    ADPCMChannelStatus *left, ADPCMChannelStatus *right, int inc)
+static int xa_decode(AVCodecContext *avctx,
+                     short *out, const unsigned char *in,
+                     ADPCMChannelStatus *left, ADPCMChannelStatus *right, int inc)
 {
     int i, j;
     int shift,filter,f0,f1;
@@ -278,7 +279,7 @@ static void xa_decode(short *out, const unsigned char *in,
         shift  = 12 - (in[4+i*2] & 15);
         filter = in[4+i*2] >> 4;
         if (filter >= FF_ARRAY_ELEMS(xa_adpcm_table)) {
-            av_log_ask_for_sample(NULL, "unknown filter %d\n", filter);
+            av_log_ask_for_sample(avctx, "unknown XA-ADPCM filter %d\n", filter);
             filter=0;
         }
         f0 = xa_adpcm_table[filter][0];
@@ -309,7 +310,7 @@ static void xa_decode(short *out, const unsigned char *in,
         shift  = 12 - (in[5+i*2] & 15);
         filter = in[5+i*2] >> 4;
         if (filter >= FF_ARRAY_ELEMS(xa_adpcm_table)) {
-            av_log_ask_for_sample(NULL, "unknown filter %d\n", filter);
+            av_log_ask_for_sample(avctx, "unknown XA-ADPCM filter %d\n", filter);
             filter=0;
         }
 
@@ -336,6 +337,8 @@ static void xa_decode(short *out, const unsigned char *in,
             left->sample2 = s_2;
         }
     }
+
+    return 0;
 }
 
 /**
@@ -823,8 +826,9 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data,
         break;
     case CODEC_ID_ADPCM_XA:
         while (buf_size >= 128) {
-            xa_decode(samples, src, &c->status[0], &c->status[1],
-                avctx->channels);
+            if ((ret = xa_decode(avctx, samples, src, &c->status[0],
+                                 &c->status[1], avctx->channels)) < 0)
+                return ret;
             src += 128;
             samples += 28 * 8;
             buf_size -= 128;
index 5493be6..37cd870 100644 (file)
 typedef struct AnmContext {
     AVFrame frame;
     int palette[AVPALETTE_COUNT];
+    GetByteContext gb;
     int x;  ///< x coordinate position
 } AnmContext;
 
 static av_cold int decode_init(AVCodecContext *avctx)
 {
     AnmContext *s = avctx->priv_data;
-    const uint8_t *buf;
     int i;
 
     avctx->pix_fmt = PIX_FMT_PAL8;
 
-    if (avctx->extradata_size != 16*8 + 4*256)
-        return -1;
-
     avcodec_get_frame_defaults(&s->frame);
     s->frame.reference = 3;
+    bytestream2_init(&s->gb, avctx->extradata, avctx->extradata_size);
+    if (bytestream2_get_bytes_left(&s->gb) < 16 * 8 + 4 * 256)
+        return -1;
 
-    buf = avctx->extradata + 16*8;
+    bytestream2_skipu(&s->gb, 16 * 8);
     for (i = 0; i < 256; i++)
-        s->palette[i] = bytestream_get_le32(&buf);
+        s->palette[i] = bytestream2_get_le32u(&s->gb);
 
     return 0;
 }
@@ -57,7 +57,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
 /**
  * Perform decode operation
  * @param dst, dst_end Destination image buffer
- * @param buf, buf_end Source buffer (optional, see below)
+ * @param gb, GetByteContext (optional, see below)
  * @param pixel Fill color (optional, see below)
  * @param count Pixel count
  * @param x Pointer to x-axis counter
@@ -65,24 +65,22 @@ static av_cold int decode_init(AVCodecContext *avctx)
  * @param linesize Destination image buffer linesize
  * @return non-zero if destination buffer is exhausted
  *
- * a copy operation is achieved when 'buf' is set
- * a fill operation is acheived when 'buf' is null and pixel is >= 0
- * a skip operation is acheived when 'buf' is null and pixel is < 0
+ * a copy operation is achieved when 'gb' is set
+ * a fill operation is acheived when 'gb' is null and pixel is >= 0
+ * a skip operation is acheived when 'gb' is null and pixel is < 0
  */
 static inline int op(uint8_t **dst, const uint8_t *dst_end,
-                     const uint8_t **buf, const uint8_t *buf_end,
+                     GetByteContext *gb,
                      int pixel, int count,
                      int *x, int width, int linesize)
 {
     int remaining = width - *x;
     while(count > 0) {
         int striplen = FFMIN(count, remaining);
-        if (buf) {
-            striplen = FFMIN(striplen, buf_end - *buf);
-            if (*buf >= buf_end)
+        if (gb) {
+            if (bytestream2_get_bytes_left(gb) < striplen)
                 goto exhausted;
-            memcpy(*dst, *buf, striplen);
-            *buf += striplen;
+            bytestream2_get_bufferu(gb, *dst, striplen);
         } else if (pixel >= 0)
             memset(*dst, pixel, striplen);
         *dst      += striplen;
@@ -111,9 +109,7 @@ static int decode_frame(AVCodecContext *avctx,
                         AVPacket *avpkt)
 {
     AnmContext *s = avctx->priv_data;
-    const uint8_t *buf = avpkt->data;
     const int buf_size = avpkt->size;
-    const uint8_t *buf_end = buf + buf_size;
     uint8_t *dst, *dst_end;
     int count;
 
@@ -124,35 +120,37 @@ static int decode_frame(AVCodecContext *avctx,
     dst     = s->frame.data[0];
     dst_end = s->frame.data[0] + s->frame.linesize[0]*avctx->height;
 
-    if (buf[0] != 0x42) {
+    bytestream2_init(&s->gb, avpkt->data, buf_size);
+
+    if (bytestream2_get_byte(&s->gb) != 0x42) {
         av_log_ask_for_sample(avctx, "unknown record type\n");
         return buf_size;
     }
-    if (buf[1]) {
+    if (bytestream2_get_byte(&s->gb)) {
         av_log_ask_for_sample(avctx, "padding bytes not supported\n");
         return buf_size;
     }
-    buf += 4;
+    bytestream2_skip(&s->gb, 2);
 
     s->x = 0;
     do {
         /* if statements are ordered by probability */
-#define OP(buf, pixel, count) \
-    op(&dst, dst_end, (buf), buf_end, (pixel), (count), &s->x, avctx->width, s->frame.linesize[0])
+#define OP(gb, pixel, count) \
+    op(&dst, dst_end, (gb), (pixel), (count), &s->x, avctx->width, s->frame.linesize[0])
 
-        int type = bytestream_get_byte(&buf);
+        int type = bytestream2_get_byte(&s->gb);
         count = type & 0x7F;
         type >>= 7;
         if (count) {
-            if (OP(type ? NULL : &buf, -1, count)) break;
+            if (OP(type ? NULL : &s->gb, -1, count)) break;
         } else if (!type) {
             int pixel;
-            count = bytestream_get_byte(&buf);  /* count==0 gives nop */
-            pixel = bytestream_get_byte(&buf);
+            count = bytestream2_get_byte(&s->gb);  /* count==0 gives nop */
+            pixel = bytestream2_get_byte(&s->gb);
             if (OP(NULL, pixel, count)) break;
         } else {
             int pixel;
-            type = bytestream_get_le16(&buf);
+            type = bytestream2_get_le16(&s->gb);
             count = type & 0x3FFF;
             type >>= 14;
             if (!count) {
@@ -164,11 +162,11 @@ static int decode_frame(AVCodecContext *avctx,
                 }
                 continue;
             }
-            pixel = type == 3 ? bytestream_get_byte(&buf) : -1;
+            pixel = type == 3 ? bytestream2_get_byte(&s->gb) : -1;
             if (type == 1) count += 0x4000;
-            if (OP(type == 2 ? &buf : NULL, pixel, count)) break;
+            if (OP(type == 2 ? &s->gb : NULL, pixel, count)) break;
         }
-    } while (buf + 1 < buf_end);
+    } while (bytestream2_get_bytes_left(&s->gb) > 0);
 
     memcpy(s->frame.data[1], s->palette, AVPALETTE_SIZE);
 
index cba2dbb..2d9ca47 100644 (file)
@@ -170,6 +170,12 @@ static av_always_inline void bytestream2_skip(GetByteContext *g,
     g->buffer += FFMIN(g->buffer_end - g->buffer, size);
 }
 
+static av_always_inline void bytestream2_skipu(GetByteContext *g,
+                                               unsigned int size)
+{
+    g->buffer += size;
+}
+
 static av_always_inline void bytestream2_skip_p(PutByteContext *p,
                                                 unsigned int size)
 {
@@ -257,6 +263,15 @@ static av_always_inline unsigned int bytestream2_get_buffer(GetByteContext *g,
     return size2;
 }
 
+static av_always_inline unsigned int bytestream2_get_bufferu(GetByteContext *g,
+                                                             uint8_t *dst,
+                                                             unsigned int size)
+{
+    memcpy(dst, g->buffer, size);
+    g->buffer += size;
+    return size;
+}
+
 static av_always_inline unsigned int bytestream2_put_buffer(PutByteContext *p,
                                                             const uint8_t *src,
                                                             unsigned int size)
@@ -272,6 +287,15 @@ static av_always_inline unsigned int bytestream2_put_buffer(PutByteContext *p,
     return size2;
 }
 
+static av_always_inline unsigned int bytestream2_put_bufferu(PutByteContext *p,
+                                                             const uint8_t *src,
+                                                             unsigned int size)
+{
+    memcpy(p->buffer, src, size);
+    p->buffer += size;
+    return size;
+}
+
 static av_always_inline void bytestream2_set_buffer(PutByteContext *p,
                                                     const uint8_t c,
                                                     unsigned int size)
@@ -286,6 +310,14 @@ static av_always_inline void bytestream2_set_buffer(PutByteContext *p,
     p->buffer += size2;
 }
 
+static av_always_inline void bytestream2_set_bufferu(PutByteContext *p,
+                                                     const uint8_t c,
+                                                     unsigned int size)
+{
+    memset(p->buffer, c, size);
+    p->buffer += size;
+}
+
 static av_always_inline unsigned int bytestream2_get_eof(PutByteContext *p)
 {
     return p->eof;
index 2cb5602..6617477 100644 (file)
@@ -3034,7 +3034,8 @@ static int decode_slice_header(H264Context *h, H264Context *h0){
     h->ref_count[1]= h->pps.ref_count[1];
 
     if(h->slice_type_nos != AV_PICTURE_TYPE_I){
-        unsigned max= (16<<(s->picture_structure != PICT_FRAME))-1;
+        unsigned max= s->picture_structure == PICT_FRAME ? 15 : 31;
+
         if(h->slice_type_nos == AV_PICTURE_TYPE_B){
             h->direct_spatial_mv_pred= get_bits1(&s->gb);
         }
@@ -3044,13 +3045,14 @@ static int decode_slice_header(H264Context *h, H264Context *h0){
             h->ref_count[0]= get_ue_golomb(&s->gb) + 1;
             if(h->slice_type_nos==AV_PICTURE_TYPE_B)
                 h->ref_count[1]= get_ue_golomb(&s->gb) + 1;
-
         }
-        if(h->ref_count[0]-1 > max || h->ref_count[1]-1 > max){
+
+        if (h->ref_count[0]-1 > max || h->ref_count[1]-1 > max){
             av_log(h->s.avctx, AV_LOG_ERROR, "reference overflow\n");
-            h->ref_count[0]= h->ref_count[1]= 1;
-            return -1;
+            h->ref_count[0] = h->ref_count[1] = 1;
+            return AVERROR_INVALIDDATA;
         }
+
         if(h->slice_type_nos == AV_PICTURE_TYPE_B)
             h->list_count= 2;
         else
index aea2cc1..d371950 100644 (file)
@@ -150,7 +150,7 @@ static int decode_frame(AVCodecContext *avctx,
 
         if (video_type == 0 || video_type == 1) {
             GetBitContext gb;
-            init_get_bits(&gb, buf, FFMIN(video_size, (buf_end - buf) * 8));
+            init_get_bits(&gb, buf, 8 * FFMIN(video_size, buf_end - buf));
 
             for (j = 0; j < avctx->height; j += 8)
                 for (i = 0; i < avctx->width; i += 8)
index 537a6c6..1db4318 100644 (file)
@@ -142,6 +142,7 @@ static int decode_q_branch(SnowContext *s, int level, int x, int y){
     const BlockNode *tl    = y && x ? &s->block[index-w-1] : left;
     const BlockNode *tr    = y && trx<w && ((x&1)==0 || level==0) ? &s->block[index-w+(1<<rem_depth)] : tl; //FIXME use lt
     int s_context= 2*left->level + 2*top->level + tl->level + tr->level;
+    int res;
 
     if(s->keyframe){
         set_blocks(s, level, x, y, null_block.color[0], null_block.color[1], null_block.color[2], null_block.mx, null_block.my, null_block.ref, BLOCK_INTRA);
@@ -170,7 +171,7 @@ static int decode_q_branch(SnowContext *s, int level, int x, int y){
                 ref= get_symbol(&s->c, &s->block_state[128 + 1024 + 32*ref_context], 0);
             if (ref >= s->ref_frames) {
                 av_log(s->avctx, AV_LOG_ERROR, "Invalid ref\n");
-                return -1;
+                return AVERROR_INVALIDDATA;
             }
             pred_mv(s, &mx, &my, ref, left, top, tr);
             mx+= get_symbol(&s->c, &s->block_state[128 + 32*(mx_context + 16*!!ref)], 1);
@@ -178,14 +179,11 @@ static int decode_q_branch(SnowContext *s, int level, int x, int y){
         }
         set_blocks(s, level, x, y, l, cb, cr, mx, my, ref, type);
     }else{
-        if (decode_q_branch(s, level+1, 2*x+0, 2*y+0)<0)
-            return -1;
-        if (decode_q_branch(s, level+1, 2*x+1, 2*y+0)<0)
-            return -1;
-        if (decode_q_branch(s, level+1, 2*x+0, 2*y+1)<0)
-            return -1;
-        if (decode_q_branch(s, level+1, 2*x+1, 2*y+1)<0)
-            return -1;
+        if ((res = decode_q_branch(s, level+1, 2*x+0, 2*y+0)) < 0 ||
+            (res = decode_q_branch(s, level+1, 2*x+1, 2*y+0)) < 0 ||
+            (res = decode_q_branch(s, level+1, 2*x+0, 2*y+1)) < 0 ||
+            (res = decode_q_branch(s, level+1, 2*x+1, 2*y+1)) < 0)
+            return res;
     }
     return 0;
 }
@@ -367,11 +365,12 @@ static int decode_blocks(SnowContext *s){
     int x, y;
     int w= s->b_width;
     int h= s->b_height;
+    int res;
 
     for(y=0; y<h; y++){
         for(x=0; x<w; x++){
-            if (decode_q_branch(s, 0, x, y) < 0)
-                return -1;
+            if ((res = decode_q_branch(s, 0, x, y)) < 0)
+                return res;
         }
     }
     return 0;
@@ -385,6 +384,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac
     int bytes_read;
     AVFrame *picture = data;
     int level, orientation, plane_index;
+    int res;
 
     ff_init_range_decoder(c, buf, buf_size);
     ff_build_rac_states(c, 0.05*(1LL<<32), 256-8);
@@ -413,8 +413,8 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac
     if(avctx->debug&FF_DEBUG_PICT_INFO)
         av_log(avctx, AV_LOG_ERROR, "keyframe:%d qlog:%d\n", s->keyframe, s->qlog);
 
-    if (decode_blocks(s) < 0)
-        return -1;
+    if ((res = decode_blocks(s)) < 0)
+        return res;
 
     for(plane_index=0; plane_index<3; plane_index++){
         Plane *p= &s->plane[plane_index];
index 31cba6f..fbd4f1e 100644 (file)
@@ -79,6 +79,7 @@ static int read_header(AVFormatContext *s)
     vst->codec->codec_tag   = 0; /* no fourcc */
     vst->codec->width       = avio_rl16(pb);
     vst->codec->height      = avio_rl16(pb);
+    vst->duration           =
     vst->nb_frames          =
     ast->nb_index_entries   = avio_rl16(pb);
     avpriv_set_pts_info(vst, 64, avio_rl16(pb), 1000);
index cd6512c..714a94f 100755 (executable)
@@ -227,6 +227,11 @@ do_video_encoding ffv1.avi "-strict -2 -an -vcodec ffv1"
 do_video_decoding
 fi
 
+if [ -n "$do_ffvhuff" ] ; then
+do_video_encoding ffvhuff.avi "-an -vcodec ffvhuff"
+do_video_decoding ""
+fi
+
 if [ -n "$do_snow" ] ; then
 do_video_encoding snow.avi "-strict -2 -an -vcodec snow -qscale 2 -flags +qpel -me_method iter -dia_size 2 -cmp 12 -subcmp 12 -s 128x64"
 do_video_decoding "" "-s 352x288"
index bfca359..f0fcac3 100755 (executable)
@@ -211,6 +211,10 @@ if [ -n "$do_jpg" ] ; then
 do_image_formats jpg "-pix_fmt yuvj420p" "-f image2"
 fi
 
+if [ -n "$do_pam" ] ; then
+do_image_formats pam
+fi
+
 if [ -n "$do_pcx" ] ; then
 do_image_formats pcx
 fi
diff --git a/tests/ref/lavf/pam b/tests/ref/lavf/pam
new file mode 100644 (file)
index 0000000..972d728
--- /dev/null
@@ -0,0 +1,3 @@
+0dce5565222cf0f8b309467f279aecd2 *./tests/data/images/pam/02.pam
+./tests/data/images/pam/%02d.pam CRC=0x6da01946
+  304191 ./tests/data/images/pam/02.pam
diff --git a/tests/ref/vsynth1/ffvhuff b/tests/ref/vsynth1/ffvhuff
new file mode 100644 (file)
index 0000000..c6d7627
--- /dev/null
@@ -0,0 +1,4 @@
+0632ffae6f1e06dd299bf41a845b9099 *./tests/data/vsynth1/ffvhuff.avi
+ 5987208 ./tests/data/vsynth1/ffvhuff.avi
+c5ccac874dbf808e9088bc3107860042 *./tests/data/ffvhuff.vsynth1.out.yuv
+stddev:    0.00 PSNR:999.99 MAXDIFF:    0 bytes:  7603200/  7603200
diff --git a/tests/ref/vsynth2/ffvhuff b/tests/ref/vsynth2/ffvhuff
new file mode 100644 (file)
index 0000000..6d77e2a
--- /dev/null
@@ -0,0 +1,4 @@
+63926d8835dd5779dca0a4bc081ca8ae *./tests/data/vsynth2/ffvhuff.avi
+ 4988056 ./tests/data/vsynth2/ffvhuff.avi
+dde5895817ad9d219f79a52d0bdfb001 *./tests/data/ffvhuff.vsynth2.out.yuv
+stddev:    0.00 PSNR:999.99 MAXDIFF:    0 bytes:  7603200/  7603200