eamad.c 11.2 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
/*
 * Electronic Arts Madcow Video Decoder
 * Copyright (c) 2007-2009 Peter Ross
 *
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * FFmpeg is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with FFmpeg; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

/**
23
 * @file
24
 * Electronic Arts Madcow Video Decoder
25
 * @author Peter Ross <pross@xvid.org>
26
 *
27
 * @see technical details at
28 29 30 31
 * http://wiki.multimedia.cx/index.php?title=Electronic_Arts_MAD
 */

#include "avcodec.h"
32
#include "bytestream.h"
33
#include "bswapdsp.h"
34 35
#include "get_bits.h"
#include "aandcttab.h"
36
#include "eaidct.h"
37
#include "idctdsp.h"
38
#include "internal.h"
39 40
#include "mpeg12.h"
#include "mpeg12data.h"
41
#include "libavutil/imgutils.h"
42 43 44 45 46 47 48

#define EA_PREAMBLE_SIZE    8
#define MADk_TAG MKTAG('M', 'A', 'D', 'k')    /* MAD i-frame */
#define MADm_TAG MKTAG('M', 'A', 'D', 'm')    /* MAD p-frame */
#define MADe_TAG MKTAG('M', 'A', 'D', 'e')    /* MAD lqp-frame */

typedef struct MadContext {
49
    AVCodecContext *avctx;
50
    BlockDSPContext bdsp;
51
    BswapDSPContext bbdsp;
52
    IDCTDSPContext idsp;
53
    AVFrame *last_frame;
54
    GetBitContext gb;
55 56
    void *bitstream_buf;
    unsigned int bitstream_buf_size;
Diego Biurrun's avatar
Diego Biurrun committed
57
    DECLARE_ALIGNED(16, int16_t, block)[64];
58 59 60 61
    ScanTable scantable;
    uint16_t quant_matrix[64];
    int mb_x;
    int mb_y;
62 63 64 65
} MadContext;

static av_cold int decode_init(AVCodecContext *avctx)
{
66
    MadContext *s = avctx->priv_data;
67
    s->avctx = avctx;
68
    avctx->pix_fmt = AV_PIX_FMT_YUV420P;
69
    ff_blockdsp_init(&s->bdsp, avctx);
70
    ff_bswapdsp_init(&s->bbdsp);
71
    ff_idctdsp_init(&s->idsp, avctx);
72
    ff_init_scantable_permutation(s->idsp.idct_permutation, FF_IDCT_PERM_NONE);
73
    ff_init_scantable(s->idsp.idct_permutation, &s->scantable, ff_zigzag_direct);
74
    ff_mpeg12_init_vlcs();
75 76 77 78 79

    s->last_frame = av_frame_alloc();
    if (!s->last_frame)
        return AVERROR(ENOMEM);

80 81 82 83 84 85 86 87 88 89 90 91
    return 0;
}

static inline void comp(unsigned char *dst, int dst_stride,
                        unsigned char *src, int src_stride, int add)
{
    int j, i;
    for (j=0; j<8; j++)
        for (i=0; i<8; i++)
            dst[j*dst_stride + i] = av_clip_uint8(src[j*src_stride + i] + add);
}

92 93
static inline void comp_block(MadContext *t, AVFrame *frame,
                              int mb_x, int mb_y,
94 95 96
                              int j, int mv_x, int mv_y, int add)
{
    if (j < 4) {
97 98
        unsigned offset = (mb_y*16 + ((j&2)<<2) + mv_y)*t->last_frame->linesize[0] + mb_x*16 + ((j&1)<<3) + mv_x;
        if (offset >= (t->avctx->height - 7) * t->last_frame->linesize[0] - 7)
99
            return;
100 101
        comp(frame->data[0] + (mb_y*16 + ((j&2)<<2))*frame->linesize[0] + mb_x*16 + ((j&1)<<3),
             frame->linesize[0],
102
             t->last_frame->data[0] + offset,
103
             t->last_frame->linesize[0], add);
104
    } else if (!(t->avctx->flags & CODEC_FLAG_GRAY)) {
105
        int index = j - 3;
106 107
        unsigned offset = (mb_y * 8 + (mv_y/2))*t->last_frame->linesize[index] + mb_x * 8 + (mv_x/2);
        if (offset >= (t->avctx->height/2 - 7) * t->last_frame->linesize[index] - 7)
108
            return;
109 110
        comp(frame->data[index] + (mb_y*8)*frame->linesize[index] + mb_x * 8,
             frame->linesize[index],
111
             t->last_frame->data[index] + offset,
112
             t->last_frame->linesize[index], add);
113 114 115
    }
}

116 117
static inline void idct_put(MadContext *t, AVFrame *frame, int16_t *block,
                            int mb_x, int mb_y, int j)
