proresdec_lgpl.c 21.8 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 23 24 25 26 27 28 29 30
/*
 * Apple ProRes compatible decoder
 *
 * Copyright (c) 2010-2011 Maxim Poliakovski
 *
 * This file is part of Libav.
 *
 * Libav 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.
 *
 * Libav 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 Libav; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/**
 * @file
 * This is a decoder for Apple ProRes 422 SD/HQ/LT/Proxy and ProRes 4444.
 * It is used for storing and editing high definition video data in Apple's Final Cut Pro.
 *
 * @see http://wiki.multimedia.cx/index.php?title=Apple_ProRes
 */

31
#define LONG_BITSTREAM_READER // some ProRes vlc codes require up to 28 bits to be read at once
32 33 34 35 36

#include <stdint.h>

#include "libavutil/intmath.h"
#include "avcodec.h"
37
#include "internal.h"
38
#include "proresdata.h"
39
#include "proresdsp.h"
40 41
#include "get_bits.h"

42 43 44 45 46
typedef struct {
    const uint8_t *index;            ///< pointers to the data of this slice
    int slice_num;
    int x_pos, y_pos;
    int slice_width;
47
    int prev_slice_sf;               ///< scalefactor of the previous decoded slice
48
    DECLARE_ALIGNED(16, DCTELEM, blocks)[8 * 4 * 64];
49 50
    DECLARE_ALIGNED(16, int16_t, qmat_luma_scaled)[64];
    DECLARE_ALIGNED(16, int16_t, qmat_chroma_scaled)[64];
51
} ProresThreadData;
52 53

typedef struct {
54
    ProresDSPContext dsp;
55 56 57 58 59 60 61 62 63 64
    AVFrame    picture;
    ScanTable  scantable;
    int        scantable_type;           ///< -1 = uninitialized, 0 = progressive, 1/2 = interlaced

    int        frame_type;               ///< 0 = progressive, 1 = top-field first, 2 = bottom-field first
    int        pic_format;               ///< 2 = 422, 3 = 444
    uint8_t    qmat_luma[64];            ///< dequantization matrix for luma
    uint8_t    qmat_chroma[64];          ///< dequantization matrix for chroma
    int        qmat_changed;             ///< 1 - global quantization matrices changed
    int        total_slices;            ///< total number of slices in a picture
65 66
    ProresThreadData *slice_data;
    int        pic_num;
67 68 69 70 71 72 73 74 75
    int        chroma_factor;
    int        mb_chroma_factor;
    int        num_chroma_blocks;       ///< number of chrominance blocks in a macroblock
    int        num_x_slices;
    int        num_y_slices;
    int        slice_width_factor;
    int        slice_height_factor;
    int        num_x_mbs;
    int        num_y_mbs;
76
    int        alpha_info;
77 78 79 80 81 82 83 84
} ProresContext;


static av_cold int decode_init(AVCodecContext *avctx)
{
    ProresContext *ctx = avctx->priv_data;

    ctx->total_slices     = 0;
85
    ctx->slice_data       = NULL;
86

87
    avctx->bits_per_raw_sample = PRORES_BITS_PER_SAMPLE;
88
    ff_proresdsp_init(&ctx->dsp, avctx);
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110

    avctx->coded_frame = &ctx->picture;
    avcodec_get_frame_defaults(&ctx->picture);
    ctx->picture.type      = AV_PICTURE_TYPE_I;
    ctx->picture.key_frame = 1;

    ctx->scantable_type = -1;   // set scantable type to uninitialized
    memset(ctx->qmat_luma, 4, 64);
    memset(ctx->qmat_chroma, 4, 64);

    return 0;
}


