dnxhddec.c 24.6 KB
Newer Older
Baptiste Coudurier's avatar
Baptiste Coudurier committed
1 2
/*
 * VC3/DNxHD decoder.
3
 * Copyright (c) 2007 SmartJog S.A., Baptiste Coudurier <baptiste dot coudurier at smartjog dot com>
4
 * Copyright (c) 2011 MirriAd Ltd
5
 * Copyright (c) 2015 Christophe Gisquet
6 7
 *
 * 10 bit support added by MirriAd Ltd, Joseph Artsimovich <joseph@mirriad.com>
8
 * Slice multithreading and MB interlaced support added by Christophe Gisquet
Baptiste Coudurier's avatar
Baptiste Coudurier committed
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
 *
 * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

27
#include "libavutil/imgutils.h"
28
#include "libavutil/timer.h"
Baptiste Coudurier's avatar
Baptiste Coudurier committed
29
#include "avcodec.h"
30
#include "blockdsp.h"
31
#define  UNCHECKED_BITSTREAM_READER 1
32
#include "get_bits.h"
Baptiste Coudurier's avatar
Baptiste Coudurier committed
33
#include "dnxhddata.h"
34
#include "idctdsp.h"
35
#include "internal.h"
36
#include "profiles.h"
37
#include "thread.h"
Baptiste Coudurier's avatar
Baptiste Coudurier committed
38

39 40 41 42 43 44 45
typedef struct RowContext {
    DECLARE_ALIGNED(16, int16_t, blocks)[12][64];
    int luma_scale[64];
    int chroma_scale[64];
    GetBitContext gb;
    int last_dc[3];
    int last_qscale;
46
    int errors;
47 48
    /** -1:not set yet  0:off=RGB  1:on=YUV  2:variable */
    int format;
49 50
} RowContext;

51
typedef struct DNXHDContext {
Baptiste Coudurier's avatar
Baptiste Coudurier committed
52
    AVCodecContext *avctx;
53
    RowContext *rows;
54
    BlockDSPContext bdsp;
55 56
    const uint8_t* buf;
    int buf_size;
57
    int64_t cid;                        ///< compression id
Baptiste Coudurier's avatar
Baptiste Coudurier committed
58
    unsigned int width, height;
59
    enum AVPixelFormat pix_fmt;
Baptiste Coudurier's avatar
Baptiste Coudurier committed
60
    unsigned int mb_width, mb_height;
61
    uint32_t mb_scan_index[256];
62
    int data_offset;                    // End of mb_scan_index, where macroblocks start
Baptiste Coudurier's avatar
Baptiste Coudurier committed
63 64
    int cur_field;                      ///< current interlaced field
    VLC ac_vlc, dc_vlc, run_vlc;
65
    IDCTDSPContext idsp;
66
    ScanTable scantable;
Baptiste Coudurier's avatar
Baptiste Coudurier committed
67
    const CIDEntry *cid_table;
68
    int bit_depth; // 8, 10, 12 or 0 if not initialized at all.
Kostya Shishkov's avatar
Kostya Shishkov committed
69
    int is_444;
70
    int mbaff;
71
    int act;
72
    int (*decode_dct_block)(const struct DNXHDContext *ctx,
73
                            RowContext *row, int n);
Baptiste Coudurier's avatar
Baptiste Coudurier committed
74 75 76
} DNXHDContext;

#define DNXHD_VLC_BITS 9
77
#define DNXHD_DC_VLC_BITS 7
Baptiste Coudurier's avatar
Baptiste Coudurier committed
78

79
static int dnxhd_decode_dct_block_8(const DNXHDContext *ctx,
80
                                    RowContext *row, int n);
81
static int dnxhd_decode_dct_block_10(const DNXHDContext *ctx,
82
                                     RowContext *row, int n);
83
static int dnxhd_decode_dct_block_10_444(const DNXHDContext *ctx,
84
                                         RowContext *row, int n);
85 86 87 88
static int dnxhd_decode_dct_block_12(const DNXHDContext *ctx,
                                     RowContext *row, int n);
static int dnxhd_decode_dct_block_12_444(const DNXHDContext *ctx,
                                         RowContext *row, int n);
89

90
static av_cold int dnxhd_decode_init(AVCodecContext *avctx)
Baptiste Coudurier's avatar
Baptiste Coudurier committed
91 92 93 94
{
    DNXHDContext *ctx = avctx->priv_data;

    ctx->avctx = avctx;
95
    ctx->cid = -1;
96
    avctx->colorspace = AVCOL_SPC_BT709;
97

98 99 100
    avctx->coded_width  = FFALIGN(avctx->width,  16);
    avctx->coded_height = FFALIGN(avctx->height, 16);

101 102 103 104
    ctx->rows = av_mallocz_array(avctx->thread_count, sizeof(RowContext));
    if (!ctx->rows)
        return AVERROR(ENOMEM);

Baptiste Coudurier's avatar
Baptiste Coudurier committed
105 106 107
    return 0;
}