118 119
{
    if (j < 4) {
120
        ff_ea_idct_put_c(
121 122
            frame->data[0] + (mb_y*16 + ((j&2)<<2))*frame->linesize[0] + mb_x*16 + ((j&1)<<3),
            frame->linesize[0], block);
123
    } else if (!(t->avctx->flags & CODEC_FLAG_GRAY)) {
124
        int index = j - 3;
125
        ff_ea_idct_put_c(
126 127
            frame->data[index] + (mb_y*8)*frame->linesize[index] + mb_x*8,
            frame->linesize[index], block);
128 129 130
    }
}

131
static inline int decode_block_intra(MadContext *s, int16_t * block)
132 133 134
{
    int level, i, j, run;
    RLTable *rl = &ff_rl_mpeg1;
135 136
    const uint8_t *scantable = s->scantable.permutated;
    int16_t *quant_matrix = s->quant_matrix;
137 138 139 140 141

    block[0] = (128 + get_sbits(&s->gb, 8)) * quant_matrix[0];

    /* The RL decoder is derived from mpeg1_decode_block_intra;
       Escaped level and run values a decoded differently */
142
    i = 0;
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180
    {
        OPEN_READER(re, &s->gb);
        /* now quantify & encode AC coefficients */
        for (;;) {
            UPDATE_CACHE(re, &s->gb);
            GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0);

            if (level == 127) {
                break;
            } else if (level != 0) {
                i += run;
                j = scantable[i];
                level = (level*quant_matrix[j]) >> 4;
                level = (level-1)|1;
                level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
                LAST_SKIP_BITS(re, &s->gb, 1);
            } else {
                /* escape */
                UPDATE_CACHE(re, &s->gb);
                level = SHOW_SBITS(re, &s->gb, 10); SKIP_BITS(re, &s->gb, 10);

                UPDATE_CACHE(re, &s->gb);
                run = SHOW_UBITS(re, &s->gb, 6)+1; LAST_SKIP_BITS(re, &s->gb, 6);

                i += run;
                j = scantable[i];
                if (level < 0) {
                    level = -level;
                    level = (level*quant_matrix[j]) >> 4;
                    level = (level-1)|1;
                    level = -level;
                } else {
                    level = (level*quant_matrix[j]) >> 4;
                    level = (level-1)|1;
                }
            }
            if (i > 63) {
                av_log(s->avctx, AV_LOG_ERROR, "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y);
181
                return -1;
182 183 184 185 186 187
            }

            block[j] = level;
        }
        CLOSE_READER(re, &s->gb);
    }
188
    return 0;
189 190 191 192 193 194 195 196 197 198 199 200 201
}

static int decode_motion(GetBitContext *gb)
{
    int value = 0;
    if (get_bits1(gb)) {
        if (get_bits1(gb))
            value = -17;
        value += get_bits(gb, 4) + 1;
    }
    return value;
}

202
static int decode_mb(MadContext *s, AVFrame *frame, int inter)
203 204
{
    int mv_map = 0;
205
    int av_uninit(mv_x), av_uninit(mv_y);
206 207 208 209 210 211 212 213 214 215 216 217 218 219
    int j;

    if (inter) {
        int v = decode210(&s->gb);
        if (v < 2) {
            mv_map = v ? get_bits(&s->gb, 6) : 63;
            mv_x = decode_motion(&s->gb);
            mv_y = decode_motion(&s->gb);
        }
    }

    for (j=0; j<6; j++) {
        if (mv_map & (1<<j)) {  // mv_x and mv_y are guarded by mv_map
            int add = 2*decode_motion(&s->gb);
220
            if (s->last_frame->data[0])
221
                comp_block(s, frame, s->mb_x, s->mb_y, j, mv_x, mv_y, add);
222
        } else {
223
            s->bdsp.clear_block(s->block);
224
            if(decode_block_intra(s, s->block) < 0)
225
                return -1;
226
            idct_put(s, frame, s->block, s->mb_x, s->mb_y, j);
227 228
        }
    }
229
    return 0;
230 231
}

232
static void calc_quant_matrix(MadContext *s, int qscale)
233 234 235
{
    int i;

236 237 238
    s->quant_matrix[0] = (ff_inv_aanscales[0]*ff_mpeg1_default_intra_matrix[0]) >> 11;
    for (i=1; i<64; i++)
        s->quant_matrix[i] = (ff_inv_aanscales[i]*ff_mpeg1_default_intra_matrix[i]*qscale + 32) >> 10;
239 240 241
}