static int decode_frame_header(ProresContext *ctx, const uint8_t *buf,
                               const int data_size, AVCodecContext *avctx)
{
    int hdr_size, version, width, height, flags;
    const uint8_t *ptr;

    hdr_size = AV_RB16(buf);
    if (hdr_size > data_size) {
111
        av_log(avctx, AV_LOG_ERROR, "frame data too small\n");
112
        return AVERROR_INVALIDDATA;
113 114 115 116 117 118
    }

    version = AV_RB16(buf + 2);
    if (version >= 2) {
        av_log(avctx, AV_LOG_ERROR,
               "unsupported header version: %d\n", version);
119
        return AVERROR_INVALIDDATA;
120 121 122 123 124 125
    }

    width  = AV_RB16(buf + 8);
    height = AV_RB16(buf + 10);
    if (width != avctx->width || height != avctx->height) {
        av_log(avctx, AV_LOG_ERROR,
126
               "picture dimension changed: old: %d x %d, new: %d x %d\n",
127
               avctx->width, avctx->height, width, height);
128
        return AVERROR_INVALIDDATA;
129 130 131 132 133
    }

    ctx->frame_type = (buf[12] >> 2) & 3;
    if (ctx->frame_type > 2) {
        av_log(avctx, AV_LOG_ERROR,
134
               "unsupported frame type: %d\n", ctx->frame_type);
135
        return AVERROR_INVALIDDATA;
136 137 138 139 140 141 142
    }

    ctx->chroma_factor     = (buf[12] >> 6) & 3;
    ctx->mb_chroma_factor  = ctx->chroma_factor + 2;
    ctx->num_chroma_blocks = (1 << ctx->chroma_factor) >> 1;
    switch (ctx->chroma_factor) {
    case 2:
143
        avctx->pix_fmt = AV_PIX_FMT_YUV422P10;
144 145
        break;
    case 3:
146
        avctx->pix_fmt = AV_PIX_FMT_YUV444P10;
147 148 149
        break;
    default:
        av_log(avctx, AV_LOG_ERROR,
150
               "unsupported picture format: %d\n", ctx->pic_format);
151
        return AVERROR_INVALIDDATA;
152 153 154 155 156
    }

    if (ctx->scantable_type != ctx->frame_type) {
        if (!ctx->frame_type)
            ff_init_scantable(ctx->dsp.idct_permutation, &ctx->scantable,
157
                              ff_prores_progressive_scan);
158 159
        else
            ff_init_scantable(ctx->dsp.idct_permutation, &ctx->scantable,
160
                              ff_prores_interlaced_scan);
161 162 163 164 165 166 167 168
        ctx->scantable_type = ctx->frame_type;
    }

    if (ctx->frame_type) {      /* if interlaced */
        ctx->picture.interlaced_frame = 1;
        ctx->picture.top_field_first  = ctx->frame_type & 1;
    }

169 170 171 172
    avctx->color_primaries = buf[14];
    avctx->color_trc       = buf[15];
    avctx->colorspace      = buf[16];

173 174
    ctx->alpha_info = buf[17] & 0xf;
    if (ctx->alpha_info)
175
        av_log_missing_feature(avctx, "Alpha channel", 0);
176

177 178 179 180 181
    ctx->qmat_changed = 0;
    ptr   = buf + 20;
    flags = buf[19];
    if (flags & 2) {
        if (ptr - buf > hdr_size - 64) {
182
            av_log(avctx, AV_LOG_ERROR, "header data too small\n");
183
            return AVERROR_INVALIDDATA;
184 185 186 187 188 189 190 191 192 193 194 195 196
        }
        if (memcmp(ctx->qmat_luma, ptr, 64)) {
            memcpy(ctx->qmat_luma, ptr, 64);
            ctx->qmat_changed = 1;
        }
        ptr += 64;
    } else {
        memset(ctx->qmat_luma, 4, 64);
        ctx->qmat_changed = 1;
    }

    if (flags & 1) {
        if (ptr - buf > hdr_size - 64) {
197
            av_log(avctx, AV_LOG_ERROR, "header data too small\n");
198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222
            return -1;
        }
        if (memcmp(ctx->qmat_chroma, ptr, 64)) {
            memcpy(ctx->qmat_chroma, ptr, 64);
            ctx->qmat_changed = 1;
        }
    } else {
        memset(ctx->qmat_chroma, 4, 64);
        ctx->qmat_changed = 1;
    }

    return hdr_size;
}