108
static int dnxhd_init_vlc(DNXHDContext *ctx, uint32_t cid, int bitdepth)
Baptiste Coudurier's avatar
Baptiste Coudurier committed
109
{
110
    if (cid != ctx->cid) {
Baptiste Coudurier's avatar
Baptiste Coudurier committed
111 112
        int index;

113
        if ((index = ff_dnxhd_get_cid_table(cid)) < 0) {
Baptiste Coudurier's avatar
Baptiste Coudurier committed
114
            av_log(ctx->avctx, AV_LOG_ERROR, "unsupported cid %d\n", cid);
115
            return AVERROR(ENOSYS);
Baptiste Coudurier's avatar
Baptiste Coudurier committed
116
        }
117
        if (ff_dnxhd_cid_table[index].bit_depth != bitdepth &&
118
            ff_dnxhd_cid_table[index].bit_depth != DNXHD_VARIABLE) {
119
            av_log(ctx->avctx, AV_LOG_ERROR, "bit depth mismatches %d %d\n", ff_dnxhd_cid_table[index].bit_depth, bitdepth);
120 121
            return AVERROR_INVALIDDATA;
        }
122
        ctx->cid_table = &ff_dnxhd_cid_table[index];
123
        av_log(ctx->avctx, AV_LOG_VERBOSE, "Profile cid %d.\n", cid);
124

125 126 127
        ff_free_vlc(&ctx->ac_vlc);
        ff_free_vlc(&ctx->dc_vlc);
        ff_free_vlc(&ctx->run_vlc);
128

Baptiste Coudurier's avatar
Baptiste Coudurier committed
129
        init_vlc(&ctx->ac_vlc, DNXHD_VLC_BITS, 257,
130 131
                 ctx->cid_table->ac_bits, 1, 1,
                 ctx->cid_table->ac_codes, 2, 2, 0);
132
        init_vlc(&ctx->dc_vlc, DNXHD_DC_VLC_BITS, bitdepth > 8 ? 14 : 12,
133 134
                 ctx->cid_table->dc_bits, 1, 1,
                 ctx->cid_table->dc_codes, 1, 1, 0);
Baptiste Coudurier's avatar
Baptiste Coudurier committed
135
        init_vlc(&ctx->run_vlc, DNXHD_VLC_BITS, 62,
136 137
                 ctx->cid_table->run_bits, 1, 1,
                 ctx->cid_table->run_codes, 2, 2, 0);
Baptiste Coudurier's avatar
Baptiste Coudurier committed
138

139
        ctx->cid = cid;
Baptiste Coudurier's avatar
Baptiste Coudurier committed
140 141 142 143
    }
    return 0;
}

144 145 146 147 148 149 150 151 152 153 154 155 156 157
static av_cold int dnxhd_decode_init_thread_copy(AVCodecContext *avctx)
{
    DNXHDContext *ctx = avctx->priv_data;

    // make sure VLC tables will be loaded when cid is parsed
    ctx->cid = -1;

    ctx->rows = av_mallocz_array(avctx->thread_count, sizeof(RowContext));
    if (!ctx->rows)
        return AVERROR(ENOMEM);

    return 0;
}

158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
static int dnxhd_get_profile(int cid)
{
    switch(cid) {
    case 1270:
        return FF_PROFILE_DNXHR_444;
    case 1271:
        return FF_PROFILE_DNXHR_HQX;
    case 1272:
        return FF_PROFILE_DNXHR_HQ;
    case 1273:
        return FF_PROFILE_DNXHR_SQ;
    case 1274:
        return FF_PROFILE_DNXHR_LB;
    }
    return FF_PROFILE_DNXHD;
}

175
static int dnxhd_decode_header(DNXHDContext *ctx, AVFrame *frame,
176 177
                               const uint8_t *buf, int buf_size,
                               int first_field)