static int decode_frame(AVCodecContext *avctx,
242
                        void *data, int *got_frame,
243 244 245 246
                        AVPacket *avpkt)
{
    const uint8_t *buf = avpkt->data;
    int buf_size       = avpkt->size;
247
    MadContext *s     = avctx->priv_data;
248
    AVFrame *frame    = data;
249
    GetByteContext gb;
250
    int width, height;
251
    int chunk_type;
252
    int inter, ret;
253

254
    bytestream2_init(&gb, buf, buf_size);
255

256
    chunk_type = bytestream2_get_le32(&gb);
257
    inter = (chunk_type == MADm_TAG || chunk_type == MADe_TAG);
258
    bytestream2_skip(&gb, 10);
259

260
    av_reduce(&avctx->framerate.den, &avctx->framerate.num,
261 262 263 264 265 266 267
              bytestream2_get_le16(&gb), 1000, 1<<30);

    width  = bytestream2_get_le16(&gb);
    height = bytestream2_get_le16(&gb);
    bytestream2_skip(&gb, 1);
    calc_quant_matrix(s, bytestream2_get_byte(&gb));
    bytestream2_skip(&gb, 2);
268

269 270 271 272
    if (bytestream2_get_bytes_left(&gb) < 2) {
        av_log(avctx, AV_LOG_ERROR, "Input data too small\n");
        return AVERROR_INVALIDDATA;
    }
273

274 275 276 277 278
    if (width < 16 || height < 16) {
        av_log(avctx, AV_LOG_ERROR, "Dimensions too small\n");
        return AVERROR_INVALIDDATA;
    }

279
    if (avctx->width != width || avctx->height != height) {
280
        av_frame_unref(s->last_frame);
281
        if((width * height)/2048*7 > bytestream2_get_bytes_left(&gb))
282
            return AVERROR_INVALIDDATA;
283
        if ((ret = ff_set_dimensions(avctx, width, height)) < 0)
284
            return ret;
285 286
    }

287
    if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0)
288
        return ret;
289

290
    if (inter && !s->last_frame->data[0]) {
291
        av_log(avctx, AV_LOG_WARNING, "Missing reference frame.\n");
292
        ret = ff_get_buffer(avctx, s->last_frame, AV_GET_BUFFER_FLAG_REF);
293 294
        if (ret < 0)
            return ret;
295 296 297 298 299 300
        memset(s->last_frame->data[0], 0, s->last_frame->height *
               s->last_frame->linesize[0]);
        memset(s->last_frame->data[1], 0x80, s->last_frame->height / 2 *
               s->last_frame->linesize[1]);
        memset(s->last_frame->data[2], 0x80, s->last_frame->height / 2 *
               s->last_frame->linesize[2]);
301 302
    }

303
    av_fast_padded_malloc(&s->bitstream_buf, &s->bitstream_buf_size,
304
                          bytestream2_get_bytes_left(&gb));
305
    if (!s->bitstream_buf)
306
        return AVERROR(ENOMEM);
307 308
    s->bbdsp.bswap16_buf(s->bitstream_buf, (const uint16_t *)(buf + bytestream2_tell(&gb)),
                         bytestream2_get_bytes_left(&gb) / 2);
309
    memset((uint8_t*)s->bitstream_buf + bytestream2_get_bytes_left(&gb), 0, FF_INPUT_BUFFER_PADDING_SIZE);
310
    init_get_bits(&s->gb, s->bitstream_buf, 8*(bytestream2_get_bytes_left(&gb)));
311 312 313

    for (s->mb_y=0; s->mb_y < (avctx->height+15)/16; s->mb_y++)
        for (s->mb_x=0; s->mb_x < (avctx->width +15)/16; s->mb_x++)
314
            if(decode_mb(s, frame, inter) < 0)
315
                return AVERROR_INVALIDDATA;
316

317
    *got_frame = 1;
318

319
    if (chunk_type != MADe_TAG) {
320 321
        av_frame_unref(s->last_frame);
        if ((ret = av_frame_ref(s->last_frame, frame)) < 0)
322 323
            return ret;
    }
324 325 326 327 328 329 330

    return buf_size;
}

static av_cold int decode_end(AVCodecContext *avctx)
{
    MadContext *t = avctx->priv_data;
331
    av_frame_free(&t->last_frame);
332
    av_freep(&t->bitstream_buf);
333 334 335
    return 0;
}

336
AVCodec ff_eamad_decoder = {
337
    .name           = "eamad",
338
    .long_name      = NULL_IF_CONFIG_SMALL("Electronic Arts Madcow Video"),
339
    .type           = AVMEDIA_TYPE_VIDEO,
340
    .id             = AV_CODEC_ID_MAD,
341 342 343 344 345
    .priv_data_size = sizeof(MadContext),
    .init           = decode_init,
    .close          = decode_end,
    .decode         = decode_frame,
    .capabilities   = CODEC_CAP_DR1,
346
};