static int decode_picture_header(ProresContext *ctx, const uint8_t *buf,
                                 const int data_size, AVCodecContext *avctx)
{
    int   i, hdr_size, pic_data_size, num_slices;
    int   slice_width_factor, slice_height_factor;
    int   remainder, num_x_slices;
    const uint8_t *data_ptr, *index_ptr;

    hdr_size = data_size > 0 ? buf[0] >> 3 : 0;
    if (hdr_size < 8 || hdr_size > data_size) {
223
        av_log(avctx, AV_LOG_ERROR, "picture header too small\n");
224
        return AVERROR_INVALIDDATA;
225 226 227 228
    }

    pic_data_size = AV_RB32(buf + 1);
    if (pic_data_size > data_size) {
229
        av_log(avctx, AV_LOG_ERROR, "picture data too small\n");
230
        return AVERROR_INVALIDDATA;
231 232 233 234 235 236
    }

    slice_width_factor  = buf[7] >> 4;
    slice_height_factor = buf[7] & 0xF;
    if (slice_width_factor > 3 || slice_height_factor) {
        av_log(avctx, AV_LOG_ERROR,
237
               "unsupported slice dimension: %d x %d\n",
238
               1 << slice_width_factor, 1 << slice_height_factor);
239
        return AVERROR_INVALIDDATA;
240 241 242 243 244 245
    }

    ctx->slice_width_factor  = slice_width_factor;
    ctx->slice_height_factor = slice_height_factor;

    ctx->num_x_mbs = (avctx->width + 15) >> 4;
246 247 248
    ctx->num_y_mbs = (avctx->height +
                      (1 << (4 + ctx->picture.interlaced_frame)) - 1) >>
                     (4 + ctx->picture.interlaced_frame);
249 250 251 252 253 254 255

    remainder    = ctx->num_x_mbs & ((1 << slice_width_factor) - 1);
    num_x_slices = (ctx->num_x_mbs >> slice_width_factor) + (remainder & 1) +
                   ((remainder >> 1) & 1) + ((remainder >> 2) & 1);

    num_slices = num_x_slices * ctx->num_y_mbs;
    if (num_slices != AV_RB16(buf + 5)) {
256
        av_log(avctx, AV_LOG_ERROR, "invalid number of slices\n");
257
        return AVERROR_INVALIDDATA;
258 259 260
    }

    if (ctx->total_slices != num_slices) {
261 262 263
        av_freep(&ctx->slice_data);
        ctx->slice_data = av_malloc((num_slices + 1) * sizeof(ctx->slice_data[0]));
        if (!ctx->slice_data)
264 265 266 267 268
            return AVERROR(ENOMEM);
        ctx->total_slices = num_slices;
    }

    if (hdr_size + num_slices * 2 > data_size) {
269
        av_log(avctx, AV_LOG_ERROR, "slice table too small\n");
270
        return AVERROR_INVALIDDATA;
271 272 273 274 275 276 277
    }

    /* parse slice table allowing quick access to the slice data */
    index_ptr = buf + hdr_size;
    data_ptr = index_ptr + num_slices * 2;

    for (i = 0; i < num_slices; i++) {
278
        ctx->slice_data[i].index = data_ptr;
279
        ctx->slice_data[i].prev_slice_sf = 0;
280 281
        data_ptr += AV_RB16(index_ptr + i * 2);
    }
282
    ctx->slice_data[i].index = data_ptr;
283
    ctx->slice_data[i].prev_slice_sf = 0;
284 285

    if (data_ptr > buf + data_size) {
286
        av_log(avctx, AV_LOG_ERROR, "out of slice data\n");
287 288 289 290 291 292 293 294 295 296
        return -1;
    }

    return pic_data_size;
}


/**
 * Read an unsigned rice/exp golomb codeword.
 */