Baptiste Coudurier's avatar
Baptiste Coudurier committed
178
{
179
    int i, cid, ret;
180
    int old_bit_depth = ctx->bit_depth, bitdepth;
181
    uint64_t header_prefix;
182
    if (buf_size < 0x280) {
183 184
        av_log(ctx->avctx, AV_LOG_ERROR,
               "buffer too small (%d < 640).\n", buf_size);
185
        return AVERROR_INVALIDDATA;
186
    }
Baptiste Coudurier's avatar
Baptiste Coudurier committed
187

188
    header_prefix = ff_dnxhd_parse_header_prefix(buf);
189
    if (header_prefix == 0) {
190 191 192
        av_log(ctx->avctx, AV_LOG_ERROR,
               "unknown header 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X\n",
               buf[0], buf[1], buf[2], buf[3], buf[4]);
193
        return AVERROR_INVALIDDATA;
Baptiste Coudurier's avatar
Baptiste Coudurier committed
194
    }
195 196
    if (buf[5] & 2) { /* interlaced */
        ctx->cur_field = buf[5] & 1;
197 198
        frame->interlaced_frame = 1;
        frame->top_field_first  = first_field ^ ctx->cur_field;
199 200
        av_log(ctx->avctx, AV_LOG_DEBUG,
               "interlaced %d, cur field %d\n", buf[5] & 3, ctx->cur_field);
201 202
    } else {
        ctx->cur_field = 0;
Baptiste Coudurier's avatar
Baptiste Coudurier committed
203
    }
204
    ctx->mbaff = (buf[0x6] >> 5) & 1;
Baptiste Coudurier's avatar
Baptiste Coudurier committed
205 206 207 208

    ctx->height = AV_RB16(buf + 0x18);
    ctx->width  = AV_RB16(buf + 0x1a);

209
    switch(buf[0x21] >> 5) {
210 211 212
    case 1: bitdepth = 8; break;
    case 2: bitdepth = 10; break;
    case 3: bitdepth = 12; break;
213 214 215 216 217
    default:
        av_log(ctx->avctx, AV_LOG_ERROR,
               "Unknown bitdepth indicator (%d)\n", buf[0x21] >> 5);
        return AVERROR_INVALIDDATA;
    }
218 219

    cid = AV_RB32(buf + 0x28);
220 221 222

    ctx->avctx->profile = dnxhd_get_profile(cid);

223 224 225 226 227 228 229 230 231 232
    if ((ret = dnxhd_init_vlc(ctx, cid, bitdepth)) < 0)
        return ret;
    if (ctx->mbaff && ctx->cid_table->cid != 1260)
        av_log(ctx->avctx, AV_LOG_WARNING,
               "Adaptive MB interlace flag in an unsupported profile.\n");

    ctx->act = buf[0x2C] & 7;
    if (ctx->act && ctx->cid_table->cid != 1256 && ctx->cid_table->cid != 1270)
        av_log(ctx->avctx, AV_LOG_WARNING,
               "Adaptive color transform in an unsupported profile.\n");
233

234 235
    ctx->is_444 = (buf[0x2C] >> 6) & 1;
    if (ctx->is_444) {
236
        if (bitdepth == 8) {
237
            avpriv_request_sample(ctx->avctx, "4:4:4 8 bits");
238
            return AVERROR_INVALIDDATA;
239
        } else if (bitdepth == 10) {
240
            ctx->decode_dct_block = dnxhd_decode_dct_block_10_444;
241 242
            ctx->pix_fmt = ctx->act ? AV_PIX_FMT_YUV444P10
                                    : AV_PIX_FMT_GBRP10;
243 244
        } else {
            ctx->decode_dct_block = dnxhd_decode_dct_block_12_444;
245 246
            ctx->pix_fmt = ctx->act ? AV_PIX_FMT_YUV444P12
                                    : AV_PIX_FMT_GBRP12;
247
        }
248
    } else if (bitdepth == 12) {
249 250
        ctx->decode_dct_block = dnxhd_decode_dct_block_12;
        ctx->pix_fmt = AV_PIX_FMT_YUV422P12;
251
    } else if (bitdepth == 10) {
252 253
        ctx->decode_dct_block = dnxhd_decode_dct_block_10;
        ctx->pix_fmt = AV_PIX_FMT_YUV422P10;
254
    } else {
255 256
        ctx->decode_dct_block = dnxhd_decode_dct_block_8;
        ctx->pix_fmt = AV_PIX_FMT_YUV422P;
Baptiste Coudurier's avatar
Baptiste Coudurier committed
257
    }
258 259

    ctx->avctx->bits_per_raw_sample = ctx->bit_depth = bitdepth;
260 261 262
    if (ctx->bit_depth != old_bit_depth) {
        ff_blockdsp_init(&ctx->bdsp, ctx->avctx);
        ff_idctdsp_init(&ctx->idsp, ctx->avctx);
263 264
        ff_init_scantable(ctx->idsp.idct_permutation, &ctx->scantable,
                          ff_zigzag_direct);
265
    }
Baptiste Coudurier's avatar
Baptiste Coudurier committed
266

267 268
    // make sure profile size constraints are respected
    // DNx100 allows 1920->1440 and 1280->960 subsampling
269 270
    if (ctx->width != ctx->cid_table->width &&
        ctx->cid_table->width != DNXHD_VARIABLE) {
271 272 273 274 275 276
        av_reduce(&ctx->avctx->sample_aspect_ratio.num,
                  &ctx->avctx->sample_aspect_ratio.den,
                  ctx->width, ctx->cid_table->width, 255);
        ctx->width = ctx->cid_table->width;
    }

277
    if (buf_size < ctx->cid_table->coding_unit_size) {
278 279
        av_log(ctx->avctx, AV_LOG_ERROR, "incorrect frame size (%d < %d).\n",
               buf_size, ctx->cid_table->coding_unit_size);
280
        return AVERROR_INVALIDDATA;
Baptiste Coudurier's avatar
Baptiste Coudurier committed
281 282
    }

283
    ctx->mb_width  = (ctx->width + 15)>> 4;
Baptiste Coudurier's avatar
Baptiste Coudurier committed
284 285
    ctx->mb_height = buf[0x16d];

286
    if ((ctx->height + 15) >> 4 == ctx->mb_height && frame->interlaced_frame)
287 288
        ctx->height <<= 1;

289 290 291 292
    av_log(ctx->avctx, AV_LOG_VERBOSE, "%dx%d, 4:%s %d bits, MBAFF=%d ACT=%d\n",
           ctx->width, ctx->height, ctx->is_444 ? "4:4" : "2:2",
           ctx->bit_depth, ctx->mbaff, ctx->act);

293
    // Newer format supports variable mb_scan_index sizes
294
    if (ctx->mb_height > 68 && ff_dnxhd_check_header_prefix_hr(header_prefix)) {
295 296 297 298 299 300 301 302 303 304 305 306
        ctx->data_offset = 0x170 + (ctx->mb_height << 2);
    } else {
        if (ctx->mb_height > 68 ||
            (ctx->mb_height << frame->interlaced_frame) > (ctx->height + 15) >> 4) {
            av_log(ctx->avctx, AV_LOG_ERROR,
                   "mb height too big: %d\n", ctx->mb_height);
            return AVERROR_INVALIDDATA;
        }
        ctx->data_offset = 0x280;
    }

    if (buf_size < ctx->data_offset) {
307
        av_log(ctx->avctx, AV_LOG_ERROR,
308
               "buffer too small (%d < %d).\n", buf_size, ctx->data_offset);
309
        return AVERROR_INVALIDDATA;
Baptiste Coudurier's avatar
Baptiste Coudurier committed
310 311
    }

312
    av_assert0((unsigned)ctx->mb_height <= FF_ARRAY_ELEMS(ctx->mb_scan_index));
313

Baptiste Coudurier's avatar
Baptiste Coudurier committed
314
    for (i = 0; i < ctx->mb_height; i++) {
315
        ctx->mb_scan_index[i] = AV_RB32(buf + 0x170 + (i << 2));
316 317
        ff_dlog(ctx->avctx, "mb scan index %d, pos %d: %u\n", i, 0x170 + (i << 2), ctx->mb_scan_index[i]);
        if (buf_size - ctx->data_offset < ctx->mb_scan_index[i]) {
318
            av_log(ctx->avctx, AV_LOG_ERROR,
319 320
                   "invalid mb scan index (%u vs %u).\n",
                   ctx->mb_scan_index[i], buf_size - ctx->data_offset);
321
            return AVERROR_INVALIDDATA;
Baptiste Coudurier's avatar
Baptiste Coudurier committed
322 323 324 325 326 327
        }
    }

    return 0;
}

