]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/mss2.c
floatdsp: move butterflies_float from dsputil to avfloatdsp.
[ffmpeg] / libavcodec / mss2.c
index e4c854a01e9ac224175c74e653030eb4da865662..9936272443d923671716a721a8f00a1e6c9fd165 100644 (file)
@@ -24,6 +24,7 @@
  */
 
 #include "libavutil/avassert.h"
+#include "internal.h"
 #include "msmpeg4data.h"
 #include "vc1.h"
 #include "mss12.h"
@@ -106,7 +107,7 @@ static int arith2_get_number(ArithCoder *c, int n)
     return val;
 }
 
-static int arith2_get_prob(ArithCoder *c, int *probs)
+static int arith2_get_prob(ArithCoder *c, int16_t *probs)
 {
     int range = c->high - c->low + 1, n = *probs;
     int scale = av_log2(range) - av_log2(n);
@@ -161,8 +162,8 @@ static int decode_pal_v2(MSS12Context *ctx, const uint8_t *buf, int buf_size)
         return 0;
 
     ncol = *buf++;
-    if (buf_size < 2 + ncol * 3)
-        return -1;
+    if (ncol > ctx->free_colours || buf_size < 2 + ncol * 3)
+        return AVERROR_INVALIDDATA;
     for (i = 0; i < ncol; i++)
         *pal++ = AV_RB24(buf + 3 * i);
 
@@ -188,7 +189,7 @@ static int decode_555(GetByteContext *gB, uint16_t *dst, int stride,
         READ_PAIR(y, endy)
 
         if (endx >= w || endy >= h || x > endx || y > endy)
-            return -1;
+            return AVERROR_INVALIDDATA;
         dst += x + stride * y;
         w    = endx - x + 1;
         h    = endy - y + 1;
@@ -335,8 +336,7 @@ static int decode_rle(GetBitContext *gb, uint8_t *pal_dst, int pal_stride,
                     else
                         repeat = get_bits(gb, b);
 
-                    while (b--)
-                        repeat += 1 << b;
+                    repeat += (1 << b) - 1;
 
                     if (last_symbol == -2) {
                         int skip = FFMIN(repeat, pal_dst + w - pp);
@@ -373,13 +373,14 @@ static int decode_wmv9(AVCodecContext *avctx, const uint8_t *buf, int buf_size,
     VC1Context *v     = avctx->priv_data;
     MpegEncContext *s = &v->s;
     AVFrame *f;
+    int ret;
 
     ff_mpeg_flush(avctx);
 
     if (s->current_picture_ptr == NULL || s->current_picture_ptr->f.data[0]) {
         int i = ff_find_unused_picture(s, 0);
         if (i < 0)
-            return -1;
+            return i;
         s->current_picture_ptr = &s->picture[i];
     }
 
@@ -397,12 +398,12 @@ static int decode_wmv9(AVCodecContext *avctx, const uint8_t *buf, int buf_size,
         return AVERROR_INVALIDDATA;
     }
 
-    avctx->pix_fmt = PIX_FMT_YUV420P;
+    avctx->pix_fmt = AV_PIX_FMT_YUV420P;
 
-    if (ff_MPV_frame_start(s, avctx) < 0) {
+    if ((ret = ff_MPV_frame_start(s, avctx)) < 0) {
         av_log(v->s.avctx, AV_LOG_ERROR, "ff_MPV_frame_start error\n");
-        avctx->pix_fmt = PIX_FMT_RGB24;
-        return -1;
+        avctx->pix_fmt = AV_PIX_FMT_RGB24;
+        return ret;
     }
 
     ff_er_frame_start(s);
@@ -449,7 +450,7 @@ static int decode_wmv9(AVCodecContext *avctx, const uint8_t *buf, int buf_size,
                                 f->data[1], f->data[2], f->linesize[1],
                                 w, h);
 
-    avctx->pix_fmt = PIX_FMT_RGB24;
+    avctx->pix_fmt = AV_PIX_FMT_RGB24;
 
     return 0;
 }
@@ -461,7 +462,7 @@ typedef struct Rectangle {
 #define MAX_WMV9_RECTANGLES 20
 #define ARITH2_PADDING 2
 
-static int mss2_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
+static int mss2_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                              AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
@@ -475,7 +476,7 @@ static int mss2_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
     int keyframe, has_wmv9, has_mv, is_rle, is_555, ret;
 
     Rectangle wmv9rects[MAX_WMV9_RECTANGLES], *r;
-    int used_rects = 0, i, implicit_rect, av_uninit(wmv9_mask);
+    int used_rects = 0, i, implicit_rect = 0, av_uninit(wmv9_mask);
 
     av_assert0(FF_INPUT_BUFFER_PADDING_SIZE >=
                ARITH2_PADDING + (MIN_CACHE_BITS + 7) / 8);
@@ -520,7 +521,7 @@ static int mss2_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
     if (is_555 && (has_wmv9 || has_mv || c->slice_split && ctx->split_position))
         return AVERROR_INVALIDDATA;
 
-    avctx->pix_fmt = is_555 ? PIX_FMT_RGB555 : PIX_FMT_RGB24;
+    avctx->pix_fmt = is_555 ? AV_PIX_FMT_RGB555 : AV_PIX_FMT_RGB24;
     if (ctx->pic.data[0] && ctx->pic.format != avctx->pix_fmt)
         avctx->release_buffer(avctx, &ctx->pic);
 
@@ -606,7 +607,7 @@ static int mss2_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
                                 FF_BUFFER_HINTS_PRESERVE |
                                 FF_BUFFER_HINTS_REUSABLE;
 
-        if ((ret = avctx->get_buffer(avctx, &ctx->pic)) < 0) {
+        if ((ret = ff_get_buffer(avctx, &ctx->pic)) < 0) {
             av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
             return ret;
         }
@@ -617,7 +618,7 @@ static int mss2_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
                               ctx->last_pic.linesize[0] * (avctx->height - 1);
         } else {
             av_log(avctx, AV_LOG_ERROR, "Missing keyframe\n");
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
     } else {
         if (ctx->last_pic.data[0])
@@ -651,25 +652,6 @@ static int mss2_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
             return AVERROR_INVALIDDATA;
 
         buf_size -= bytestream2_tell(&gB);
-    } else if (is_rle) {
-        init_get_bits(&gb, buf, buf_size * 8);
-        if (ret = decode_rle(&gb, c->pal_pic, c->pal_stride,
-                             c->rgb_pic, c->rgb_stride, c->pal, keyframe,
-                             ctx->split_position, 0,
-                             avctx->width, avctx->height))
-            return ret;
-        align_get_bits(&gb);
-
-        if (c->slice_split)
-            if (ret = decode_rle(&gb, c->pal_pic, c->pal_stride,
-                                 c->rgb_pic, c->rgb_stride, c->pal, keyframe,
-                                 ctx->split_position, 1,
-                                 avctx->width, avctx->height))
-                return ret;
-
-        align_get_bits(&gb);
-        buf      += get_bits_count(&gb) >> 3;
-        buf_size -= get_bits_count(&gb) >> 3;
     } else {
         if (keyframe) {
             c->corrupted = 0;
@@ -677,32 +659,54 @@ static int mss2_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
             if (c->slice_split)
                 ff_mss12_slicecontext_reset(&ctx->sc[1]);
         }
-        else if (c->corrupted)
-            return AVERROR_INVALIDDATA;
-        bytestream2_init(&gB, buf, buf_size + ARITH2_PADDING);
-        arith2_init(&acoder, &gB);
-        c->keyframe = keyframe;
-        if (c->corrupted = ff_mss12_decode_rect(&ctx->sc[0], &acoder, 0, 0,
-                                                avctx->width,
-                                                ctx->split_position))
-            return AVERROR_INVALIDDATA;
+        if (is_rle) {
+            init_get_bits(&gb, buf, buf_size * 8);
+            if (ret = decode_rle(&gb, c->pal_pic, c->pal_stride,
+                                 c->rgb_pic, c->rgb_stride, c->pal, keyframe,
+                                 ctx->split_position, 0,
+                                 avctx->width, avctx->height))
+                return ret;
+            align_get_bits(&gb);
 
-        buf      += arith2_get_consumed_bytes(&acoder);
-        buf_size -= arith2_get_consumed_bytes(&acoder);
-        if (c->slice_split) {
-            if (buf_size < 1)
+            if (c->slice_split)
+                if (ret = decode_rle(&gb, c->pal_pic, c->pal_stride,
+                                     c->rgb_pic, c->rgb_stride, c->pal, keyframe,
+                                     ctx->split_position, 1,
+                                     avctx->width, avctx->height))
+                    return ret;
+
+            align_get_bits(&gb);
+            buf      += get_bits_count(&gb) >> 3;
+            buf_size -= get_bits_count(&gb) >> 3;
+        } else if (!implicit_rect || wmv9_mask != -1) {
+            if (c->corrupted)
                 return AVERROR_INVALIDDATA;
             bytestream2_init(&gB, buf, buf_size + ARITH2_PADDING);
             arith2_init(&acoder, &gB);
-            if (c->corrupted = ff_mss12_decode_rect(&ctx->sc[1], &acoder, 0,
-                                                    ctx->split_position,
+            c->keyframe = keyframe;
+            if (c->corrupted = ff_mss12_decode_rect(&ctx->sc[0], &acoder, 0, 0,
                                                     avctx->width,
-                                                    avctx->height - ctx->split_position))
+                                                    ctx->split_position))
                 return AVERROR_INVALIDDATA;
 
             buf      += arith2_get_consumed_bytes(&acoder);
             buf_size -= arith2_get_consumed_bytes(&acoder);
-        }
+            if (c->slice_split) {
+                if (buf_size < 1)
+                    return AVERROR_INVALIDDATA;
+                bytestream2_init(&gB, buf, buf_size + ARITH2_PADDING);
+                arith2_init(&acoder, &gB);
+                if (c->corrupted = ff_mss12_decode_rect(&ctx->sc[1], &acoder, 0,
+                                                        ctx->split_position,
+                                                        avctx->width,
+                                                        avctx->height - ctx->split_position))
+                    return AVERROR_INVALIDDATA;
+
+                buf      += arith2_get_consumed_bytes(&acoder);
+                buf_size -= arith2_get_consumed_bytes(&acoder);
+            }
+        } else
+            memset(c->pal_pic, 0, c->pal_stride * avctx->height);
     }
 
     if (has_wmv9) {
@@ -741,7 +745,7 @@ static int mss2_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
     if (buf_size)
         av_log(avctx, AV_LOG_WARNING, "buffer not fully consumed\n");
 
-    *data_size       = sizeof(AVFrame);
+    *got_frame       = 1;
     *(AVFrame *)data = ctx->pic;
 
     return avpkt->size;
@@ -750,16 +754,14 @@ static int mss2_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
 static av_cold int wmv9_init(AVCodecContext *avctx)
 {
     VC1Context *v = avctx->priv_data;
+    int ret;
 
     v->s.avctx    = avctx;
     avctx->flags |= CODEC_FLAG_EMU_EDGE;
     v->s.flags   |= CODEC_FLAG_EMU_EDGE;
 
-    if (avctx->idct_algo == FF_IDCT_AUTO)
-        avctx->idct_algo = FF_IDCT_WMV2;
-
-    if (ff_vc1_init_common(v) < 0)
-        return -1;
+    if ((ret = ff_vc1_init_common(v)) < 0)
+        return ret;
     ff_vc1dsp_init(&v->vc1dsp);
 
     v->profile = PROFILE_MAIN;
@@ -799,9 +801,9 @@ static av_cold int wmv9_init(AVCodecContext *avctx)
 
     ff_vc1_init_transposed_scantables(v);
 
-    if (ff_msmpeg4_decode_init(avctx) < 0 ||
-        ff_vc1_decode_init_alloc_tables(v) < 0)
-        return -1;
+    if ((ret = ff_msmpeg4_decode_init(avctx)) < 0 ||
+        (ret = ff_vc1_decode_init_alloc_tables(v)) < 0)
+        return ret;
 
     /* error concealment */
     v->s.me.qpel_put = v->s.dsp.put_qpel_pixels_tab;
@@ -837,8 +839,8 @@ static av_cold int mss2_decode_init(AVCodecContext *avctx)
     if (ret = ff_mss12_decode_init(c, 1, &ctx->sc[0], &ctx->sc[1]))
         return ret;
     c->pal_stride   = c->mask_stride;
-    c->pal_pic      = av_malloc(c->pal_stride * avctx->height);
-    c->last_pal_pic = av_malloc(c->pal_stride * avctx->height);
+    c->pal_pic      = av_mallocz(c->pal_stride * avctx->height);
+    c->last_pal_pic = av_mallocz(c->pal_stride * avctx->height);
     if (!c->pal_pic || !c->last_pal_pic) {
         mss2_decode_end(avctx);
         return AVERROR(ENOMEM);
@@ -849,8 +851,8 @@ static av_cold int mss2_decode_init(AVCodecContext *avctx)
     }
     ff_mss2dsp_init(&ctx->dsp);
 
-    avctx->pix_fmt = c->free_colours == 127 ? PIX_FMT_RGB555
-                                            : PIX_FMT_RGB24;
+    avctx->pix_fmt = c->free_colours == 127 ? AV_PIX_FMT_RGB555
+                                            : AV_PIX_FMT_RGB24;
 
     return 0;
 }