297
static inline int decode_vlc_codeword(GetBitContext *gb, unsigned codebook)
298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320
{
    unsigned int rice_order, exp_order, switch_bits;
    unsigned int buf, code;
    int log, prefix_len, len;

    OPEN_READER(re, gb);
    UPDATE_CACHE(re, gb);
    buf = GET_CACHE(re, gb);

    /* number of prefix bits to switch between Rice and expGolomb */
    switch_bits = (codebook & 3) + 1;
    rice_order  = codebook >> 5;        /* rice code order */
    exp_order   = (codebook >> 2) & 7;  /* exp golomb code order */

    log = 31 - av_log2(buf); /* count prefix bits (zeroes) */

    if (log < switch_bits) { /* ok, we got a rice code */
        if (!rice_order) {
            /* shortcut for faster decoding of rice codes without remainder */
            code = log;
            LAST_SKIP_BITS(re, gb, log + 1);
        } else {
            prefix_len = log + 1;
321
            code = (log << rice_order) + NEG_USR32(buf << prefix_len, rice_order);
322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355
            LAST_SKIP_BITS(re, gb, prefix_len + rice_order);
        }
    } else { /* otherwise we got a exp golomb code */
        len  = (log << 1) - switch_bits + exp_order + 1;
        code = NEG_USR32(buf, len) - (1 << exp_order) + (switch_bits << rice_order);
        LAST_SKIP_BITS(re, gb, len);
    }

    CLOSE_READER(re, gb);

    return code;
}

#define LSB2SIGN(x) (-((x) & 1))
#define TOSIGNED(x) (((x) >> 1) ^ LSB2SIGN(x))

/**
 * Decode DC coefficients for all blocks in a slice.
 */
static inline void decode_dc_coeffs(GetBitContext *gb, DCTELEM *out,
                                    int nblocks)
{
    DCTELEM prev_dc;
    int     i, sign;
    int16_t delta;
    unsigned int code;

    code   = decode_vlc_codeword(gb, FIRST_DC_CB);
    out[0] = prev_dc = TOSIGNED(code);

    out   += 64; /* move to the DC coeff of the next block */
    delta  = 3;

    for (i = 1; i < nblocks; i++, out += 64) {
356
        code = decode_vlc_codeword(gb, ff_prores_dc_codebook[FFMIN(FFABS(delta), 3)]);
357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384

        sign     = -(((delta >> 15) & 1) ^ (code & 1));
        delta    = (((code + 1) >> 1) ^ sign) - sign;
        prev_dc += delta;
        out[0]   = prev_dc;
    }
}


/**
 * Decode AC coefficients for all blocks in a slice.
 */
static inline void decode_ac_coeffs(GetBitContext *gb, DCTELEM *out,
                                    int blocks_per_slice,
                                    int plane_size_factor,
                                    const uint8_t *scan)
{
    int pos, block_mask, run, level, sign, run_cb_index, lev_cb_index;
    int max_coeffs, bits_left;

    /* set initial prediction values */
    run   = 4;
    level = 2;

    max_coeffs = blocks_per_slice << 6;
    block_mask = blocks_per_slice - 1;

    for (pos = blocks_per_slice - 1; pos < max_coeffs;) {
385 386
        run_cb_index = ff_prores_run_to_cb_index[FFMIN(run, 15)];
        lev_cb_index = ff_prores_lev_to_cb_index[FFMIN(level, 9)];
387 388

        bits_left = get_bits_left(gb);
389
        if (bits_left <= 0 || (bits_left <= 8 && !show_bits(gb, bits_left)))
390 391
            return;

392
        run = decode_vlc_codeword(gb, ff_prores_ac_codebook[run_cb_index]);
393 394

        bits_left = get_bits_left(gb);
395
        if (bits_left <= 0 || (bits_left <= 8 && !show_bits(gb, bits_left)))
396 397
            return;

398
        level = decode_vlc_codeword(gb, ff_prores_ac_codebook[lev_cb_index]) + 1;
399 400 401 402 403 404 405 406 407 408 409 410 411 412 413

        pos += run + 1;
        if (pos >= max_coeffs)
            break;

        sign = get_sbits(gb, 1);
        out[((pos & block_mask) << 6) + scan[pos >> plane_size_factor]] =
            (level ^ sign) - sign;
    }
}