328
static av_always_inline int dnxhd_decode_dct_block(const DNXHDContext *ctx,
329 330 331 332
                                                   RowContext *row,
                                                   int n,
                                                   int index_bits,
                                                   int level_bias,
333 334
                                                   int level_shift,
                                                   int dc_shift)
Baptiste Coudurier's avatar
Baptiste Coudurier committed
335
{
336
    int i, j, index1, index2, len, flags;
Baptiste Coudurier's avatar
Baptiste Coudurier committed
337
    int level, component, sign;
338
    const int *scale;
339
    const uint8_t *weight_matrix;
340
    const uint8_t *ac_info = ctx->cid_table->ac_info;
341
    int16_t *block = row->blocks[n];
342
    const int eob_index     = ctx->cid_table->eob_index;
343
    int ret = 0;
344
    OPEN_READER(bs, &row->gb);
Baptiste Coudurier's avatar
Baptiste Coudurier committed
345

346 347
    ctx->bdsp.clear_block(block);

Kostya Shishkov's avatar
Kostya Shishkov committed
348
    if (!ctx->is_444) {
349 350
        if (n & 2) {
            component     = 1 + (n & 1);
351
            scale = row->chroma_scale;
Kostya Shishkov's avatar
Kostya Shishkov committed
352 353
            weight_matrix = ctx->cid_table->chroma_weight;
        } else {
354
            component     = 0;
355
            scale = row->luma_scale;
Kostya Shishkov's avatar
Kostya Shishkov committed
356 357
            weight_matrix = ctx->cid_table->luma_weight;
        }
Baptiste Coudurier's avatar
Baptiste Coudurier committed
358
    } else {
Kostya Shishkov's avatar
Kostya Shishkov committed
359 360
        component = (n >> 1) % 3;
        if (component) {
361
            scale = row->chroma_scale;
Kostya Shishkov's avatar
Kostya Shishkov committed
362 363
            weight_matrix = ctx->cid_table->chroma_weight;
        } else {
364
            scale = row->luma_scale;
Kostya Shishkov's avatar
Kostya Shishkov committed
365 366
            weight_matrix = ctx->cid_table->luma_weight;
        }
Baptiste Coudurier's avatar
Baptiste Coudurier committed
367 368
    }

369 370
    UPDATE_CACHE(bs, &row->gb);
    GET_VLC(len, bs, &row->gb, ctx->dc_vlc.table, DNXHD_DC_VLC_BITS, 1);
371
    if (len) {
372 373
        level = GET_CACHE(bs, &row->gb);
        LAST_SKIP_BITS(bs, &row->gb, len);
374 375
        sign  = ~level >> 31;
        level = (NEG_USR32(sign ^ level, len) ^ sign) - sign;
376
        row->last_dc[component] += level * (1 << dc_shift);
377
    }
378
    block[0] = row->last_dc[component];
379

380
    i = 0;
Baptiste Coudurier's avatar
Baptiste Coudurier committed
381

382 383
    UPDATE_CACHE(bs, &row->gb);
    GET_VLC(index1, bs, &row->gb, ctx->ac_vlc.table,
384 385
            DNXHD_VLC_BITS, 2);

386
    while (index1 != eob_index) {
387 388
        level = ac_info[2*index1+0];
        flags = ac_info[2*index1+1];
Baptiste Coudurier's avatar
Baptiste Coudurier committed
389

390 391
        sign = SHOW_SBITS(bs, &row->gb, 1);
        SKIP_BITS(bs, &row->gb, 1);
392

393
        if (flags & 1) {
394 395
            level += SHOW_UBITS(bs, &row->gb, index_bits) << 7;
            SKIP_BITS(bs, &row->gb, index_bits);
Baptiste Coudurier's avatar
Baptiste Coudurier committed
396 397
        }

398
        if (flags & 2) {
399 400
            UPDATE_CACHE(bs, &row->gb);
            GET_VLC(index2, bs, &row->gb, ctx->run_vlc.table,
401
                    DNXHD_VLC_BITS, 2);
402
            i += ctx->cid_table->run[index2];
Baptiste Coudurier's avatar
Baptiste Coudurier committed
403 404
        }

405
        if (++i > 63) {
406
            av_log(ctx->avctx, AV_LOG_ERROR, "ac tex damaged %d, %d\n", n, i);
407
            ret = -1;
408
            break;
409 410
        }

411
        j     = ctx->scantable.permutated[i];
412
        level *= scale[i];
413
        level += scale[i] >> 1;
414
        if (level_bias < 32 || weight_matrix[i] != level_bias)
415
            level += level_bias; // 1<<(level_shift-1)
416 417
        level >>= level_shift;

418
        block[j] = (level ^ sign) - sign;
419

420 421
        UPDATE_CACHE(bs, &row->gb);
        GET_VLC(index1, bs, &row->gb, ctx->ac_vlc.table,
422
                DNXHD_VLC_BITS, 2);
Baptiste Coudurier's avatar
Baptiste Coudurier committed
423
    }
424

425
    CLOSE_READER(bs, &row->gb);
426
    return ret;
427 428
}