/**
 * Decode a slice plane (luma or chroma).
 */
414 415
static void decode_slice_plane(ProresContext *ctx, ProresThreadData *td,
                               const uint8_t *buf,
416 417 418
                               int data_size, uint16_t *out_ptr,
                               int linesize, int mbs_per_slice,
                               int blocks_per_mb, int plane_size_factor,
419
                               const int16_t *qmat, int is_chroma)
420 421 422
{
    GetBitContext gb;
    DCTELEM *block_ptr;
423
    int mb_num, blocks_per_slice;
424 425 426

    blocks_per_slice = mbs_per_slice * blocks_per_mb;

427
    memset(td->blocks, 0, 8 * 4 * 64 * sizeof(*td->blocks));
428 429 430

    init_get_bits(&gb, buf, data_size << 3);

431
    decode_dc_coeffs(&gb, td->blocks, blocks_per_slice);
432

433
    decode_ac_coeffs(&gb, td->blocks, blocks_per_slice,
434 435 436
                     plane_size_factor, ctx->scantable.permutated);

    /* inverse quantization, inverse transform and output */
437
    block_ptr = td->blocks;
Maxim Poliakovski's avatar
Maxim Poliakovski committed
438

439 440 441
    if (!is_chroma) {
        for (mb_num = 0; mb_num < mbs_per_slice; mb_num++, out_ptr += blocks_per_mb * 4) {
            ctx->dsp.idct_put(out_ptr,                    linesize, block_ptr, qmat);
442
            block_ptr += 64;
443 444 445 446 447
            if (blocks_per_mb > 2) {
                ctx->dsp.idct_put(out_ptr + 8,            linesize, block_ptr, qmat);
                block_ptr += 64;
            }
            ctx->dsp.idct_put(out_ptr + linesize * 4,     linesize, block_ptr, qmat);
448
            block_ptr += 64;
449 450 451 452
            if (blocks_per_mb > 2) {
                ctx->dsp.idct_put(out_ptr + linesize * 4 + 8, linesize, block_ptr, qmat);
                block_ptr += 64;
            }
453
        }
454 455 456 457 458
    } else {
        for (mb_num = 0; mb_num < mbs_per_slice; mb_num++, out_ptr += blocks_per_mb * 4) {
            ctx->dsp.idct_put(out_ptr,                    linesize, block_ptr, qmat);
            block_ptr += 64;
            ctx->dsp.idct_put(out_ptr + linesize * 4,     linesize, block_ptr, qmat);
459
            block_ptr += 64;
460 461 462 463 464 465
            if (blocks_per_mb > 2) {
                ctx->dsp.idct_put(out_ptr + 8,            linesize, block_ptr, qmat);
                block_ptr += 64;
                ctx->dsp.idct_put(out_ptr + linesize * 4 + 8, linesize, block_ptr, qmat);
                block_ptr += 64;
            }
466
        }
467 468 469 470
    }
}