429
static int dnxhd_decode_dct_block_8(const DNXHDContext *ctx,
430
                                    RowContext *row, int n)
431
{
432
    return dnxhd_decode_dct_block(ctx, row, n, 4, 32, 6, 0);
433 434
}

435
static int dnxhd_decode_dct_block_10(const DNXHDContext *ctx,
436
                                     RowContext *row, int n)
437
{
438
    return dnxhd_decode_dct_block(ctx, row, n, 6, 8, 4, 0);
Baptiste Coudurier's avatar
Baptiste Coudurier committed
439 440
}

441
static int dnxhd_decode_dct_block_10_444(const DNXHDContext *ctx,
442
                                         RowContext *row, int n)
Kostya Shishkov's avatar
Kostya Shishkov committed
443
{
444 445 446 447 448 449 450 451 452 453 454 455 456
    return dnxhd_decode_dct_block(ctx, row, n, 6, 32, 6, 0);
}

static int dnxhd_decode_dct_block_12(const DNXHDContext *ctx,
                                     RowContext *row, int n)
{
    return dnxhd_decode_dct_block(ctx, row, n, 6, 8, 4, 2);
}

static int dnxhd_decode_dct_block_12_444(const DNXHDContext *ctx,
                                         RowContext *row, int n)
{
    return dnxhd_decode_dct_block(ctx, row, n, 6, 32, 4, 2);
Kostya Shishkov's avatar
Kostya Shishkov committed
457 458
}