471
static int decode_slice(AVCodecContext *avctx, void *tdata)
472
{
473
    ProresThreadData *td = tdata;
474 475 476 477 478 479
    ProresContext *ctx = avctx->priv_data;
    int mb_x_pos  = td->x_pos;
    int mb_y_pos  = td->y_pos;
    int pic_num   = ctx->pic_num;
    int slice_num = td->slice_num;
    int mbs_per_slice = td->slice_width;
480 481 482 483 484 485 486
    const uint8_t *buf;
    uint8_t *y_data, *u_data, *v_data;
    AVFrame *pic = avctx->coded_frame;
    int i, sf, slice_width_factor;
    int slice_data_size, hdr_size, y_data_size, u_data_size, v_data_size;
    int y_linesize, u_linesize, v_linesize;

487 488
    buf             = ctx->slice_data[slice_num].index;
    slice_data_size = ctx->slice_data[slice_num + 1].index - buf;
489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510

    slice_width_factor = av_log2(mbs_per_slice);

    y_data     = pic->data[0];
    u_data     = pic->data[1];
    v_data     = pic->data[2];
    y_linesize = pic->linesize[0];
    u_linesize = pic->linesize[1];
    v_linesize = pic->linesize[2];

    if (pic->interlaced_frame) {
        if (!(pic_num ^ pic->top_field_first)) {
            y_data += y_linesize;
            u_data += u_linesize;
            v_data += v_linesize;
        }
        y_linesize <<= 1;
        u_linesize <<= 1;
        v_linesize <<= 1;
    }

    if (slice_data_size < 6) {
511
        av_log(avctx, AV_LOG_ERROR, "slice data too small\n");
512
        return AVERROR_INVALIDDATA;
513 514 515 516 517 518
    }

    /* parse slice header */
    hdr_size    = buf[0] >> 3;
    y_data_size = AV_RB16(buf + 2);
    u_data_size = AV_RB16(buf + 4);
519 520
    v_data_size = hdr_size > 7 ? AV_RB16(buf + 6) :
        slice_data_size - y_data_size - u_data_size - hdr_size;
521

522 523
    if (hdr_size + y_data_size + u_data_size + v_data_size > slice_data_size ||
        v_data_size < 0 || hdr_size < 6) {
524
        av_log(avctx, AV_LOG_ERROR, "invalid data size\n");
525
        return AVERROR_INVALIDDATA;
526 527 528 529 530 531
    }

    sf = av_clip(buf[1], 1, 224);
    sf = sf > 128 ? (sf - 96) << 2 : sf;

    /* scale quantization matrixes according with slice's scale factor */
532
    /* TODO: this can be SIMD-optimized a lot */
533 534
    if (ctx->qmat_changed || sf != td->prev_slice_sf) {
        td->prev_slice_sf = sf;
535
        for (i = 0; i < 64; i++) {
536 537
            td->qmat_luma_scaled[ctx->dsp.idct_permutation[i]]   = ctx->qmat_luma[i]   * sf;
            td->qmat_chroma_scaled[ctx->dsp.idct_permutation[i]] = ctx->qmat_chroma[i] * sf;
538 539 540 541
        }
    }

    /* decode luma plane */
542
    decode_slice_plane(ctx, td, buf + hdr_size, y_data_size,
543 544 545
                       (uint16_t*) (y_data + (mb_y_pos << 4) * y_linesize +
                                    (mb_x_pos << 5)), y_linesize,
                       mbs_per_slice, 4, slice_width_factor + 2,
546
                       td->qmat_luma_scaled, 0);
547 548

    /* decode U chroma plane */
549
    decode_slice_plane(ctx, td, buf + hdr_size + y_data_size, u_data_size,
550 551 552 553
                       (uint16_t*) (u_data + (mb_y_pos << 4) * u_linesize +
                                    (mb_x_pos << ctx->mb_chroma_factor)),
                       u_linesize, mbs_per_slice, ctx->num_chroma_blocks,
                       slice_width_factor + ctx->chroma_factor - 1,
554
                       td->qmat_chroma_scaled, 1);
555 556

    /* decode V chroma plane */
557
    decode_slice_plane(ctx, td, buf + hdr_size + y_data_size + u_data_size,
558 559 560 561 562
                       v_data_size,
                       (uint16_t*) (v_data + (mb_y_pos << 4) * v_linesize +
                                    (mb_x_pos << ctx->mb_chroma_factor)),
                       v_linesize, mbs_per_slice, ctx->num_chroma_blocks,
                       slice_width_factor + ctx->chroma_factor - 1,
563
                       td->qmat_chroma_scaled, 1);
564 565 566 567 568 569 570 571 572 573 574 575

    return 0;
}