459 460
static int dnxhd_decode_macroblock(const DNXHDContext *ctx, RowContext *row,
                                   AVFrame *frame, int x, int y)
Baptiste Coudurier's avatar
Baptiste Coudurier committed
461
{
462
    int shift1 = ctx->bit_depth >= 10;
463 464
    int dct_linesize_luma   = frame->linesize[0];
    int dct_linesize_chroma = frame->linesize[1];
Baptiste Coudurier's avatar
Baptiste Coudurier committed
465
    uint8_t *dest_y, *dest_u, *dest_v;
466
    int dct_y_offset, dct_x_offset;
467
    int qscale, i, act;
468
    int interlaced_mb = 0;
Baptiste Coudurier's avatar
Baptiste Coudurier committed
469

470
    if (ctx->mbaff) {
471 472
        interlaced_mb = get_bits1(&row->gb);
        qscale = get_bits(&row->gb, 10);
473
    } else {
474
        qscale = get_bits(&row->gb, 11);
475
    }
476
    act = get_bits1(&row->gb);
477
    if (act) {
478 479 480 481 482 483 484 485 486 487 488
        if (!ctx->act) {
            static int act_warned;
            if (!act_warned) {
                act_warned = 1;
                av_log(ctx->avctx, AV_LOG_ERROR,
                       "ACT flag set, in violation of frame header.\n");
            }
        } else if (row->format == -1) {
            row->format = act;
        } else if (row->format != act) {
            row->format = 2; // Variable
489 490
        }
    }
Baptiste Coudurier's avatar
Baptiste Coudurier committed
491

492
    if (qscale != row->last_qscale) {
493
        for (i = 0; i < 64; i++) {
494 495
            row->luma_scale[i]   = qscale * ctx->cid_table->luma_weight[i];
            row->chroma_scale[i] = qscale * ctx->cid_table->chroma_weight[i];
496
        }
497
        row->last_qscale = qscale;
498 499
    }

500
    for (i = 0; i < 8 + 4 * ctx->is_444; i++) {
501 502
        if (ctx->decode_dct_block(ctx, row, i) < 0)
            return AVERROR_INVALIDDATA;
Kostya Shishkov's avatar
Kostya Shishkov committed
503
    }
504

505
    if (frame->interlaced_frame) {
506 507 508 509
        dct_linesize_luma   <<= 1;
        dct_linesize_chroma <<= 1;
    }

510
    dest_y = frame->data[0] + ((y * dct_linesize_luma)   << 4) + (x << (4 + shift1));
Kostya Shishkov's avatar
Kostya Shishkov committed
511 512
    dest_u = frame->data[1] + ((y * dct_linesize_chroma) << 4) + (x << (3 + shift1 + ctx->is_444));
    dest_v = frame->data[2] + ((y * dct_linesize_chroma) << 4) + (x << (3 + shift1 + ctx->is_444));
Baptiste Coudurier's avatar
Baptiste Coudurier committed
513

514
    if (frame->interlaced_frame && ctx->cur_field) {
515 516 517
        dest_y += frame->linesize[0];
        dest_u += frame->linesize[1];
        dest_v += frame->linesize[2];
518
    }
519 520 521 522
    if (interlaced_mb) {
        dct_linesize_luma   <<= 1;
        dct_linesize_chroma <<= 1;
    }
523

524
    dct_y_offset = interlaced_mb ? frame->linesize[0] : (dct_linesize_luma << 3);
525
    dct_x_offset = 8 << shift1;
Kostya Shishkov's avatar
Kostya Shishkov committed
526
    if (!ctx->is_444) {
527 528 529 530
        ctx->idsp.idct_put(dest_y,                               dct_linesize_luma, row->blocks[0]);
        ctx->idsp.idct_put(dest_y + dct_x_offset,                dct_linesize_luma, row->blocks[1]);
        ctx->idsp.idct_put(dest_y + dct_y_offset,                dct_linesize_luma, row->blocks[4]);
        ctx->idsp.idct_put(dest_y + dct_y_offset + dct_x_offset, dct_linesize_luma, row->blocks[5]);
Kostya Shishkov's avatar
Kostya Shishkov committed
531

532
        if (!(ctx->avctx->flags & AV_CODEC_FLAG_GRAY)) {
533
            dct_y_offset = interlaced_mb ? frame->linesize[1] : (dct_linesize_chroma << 3);
534 535 536 537
            ctx->idsp.idct_put(dest_u,                dct_linesize_chroma, row->blocks[2]);
            ctx->idsp.idct_put(dest_v,                dct_linesize_chroma, row->blocks[3]);
            ctx->idsp.idct_put(dest_u + dct_y_offset, dct_linesize_chroma, row->blocks[6]);
            ctx->idsp.idct_put(dest_v + dct_y_offset, dct_linesize_chroma, row->blocks[7]);
Kostya Shishkov's avatar
Kostya Shishkov committed
538 539
        }
    } else {
540 541 542 543
        ctx->idsp.idct_put(dest_y,                               dct_linesize_luma, row->blocks[0]);
        ctx->idsp.idct_put(dest_y + dct_x_offset,                dct_linesize_luma, row->blocks[1]);
        ctx->idsp.idct_put(dest_y + dct_y_offset,                dct_linesize_luma, row->blocks[6]);
        ctx->idsp.idct_put(dest_y + dct_y_offset + dct_x_offset, dct_linesize_luma, row->blocks[7]);
Kostya Shishkov's avatar
Kostya Shishkov committed
544

545
        if (!(ctx->avctx->flags & AV_CODEC_FLAG_GRAY)) {
546
            dct_y_offset = interlaced_mb ? frame->linesize[1] : (dct_linesize_chroma << 3);
547 548 549 550 551 552 553 554
            ctx->idsp.idct_put(dest_u,                               dct_linesize_chroma, row->blocks[2]);
            ctx->idsp.idct_put(dest_u + dct_x_offset,                dct_linesize_chroma, row->blocks[3]);
            ctx->idsp.idct_put(dest_u + dct_y_offset,                dct_linesize_chroma, row->blocks[8]);
            ctx->idsp.idct_put(dest_u + dct_y_offset + dct_x_offset, dct_linesize_chroma, row->blocks[9]);
            ctx->idsp.idct_put(dest_v,                               dct_linesize_chroma, row->blocks[4]);
            ctx->idsp.idct_put(dest_v + dct_x_offset,                dct_linesize_chroma, row->blocks[5]);
            ctx->idsp.idct_put(dest_v + dct_y_offset,                dct_linesize_chroma, row->blocks[10]);
            ctx->idsp.idct_put(dest_v + dct_y_offset + dct_x_offset, dct_linesize_chroma, row->blocks[11]);
Kostya Shishkov's avatar
Kostya Shishkov committed
555
        }
Baptiste Coudurier's avatar
Baptiste Coudurier committed
556 557 558 559 560
    }

    return 0;
}

561 562
static int dnxhd_decode_row(AVCodecContext *avctx, void *data,
                            int rownb, int threadnb)
Baptiste Coudurier's avatar
Baptiste Coudurier committed
563
{
564 565 566 567 568 569 570 571 572 573 574
    const DNXHDContext *ctx = avctx->priv_data;
    uint32_t offset = ctx->mb_scan_index[rownb];
    RowContext *row = ctx->rows + threadnb;
    int x;

    row->last_dc[0] =
    row->last_dc[1] =
    row->last_dc[2] = 1 << (ctx->bit_depth + 2); // for levels +2^(bitdepth-1)
    init_get_bits(&row->gb, ctx->buf + offset, (ctx->buf_size - offset) << 3);
    for (x = 0; x < ctx->mb_width; x++) {
        //START_TIMER;
575 576 577 578 579
        int ret = dnxhd_decode_macroblock(ctx, row, data, x, rownb);
        if (ret < 0) {
            row->errors++;
            return ret;
        }
580
        //STOP_TIMER("decode macroblock");
Baptiste Coudurier's avatar
Baptiste Coudurier committed
581
    }
582

Baptiste Coudurier's avatar
Baptiste Coudurier committed
583 584 585
    return 0;
}

586 587
static int dnxhd_decode_frame(AVCodecContext *avctx, void *data,
                              int *got_frame, AVPacket *avpkt)