static int decode_picture(ProresContext *ctx, int pic_num,
                          AVCodecContext *avctx)
{
    int slice_num, slice_width, x_pos, y_pos;

    slice_num = 0;

576
    ctx->pic_num = pic_num;
577 578 579 580 581 582 583 584
    for (y_pos = 0; y_pos < ctx->num_y_mbs; y_pos++) {
        slice_width = 1 << ctx->slice_width_factor;

        for (x_pos = 0; x_pos < ctx->num_x_mbs && slice_width;
             x_pos += slice_width) {
            while (ctx->num_x_mbs - x_pos < slice_width)
                slice_width >>= 1;

585 586 587 588
            ctx->slice_data[slice_num].slice_num   = slice_num;
            ctx->slice_data[slice_num].x_pos       = x_pos;
            ctx->slice_data[slice_num].y_pos       = y_pos;
            ctx->slice_data[slice_num].slice_width = slice_width;
589 590 591 592 593

            slice_num++;
        }
    }

594
    return avctx->execute(avctx, decode_slice,
595 596
                          ctx->slice_data, NULL, slice_num,
                          sizeof(ctx->slice_data[0]));
597 598 599 600 601
}


#define MOVE_DATA_PTR(nbytes) buf += (nbytes); buf_size -= (nbytes)

602
static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
603 604 605 606 607 608 609 610 611 612 613 614
                        AVPacket *avpkt)
{
    ProresContext *ctx = avctx->priv_data;
    AVFrame *picture   = avctx->coded_frame;
    const uint8_t *buf = avpkt->data;
    int buf_size       = avpkt->size;
    int frame_hdr_size, pic_num, pic_data_size;

    /* check frame atom container */
    if (buf_size < 28 || buf_size < AV_RB32(buf) ||
        AV_RB32(buf + 4) != FRAME_ID) {
        av_log(avctx, AV_LOG_ERROR, "invalid frame\n");
615
        return AVERROR_INVALIDDATA;
616 617 618 619 620 621
    }

    MOVE_DATA_PTR(8);

    frame_hdr_size = decode_frame_header(ctx, buf, buf_size, avctx);
    if (frame_hdr_size < 0)
622
        return AVERROR_INVALIDDATA;
623 624 625 626 627 628 629

    MOVE_DATA_PTR(frame_hdr_size);

    if (picture->data[0])
        avctx->release_buffer(avctx, picture);

    picture->reference = 0;
630
    if (ff_get_buffer(avctx, picture) < 0)
631 632 633 634 635
        return -1;

    for (pic_num = 0; ctx->picture.interlaced_frame - pic_num + 1; pic_num++) {
        pic_data_size = decode_picture_header(ctx, buf, buf_size, avctx);
        if (pic_data_size < 0)
636
            return AVERROR_INVALIDDATA;
637 638 639 640 641 642 643

        if (decode_picture(ctx, pic_num, avctx))
            return -1;

        MOVE_DATA_PTR(pic_data_size);
    }

644
    *got_frame       = 1;
645 646 647 648 649 650 651 652 653 654 655 656 657
    *(AVFrame*) data = *avctx->coded_frame;

    return avpkt->size;
}


static av_cold int decode_close(AVCodecContext *avctx)
{
    ProresContext *ctx = avctx->priv_data;

    if (ctx->picture.data[0])
        avctx->release_buffer(avctx, &ctx->picture);

658
    av_freep(&ctx->slice_data);
659 660 661 662 663 664

    return 0;
}


AVCodec ff_prores_lgpl_decoder = {
665
    .name           = "prores_lgpl",
666
    .type           = AVMEDIA_TYPE_VIDEO,
667
    .id             = AV_CODEC_ID_PRORES,
668 669 670 671
    .priv_data_size = sizeof(ProresContext),
    .init           = decode_init,
    .close          = decode_close,
    .decode         = decode_frame,
672
    .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_SLICE_THREADS,
673 674
    .long_name      = NULL_IF_CONFIG_SMALL("Apple ProRes (iCodec Pro)")
};