Baptiste Coudurier's avatar
Baptiste Coudurier committed
588
{
589 590
    const uint8_t *buf = avpkt->data;
    int buf_size = avpkt->size;
Baptiste Coudurier's avatar
Baptiste Coudurier committed
591
    DNXHDContext *ctx = avctx->priv_data;
592
    ThreadFrame frame = { .f = data };
Baptiste Coudurier's avatar
Baptiste Coudurier committed
593
    AVFrame *picture = data;
594
    int first_field = 1;
595
    int ret, i;
Baptiste Coudurier's avatar
Baptiste Coudurier committed
596

597
    ff_dlog(avctx, "frame size %d\n", buf_size);
Baptiste Coudurier's avatar
Baptiste Coudurier committed
598

599 600 601
    for (i = 0; i < avctx->thread_count; i++)
        ctx->rows[i].format = -1;

602
decode_coding_unit:
603 604
    if ((ret = dnxhd_decode_header(ctx, picture, buf, buf_size, first_field)) < 0)
        return ret;
Baptiste Coudurier's avatar
Baptiste Coudurier committed
605

606 607 608 609 610 611
    if ((avctx->width || avctx->height) &&
        (ctx->width != avctx->width || ctx->height != avctx->height)) {
        av_log(avctx, AV_LOG_WARNING, "frame size changed: %dx%d -> %dx%d\n",
               avctx->width, avctx->height, ctx->width, ctx->height);
        first_field = 1;
    }
612 613 614 615 616
    if (avctx->pix_fmt != AV_PIX_FMT_NONE && avctx->pix_fmt != ctx->pix_fmt) {
        av_log(avctx, AV_LOG_WARNING, "pix_fmt changed: %s -> %s\n",
               av_get_pix_fmt_name(avctx->pix_fmt), av_get_pix_fmt_name(ctx->pix_fmt));
        first_field = 1;
    }
617

618
    avctx->pix_fmt = ctx->pix_fmt;
619 620 621
    ret = ff_set_dimensions(avctx, ctx->width, ctx->height);
    if (ret < 0)
        return ret;
Baptiste Coudurier's avatar
Baptiste Coudurier committed
622

623
    if (first_field) {
624
        if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
625
            return ret;
626 627
        picture->pict_type = AV_PICTURE_TYPE_I;
        picture->key_frame = 1;
628
    }
Baptiste Coudurier's avatar
Baptiste Coudurier committed
629

630 631
    ctx->buf_size = buf_size - ctx->data_offset;
    ctx->buf = buf + ctx->data_offset;
632
    avctx->execute2(avctx, dnxhd_decode_row, picture, NULL, ctx->mb_height);
Baptiste Coudurier's avatar
Baptiste Coudurier committed
633

634
    if (first_field && picture->interlaced_frame) {
635 636 637 638 639 640
        buf      += ctx->cid_table->coding_unit_size;
        buf_size -= ctx->cid_table->coding_unit_size;
        first_field = 0;
        goto decode_coding_unit;
    }

641 642 643 644 645 646
    ret = 0;
    for (i = 0; i < avctx->thread_count; i++) {
        ret += ctx->rows[i].errors;
        ctx->rows[i].errors = 0;
    }

647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676
    if (ctx->act) {
        static int act_warned;
        int format = ctx->rows[0].format;
        for (i = 1; i < avctx->thread_count; i++) {
            if (ctx->rows[i].format != format &&
                ctx->rows[i].format != -1 /* not run */) {
                format = 2;
                break;
            }
        }
        switch (format) {
        case -1:
        case 2:
            if (!act_warned) {
                act_warned = 1;
                av_log(ctx->avctx, AV_LOG_ERROR,
                       "Unsupported: variable ACT flag.\n");
            }
            break;
        case 0:
            ctx->pix_fmt = ctx->bit_depth==10
                         ? AV_PIX_FMT_GBRP10 : AV_PIX_FMT_GBRP12;
            break;
        case 1:
            ctx->pix_fmt = ctx->bit_depth==10
                         ? AV_PIX_FMT_YUV444P10 : AV_PIX_FMT_YUV444P12;
            break;
        }
    }
    avctx->pix_fmt = ctx->pix_fmt;
677 678 679 680 681
    if (ret) {
        av_log(ctx->avctx, AV_LOG_ERROR, "%d lines with errors\n", ret);
        return AVERROR_INVALIDDATA;
    }

682
    *got_frame = 1;
683
    return avpkt->size;
Baptiste Coudurier's avatar
Baptiste Coudurier committed
684 685
}

686
static av_cold int dnxhd_decode_close(AVCodecContext *avctx)
Baptiste Coudurier's avatar
Baptiste Coudurier committed
687 688 689
{
    DNXHDContext *ctx = avctx->priv_data;

690 691 692
    ff_free_vlc(&ctx->ac_vlc);
    ff_free_vlc(&ctx->dc_vlc);
    ff_free_vlc(&ctx->run_vlc);
693 694 695

    av_freep(&ctx->rows);

Baptiste Coudurier's avatar
Baptiste Coudurier committed
696 697 698
    return 0;
}

699
AVCodec ff_dnxhd_decoder = {
700
    .name           = "dnxhd",
701
    .long_name      = NULL_IF_CONFIG_SMALL("VC3/DNxHD"),
702
    .type           = AVMEDIA_TYPE_VIDEO,
703
    .id             = AV_CODEC_ID_DNXHD,
704 705 706 707
    .priv_data_size = sizeof(DNXHDContext),
    .init           = dnxhd_decode_init,
    .close          = dnxhd_decode_close,
    .decode         = dnxhd_decode_frame,
708 709 710
    .capabilities   = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS |
                      AV_CODEC_CAP_SLICE_THREADS,
    .init_thread_copy = ONLY_IF_THREADS_ENABLED(dnxhd_decode_init_thread_copy),
711
    .profiles       = NULL_IF_CONFIG_SMALL(ff_dnxhd_profiles),
Baptiste Coudurier's avatar
Baptiste Coudurier committed
712
};