libavcodec/proresdec.c
Go to the documentation of this file.
00001 /*
00002  * Apple ProRes compatible decoder
00003  *
00004  * Copyright (c) 2010-2011 Maxim Poliakovski
00005  *
00006  * This file is part of Libav.
00007  *
00008  * Libav is free software; you can redistribute it and/or
00009  * modify it under the terms of the GNU Lesser General Public
00010  * License as published by the Free Software Foundation; either
00011  * version 2.1 of the License, or (at your option) any later version.
00012  *
00013  * Libav is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016  * Lesser General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU Lesser General Public
00019  * License along with Libav; if not, write to the Free Software
00020  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00021  */
00022 
00031 #define LONG_BITSTREAM_READER // some ProRes vlc codes require up to 28 bits to be read at once
00032 
00033 #include <stdint.h>
00034 
00035 #include "libavutil/intmath.h"
00036 #include "avcodec.h"
00037 #include "proresdsp.h"
00038 #include "get_bits.h"
00039 
00040 typedef struct {
00041     const uint8_t *index;            
00042     int slice_num;
00043     int x_pos, y_pos;
00044     int slice_width;
00045     DECLARE_ALIGNED(16, DCTELEM, blocks[8 * 4 * 64]);
00046 } ProresThreadData;
00047 
00048 typedef struct {
00049     ProresDSPContext dsp;
00050     AVFrame    picture;
00051     ScanTable  scantable;
00052     int        scantable_type;           
00053 
00054     int        frame_type;               
00055     int        pic_format;               
00056     uint8_t    qmat_luma[64];            
00057     uint8_t    qmat_chroma[64];          
00058     int        qmat_changed;             
00059     int        prev_slice_sf;            
00060     DECLARE_ALIGNED(16, int16_t, qmat_luma_scaled[64]);
00061     DECLARE_ALIGNED(16, int16_t, qmat_chroma_scaled[64]);
00062     int        total_slices;            
00063     ProresThreadData *slice_data;
00064     int        pic_num;
00065     int        chroma_factor;
00066     int        mb_chroma_factor;
00067     int        num_chroma_blocks;       
00068     int        num_x_slices;
00069     int        num_y_slices;
00070     int        slice_width_factor;
00071     int        slice_height_factor;
00072     int        num_x_mbs;
00073     int        num_y_mbs;
00074     int        alpha_info;
00075 } ProresContext;
00076 
00077 
00078 static const uint8_t progressive_scan[64] = {
00079      0,  1,  8,  9,  2,  3, 10, 11,
00080     16, 17, 24, 25, 18, 19, 26, 27,
00081      4,  5, 12, 20, 13,  6,  7, 14,
00082     21, 28, 29, 22, 15, 23, 30, 31,
00083     32, 33, 40, 48, 41, 34, 35, 42,
00084     49, 56, 57, 50, 43, 36, 37, 44,
00085     51, 58, 59, 52, 45, 38, 39, 46,
00086     53, 60, 61, 54, 47, 55, 62, 63
00087 };
00088 
00089 static const uint8_t interlaced_scan[64] = {
00090      0,  8,  1,  9, 16, 24, 17, 25,
00091      2, 10,  3, 11, 18, 26, 19, 27,
00092     32, 40, 33, 34, 41, 48, 56, 49,
00093     42, 35, 43, 50, 57, 58, 51, 59,
00094      4, 12,  5,  6, 13, 20, 28, 21,
00095     14,  7, 15, 22, 29, 36, 44, 37,
00096     30, 23, 31, 38, 45, 52, 60, 53,
00097     46, 39, 47, 54, 61, 62, 55, 63
00098 };
00099 
00100 
00101 static av_cold int decode_init(AVCodecContext *avctx)
00102 {
00103     ProresContext *ctx = avctx->priv_data;
00104 
00105     ctx->total_slices     = 0;
00106     ctx->slice_data       = NULL;
00107 
00108     avctx->bits_per_raw_sample = PRORES_BITS_PER_SAMPLE;
00109     ff_proresdsp_init(&ctx->dsp);
00110 
00111     avctx->coded_frame = &ctx->picture;
00112     avcodec_get_frame_defaults(&ctx->picture);
00113     ctx->picture.type      = AV_PICTURE_TYPE_I;
00114     ctx->picture.key_frame = 1;
00115 
00116     ctx->scantable_type = -1;   // set scantable type to uninitialized
00117     memset(ctx->qmat_luma, 4, 64);
00118     memset(ctx->qmat_chroma, 4, 64);
00119     ctx->prev_slice_sf = 0;
00120 
00121     return 0;
00122 }
00123 
00124 
00125 static int decode_frame_header(ProresContext *ctx, const uint8_t *buf,
00126                                const int data_size, AVCodecContext *avctx)
00127 {
00128     int hdr_size, version, width, height, flags;
00129     const uint8_t *ptr;
00130 
00131     hdr_size = AV_RB16(buf);
00132     if (hdr_size > data_size) {
00133         av_log(avctx, AV_LOG_ERROR, "frame data too small\n");
00134         return AVERROR_INVALIDDATA;
00135     }
00136 
00137     version = AV_RB16(buf + 2);
00138     if (version >= 2) {
00139         av_log(avctx, AV_LOG_ERROR,
00140                "unsupported header version: %d\n", version);
00141         return AVERROR_INVALIDDATA;
00142     }
00143 
00144     width  = AV_RB16(buf + 8);
00145     height = AV_RB16(buf + 10);
00146     if (width != avctx->width || height != avctx->height) {
00147         av_log(avctx, AV_LOG_ERROR,
00148                "picture dimension changed: old: %d x %d, new: %d x %d\n",
00149                avctx->width, avctx->height, width, height);
00150         return AVERROR_INVALIDDATA;
00151     }
00152 
00153     ctx->frame_type = (buf[12] >> 2) & 3;
00154     if (ctx->frame_type > 2) {
00155         av_log(avctx, AV_LOG_ERROR,
00156                "unsupported frame type: %d\n", ctx->frame_type);
00157         return AVERROR_INVALIDDATA;
00158     }
00159 
00160     ctx->chroma_factor     = (buf[12] >> 6) & 3;
00161     ctx->mb_chroma_factor  = ctx->chroma_factor + 2;
00162     ctx->num_chroma_blocks = (1 << ctx->chroma_factor) >> 1;
00163     switch (ctx->chroma_factor) {
00164     case 2:
00165         avctx->pix_fmt = PIX_FMT_YUV422P10;
00166         break;
00167     case 3:
00168         avctx->pix_fmt = PIX_FMT_YUV444P10;
00169         break;
00170     default:
00171         av_log(avctx, AV_LOG_ERROR,
00172                "unsupported picture format: %d\n", ctx->pic_format);
00173         return AVERROR_INVALIDDATA;
00174     }
00175 
00176     if (ctx->scantable_type != ctx->frame_type) {
00177         if (!ctx->frame_type)
00178             ff_init_scantable(ctx->dsp.idct_permutation, &ctx->scantable,
00179                               progressive_scan);
00180         else
00181             ff_init_scantable(ctx->dsp.idct_permutation, &ctx->scantable,
00182                               interlaced_scan);
00183         ctx->scantable_type = ctx->frame_type;
00184     }
00185 
00186     if (ctx->frame_type) {      /* if interlaced */
00187         ctx->picture.interlaced_frame = 1;
00188         ctx->picture.top_field_first  = ctx->frame_type & 1;
00189     }
00190 
00191     ctx->alpha_info = buf[17] & 0xf;
00192     if (ctx->alpha_info)
00193         av_log_missing_feature(avctx, "alpha channel", 0);
00194 
00195     ctx->qmat_changed = 0;
00196     ptr   = buf + 20;
00197     flags = buf[19];
00198     if (flags & 2) {
00199         if (ptr - buf > hdr_size - 64) {
00200             av_log(avctx, AV_LOG_ERROR, "header data too small\n");
00201             return AVERROR_INVALIDDATA;
00202         }
00203         if (memcmp(ctx->qmat_luma, ptr, 64)) {
00204             memcpy(ctx->qmat_luma, ptr, 64);
00205             ctx->qmat_changed = 1;
00206         }
00207         ptr += 64;
00208     } else {
00209         memset(ctx->qmat_luma, 4, 64);
00210         ctx->qmat_changed = 1;
00211     }
00212 
00213     if (flags & 1) {
00214         if (ptr - buf > hdr_size - 64) {
00215             av_log(avctx, AV_LOG_ERROR, "header data too small\n");
00216             return -1;
00217         }
00218         if (memcmp(ctx->qmat_chroma, ptr, 64)) {
00219             memcpy(ctx->qmat_chroma, ptr, 64);
00220             ctx->qmat_changed = 1;
00221         }
00222     } else {
00223         memset(ctx->qmat_chroma, 4, 64);
00224         ctx->qmat_changed = 1;
00225     }
00226 
00227     return hdr_size;
00228 }
00229 
00230 
00231 static int decode_picture_header(ProresContext *ctx, const uint8_t *buf,
00232                                  const int data_size, AVCodecContext *avctx)
00233 {
00234     int   i, hdr_size, pic_data_size, num_slices;
00235     int   slice_width_factor, slice_height_factor;
00236     int   remainder, num_x_slices;
00237     const uint8_t *data_ptr, *index_ptr;
00238 
00239     hdr_size = data_size > 0 ? buf[0] >> 3 : 0;
00240     if (hdr_size < 8 || hdr_size > data_size) {
00241         av_log(avctx, AV_LOG_ERROR, "picture header too small\n");
00242         return AVERROR_INVALIDDATA;
00243     }
00244 
00245     pic_data_size = AV_RB32(buf + 1);
00246     if (pic_data_size > data_size) {
00247         av_log(avctx, AV_LOG_ERROR, "picture data too small\n");
00248         return AVERROR_INVALIDDATA;
00249     }
00250 
00251     slice_width_factor  = buf[7] >> 4;
00252     slice_height_factor = buf[7] & 0xF;
00253     if (slice_width_factor > 3 || slice_height_factor) {
00254         av_log(avctx, AV_LOG_ERROR,
00255                "unsupported slice dimension: %d x %d\n",
00256                1 << slice_width_factor, 1 << slice_height_factor);
00257         return AVERROR_INVALIDDATA;
00258     }
00259 
00260     ctx->slice_width_factor  = slice_width_factor;
00261     ctx->slice_height_factor = slice_height_factor;
00262 
00263     ctx->num_x_mbs = (avctx->width + 15) >> 4;
00264     ctx->num_y_mbs = (avctx->height +
00265                       (1 << (4 + ctx->picture.interlaced_frame)) - 1) >>
00266                      (4 + ctx->picture.interlaced_frame);
00267 
00268     remainder    = ctx->num_x_mbs & ((1 << slice_width_factor) - 1);
00269     num_x_slices = (ctx->num_x_mbs >> slice_width_factor) + (remainder & 1) +
00270                    ((remainder >> 1) & 1) + ((remainder >> 2) & 1);
00271 
00272     num_slices = num_x_slices * ctx->num_y_mbs;
00273     if (num_slices != AV_RB16(buf + 5)) {
00274         av_log(avctx, AV_LOG_ERROR, "invalid number of slices\n");
00275         return AVERROR_INVALIDDATA;
00276     }
00277 
00278     if (ctx->total_slices != num_slices) {
00279         av_freep(&ctx->slice_data);
00280         ctx->slice_data = av_malloc((num_slices + 1) * sizeof(ctx->slice_data[0]));
00281         if (!ctx->slice_data)
00282             return AVERROR(ENOMEM);
00283         ctx->total_slices = num_slices;
00284     }
00285 
00286     if (hdr_size + num_slices * 2 > data_size) {
00287         av_log(avctx, AV_LOG_ERROR, "slice table too small\n");
00288         return AVERROR_INVALIDDATA;
00289     }
00290 
00291     /* parse slice table allowing quick access to the slice data */
00292     index_ptr = buf + hdr_size;
00293     data_ptr = index_ptr + num_slices * 2;
00294 
00295     for (i = 0; i < num_slices; i++) {
00296         ctx->slice_data[i].index = data_ptr;
00297         data_ptr += AV_RB16(index_ptr + i * 2);
00298     }
00299     ctx->slice_data[i].index = data_ptr;
00300 
00301     if (data_ptr > buf + data_size) {
00302         av_log(avctx, AV_LOG_ERROR, "out of slice data\n");
00303         return -1;
00304     }
00305 
00306     return pic_data_size;
00307 }
00308 
00309 
00313 static inline int decode_vlc_codeword(GetBitContext *gb, uint8_t codebook)
00314 {
00315     unsigned int rice_order, exp_order, switch_bits;
00316     unsigned int buf, code;
00317     int log, prefix_len, len;
00318 
00319     OPEN_READER(re, gb);
00320     UPDATE_CACHE(re, gb);
00321     buf = GET_CACHE(re, gb);
00322 
00323     /* number of prefix bits to switch between Rice and expGolomb */
00324     switch_bits = (codebook & 3) + 1;
00325     rice_order  = codebook >> 5;        /* rice code order */
00326     exp_order   = (codebook >> 2) & 7;  /* exp golomb code order */
00327 
00328     log = 31 - av_log2(buf); /* count prefix bits (zeroes) */
00329 
00330     if (log < switch_bits) { /* ok, we got a rice code */
00331         if (!rice_order) {
00332             /* shortcut for faster decoding of rice codes without remainder */
00333             code = log;
00334             LAST_SKIP_BITS(re, gb, log + 1);
00335         } else {
00336             prefix_len = log + 1;
00337             code = (log << rice_order) + NEG_USR32(buf << prefix_len, rice_order);
00338             LAST_SKIP_BITS(re, gb, prefix_len + rice_order);
00339         }
00340     } else { /* otherwise we got a exp golomb code */
00341         len  = (log << 1) - switch_bits + exp_order + 1;
00342         code = NEG_USR32(buf, len) - (1 << exp_order) + (switch_bits << rice_order);
00343         LAST_SKIP_BITS(re, gb, len);
00344     }
00345 
00346     CLOSE_READER(re, gb);
00347 
00348     return code;
00349 }
00350 
00351 #define LSB2SIGN(x) (-((x) & 1))
00352 #define TOSIGNED(x) (((x) >> 1) ^ LSB2SIGN(x))
00353 
00354 #define FIRST_DC_CB 0xB8 // rice_order = 5, exp_golomb_order = 6, switch_bits = 0
00355 
00356 static uint8_t dc_codebook[4] = {
00357     0x04, // rice_order = 0, exp_golomb_order = 1, switch_bits = 0
00358     0x28, // rice_order = 1, exp_golomb_order = 2, switch_bits = 0
00359     0x4D, // rice_order = 2, exp_golomb_order = 3, switch_bits = 1
00360     0x70  // rice_order = 3, exp_golomb_order = 4, switch_bits = 0
00361 };
00362 
00363 
00367 static inline void decode_dc_coeffs(GetBitContext *gb, DCTELEM *out,
00368                                     int nblocks)
00369 {
00370     DCTELEM prev_dc;
00371     int     i, sign;
00372     int16_t delta;
00373     unsigned int code;
00374 
00375     code   = decode_vlc_codeword(gb, FIRST_DC_CB);
00376     out[0] = prev_dc = TOSIGNED(code);
00377 
00378     out   += 64; /* move to the DC coeff of the next block */
00379     delta  = 3;
00380 
00381     for (i = 1; i < nblocks; i++, out += 64) {
00382         code = decode_vlc_codeword(gb, dc_codebook[FFMIN(FFABS(delta), 3)]);
00383 
00384         sign     = -(((delta >> 15) & 1) ^ (code & 1));
00385         delta    = (((code + 1) >> 1) ^ sign) - sign;
00386         prev_dc += delta;
00387         out[0]   = prev_dc;
00388     }
00389 }
00390 
00391 
00392 static uint8_t ac_codebook[7] = {
00393     0x04, // rice_order = 0, exp_golomb_order = 1, switch_bits = 0
00394     0x28, // rice_order = 1, exp_golomb_order = 2, switch_bits = 0
00395     0x4C, // rice_order = 2, exp_golomb_order = 3, switch_bits = 0
00396     0x05, // rice_order = 0, exp_golomb_order = 1, switch_bits = 1
00397     0x29, // rice_order = 1, exp_golomb_order = 2, switch_bits = 1
00398     0x06, // rice_order = 0, exp_golomb_order = 1, switch_bits = 2
00399     0x0A, // rice_order = 0, exp_golomb_order = 2, switch_bits = 2
00400 };
00401 
00406 static uint8_t run_to_cb_index[16] =
00407     { 5, 5, 3, 3, 0, 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 2 };
00408 
00409 static uint8_t lev_to_cb_index[10] = { 0, 6, 3, 5, 0, 1, 1, 1, 1, 2 };
00410 
00411 
00415 static inline void decode_ac_coeffs(GetBitContext *gb, DCTELEM *out,
00416                                     int blocks_per_slice,
00417                                     int plane_size_factor,
00418                                     const uint8_t *scan)
00419 {
00420     int pos, block_mask, run, level, sign, run_cb_index, lev_cb_index;
00421     int max_coeffs, bits_left;
00422 
00423     /* set initial prediction values */
00424     run   = 4;
00425     level = 2;
00426 
00427     max_coeffs = blocks_per_slice << 6;
00428     block_mask = blocks_per_slice - 1;
00429 
00430     for (pos = blocks_per_slice - 1; pos < max_coeffs;) {
00431         run_cb_index = run_to_cb_index[FFMIN(run, 15)];
00432         lev_cb_index = lev_to_cb_index[FFMIN(level, 9)];
00433 
00434         bits_left = get_bits_left(gb);
00435         if (bits_left <= 0 || (bits_left <= 8 && !show_bits(gb, bits_left)))
00436             return;
00437 
00438         run = decode_vlc_codeword(gb, ac_codebook[run_cb_index]);
00439 
00440         bits_left = get_bits_left(gb);
00441         if (bits_left <= 0 || (bits_left <= 8 && !show_bits(gb, bits_left)))
00442             return;
00443 
00444         level = decode_vlc_codeword(gb, ac_codebook[lev_cb_index]) + 1;
00445 
00446         pos += run + 1;
00447         if (pos >= max_coeffs)
00448             break;
00449 
00450         sign = get_sbits(gb, 1);
00451         out[((pos & block_mask) << 6) + scan[pos >> plane_size_factor]] =
00452             (level ^ sign) - sign;
00453     }
00454 }
00455 
00456 
00460 static void decode_slice_plane(ProresContext *ctx, ProresThreadData *td,
00461                                const uint8_t *buf,
00462                                int data_size, uint16_t *out_ptr,
00463                                int linesize, int mbs_per_slice,
00464                                int blocks_per_mb, int plane_size_factor,
00465                                const int16_t *qmat)
00466 {
00467     GetBitContext gb;
00468     DCTELEM *block_ptr;
00469     int mb_num, blocks_per_slice;
00470 
00471     blocks_per_slice = mbs_per_slice * blocks_per_mb;
00472 
00473     memset(td->blocks, 0, 8 * 4 * 64 * sizeof(*td->blocks));
00474 
00475     init_get_bits(&gb, buf, data_size << 3);
00476 
00477     decode_dc_coeffs(&gb, td->blocks, blocks_per_slice);
00478 
00479     decode_ac_coeffs(&gb, td->blocks, blocks_per_slice,
00480                      plane_size_factor, ctx->scantable.permutated);
00481 
00482     /* inverse quantization, inverse transform and output */
00483     block_ptr = td->blocks;
00484 
00485     for (mb_num = 0; mb_num < mbs_per_slice; mb_num++, out_ptr += blocks_per_mb * 4) {
00486         ctx->dsp.idct_put(out_ptr,                    linesize, block_ptr, qmat);
00487         block_ptr += 64;
00488         if (blocks_per_mb > 2) {
00489             ctx->dsp.idct_put(out_ptr + 8,            linesize, block_ptr, qmat);
00490             block_ptr += 64;
00491         }
00492         ctx->dsp.idct_put(out_ptr + linesize * 4,     linesize, block_ptr, qmat);
00493         block_ptr += 64;
00494         if (blocks_per_mb > 2) {
00495             ctx->dsp.idct_put(out_ptr + linesize * 4 + 8, linesize, block_ptr, qmat);
00496             block_ptr += 64;
00497         }
00498     }
00499 }
00500 
00501 
00502 static int decode_slice(AVCodecContext *avctx, void *tdata)
00503 {
00504     ProresThreadData *td = tdata;
00505     ProresContext *ctx = avctx->priv_data;
00506     int mb_x_pos  = td->x_pos;
00507     int mb_y_pos  = td->y_pos;
00508     int pic_num   = ctx->pic_num;
00509     int slice_num = td->slice_num;
00510     int mbs_per_slice = td->slice_width;
00511     const uint8_t *buf;
00512     uint8_t *y_data, *u_data, *v_data;
00513     AVFrame *pic = avctx->coded_frame;
00514     int i, sf, slice_width_factor;
00515     int slice_data_size, hdr_size, y_data_size, u_data_size, v_data_size;
00516     int y_linesize, u_linesize, v_linesize;
00517 
00518     buf             = ctx->slice_data[slice_num].index;
00519     slice_data_size = ctx->slice_data[slice_num + 1].index - buf;
00520 
00521     slice_width_factor = av_log2(mbs_per_slice);
00522 
00523     y_data     = pic->data[0];
00524     u_data     = pic->data[1];
00525     v_data     = pic->data[2];
00526     y_linesize = pic->linesize[0];
00527     u_linesize = pic->linesize[1];
00528     v_linesize = pic->linesize[2];
00529 
00530     if (pic->interlaced_frame) {
00531         if (!(pic_num ^ pic->top_field_first)) {
00532             y_data += y_linesize;
00533             u_data += u_linesize;
00534             v_data += v_linesize;
00535         }
00536         y_linesize <<= 1;
00537         u_linesize <<= 1;
00538         v_linesize <<= 1;
00539     }
00540 
00541     if (slice_data_size < 6) {
00542         av_log(avctx, AV_LOG_ERROR, "slice data too small\n");
00543         return AVERROR_INVALIDDATA;
00544     }
00545 
00546     /* parse slice header */
00547     hdr_size    = buf[0] >> 3;
00548     y_data_size = AV_RB16(buf + 2);
00549     u_data_size = AV_RB16(buf + 4);
00550     v_data_size = hdr_size > 7 ? AV_RB16(buf + 6) :
00551         slice_data_size - y_data_size - u_data_size - hdr_size;
00552 
00553     if (hdr_size + y_data_size + u_data_size + v_data_size > slice_data_size ||
00554         v_data_size < 0 || hdr_size < 6) {
00555         av_log(avctx, AV_LOG_ERROR, "invalid data size\n");
00556         return AVERROR_INVALIDDATA;
00557     }
00558 
00559     sf = av_clip(buf[1], 1, 224);
00560     sf = sf > 128 ? (sf - 96) << 2 : sf;
00561 
00562     /* scale quantization matrixes according with slice's scale factor */
00563     /* TODO: this can be SIMD-optimized a lot */
00564     if (ctx->qmat_changed || sf != ctx->prev_slice_sf) {
00565         ctx->prev_slice_sf = sf;
00566         for (i = 0; i < 64; i++) {
00567             ctx->qmat_luma_scaled[ctx->dsp.idct_permutation[i]]   = ctx->qmat_luma[i]   * sf;
00568             ctx->qmat_chroma_scaled[ctx->dsp.idct_permutation[i]] = ctx->qmat_chroma[i] * sf;
00569         }
00570     }
00571 
00572     /* decode luma plane */
00573     decode_slice_plane(ctx, td, buf + hdr_size, y_data_size,
00574                        (uint16_t*) (y_data + (mb_y_pos << 4) * y_linesize +
00575                                     (mb_x_pos << 5)), y_linesize,
00576                        mbs_per_slice, 4, slice_width_factor + 2,
00577                        ctx->qmat_luma_scaled);
00578 
00579     /* decode U chroma plane */
00580     decode_slice_plane(ctx, td, buf + hdr_size + y_data_size, u_data_size,
00581                        (uint16_t*) (u_data + (mb_y_pos << 4) * u_linesize +
00582                                     (mb_x_pos << ctx->mb_chroma_factor)),
00583                        u_linesize, mbs_per_slice, ctx->num_chroma_blocks,
00584                        slice_width_factor + ctx->chroma_factor - 1,
00585                        ctx->qmat_chroma_scaled);
00586 
00587     /* decode V chroma plane */
00588     decode_slice_plane(ctx, td, buf + hdr_size + y_data_size + u_data_size,
00589                        v_data_size,
00590                        (uint16_t*) (v_data + (mb_y_pos << 4) * v_linesize +
00591                                     (mb_x_pos << ctx->mb_chroma_factor)),
00592                        v_linesize, mbs_per_slice, ctx->num_chroma_blocks,
00593                        slice_width_factor + ctx->chroma_factor - 1,
00594                        ctx->qmat_chroma_scaled);
00595 
00596     return 0;
00597 }
00598 
00599 
00600 static int decode_picture(ProresContext *ctx, int pic_num,
00601                           AVCodecContext *avctx)
00602 {
00603     int slice_num, slice_width, x_pos, y_pos;
00604 
00605     slice_num = 0;
00606 
00607     ctx->pic_num = pic_num;
00608     for (y_pos = 0; y_pos < ctx->num_y_mbs; y_pos++) {
00609         slice_width = 1 << ctx->slice_width_factor;
00610 
00611         for (x_pos = 0; x_pos < ctx->num_x_mbs && slice_width;
00612              x_pos += slice_width) {
00613             while (ctx->num_x_mbs - x_pos < slice_width)
00614                 slice_width >>= 1;
00615 
00616             ctx->slice_data[slice_num].slice_num   = slice_num;
00617             ctx->slice_data[slice_num].x_pos       = x_pos;
00618             ctx->slice_data[slice_num].y_pos       = y_pos;
00619             ctx->slice_data[slice_num].slice_width = slice_width;
00620 
00621             slice_num++;
00622         }
00623     }
00624 
00625     return avctx->execute(avctx, decode_slice,
00626                           ctx->slice_data, NULL, slice_num,
00627                           sizeof(ctx->slice_data[0]));
00628 }
00629 
00630 
00631 #define FRAME_ID MKBETAG('i', 'c', 'p', 'f')
00632 #define MOVE_DATA_PTR(nbytes) buf += (nbytes); buf_size -= (nbytes)
00633 
00634 static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
00635                         AVPacket *avpkt)
00636 {
00637     ProresContext *ctx = avctx->priv_data;
00638     AVFrame *picture   = avctx->coded_frame;
00639     const uint8_t *buf = avpkt->data;
00640     int buf_size       = avpkt->size;
00641     int frame_hdr_size, pic_num, pic_data_size;
00642 
00643     /* check frame atom container */
00644     if (buf_size < 28 || buf_size < AV_RB32(buf) ||
00645         AV_RB32(buf + 4) != FRAME_ID) {
00646         av_log(avctx, AV_LOG_ERROR, "invalid frame\n");
00647         return AVERROR_INVALIDDATA;
00648     }
00649 
00650     MOVE_DATA_PTR(8);
00651 
00652     frame_hdr_size = decode_frame_header(ctx, buf, buf_size, avctx);
00653     if (frame_hdr_size < 0)
00654         return AVERROR_INVALIDDATA;
00655 
00656     MOVE_DATA_PTR(frame_hdr_size);
00657 
00658     if (picture->data[0])
00659         avctx->release_buffer(avctx, picture);
00660 
00661     picture->reference = 0;
00662     if (avctx->get_buffer(avctx, picture) < 0)
00663         return -1;
00664 
00665     for (pic_num = 0; ctx->picture.interlaced_frame - pic_num + 1; pic_num++) {
00666         pic_data_size = decode_picture_header(ctx, buf, buf_size, avctx);
00667         if (pic_data_size < 0)
00668             return AVERROR_INVALIDDATA;
00669 
00670         if (decode_picture(ctx, pic_num, avctx))
00671             return -1;
00672 
00673         MOVE_DATA_PTR(pic_data_size);
00674     }
00675 
00676     *data_size       = sizeof(AVPicture);
00677     *(AVFrame*) data = *avctx->coded_frame;
00678 
00679     return avpkt->size;
00680 }
00681 
00682 
00683 static av_cold int decode_close(AVCodecContext *avctx)
00684 {
00685     ProresContext *ctx = avctx->priv_data;
00686 
00687     if (ctx->picture.data[0])
00688         avctx->release_buffer(avctx, &ctx->picture);
00689 
00690     av_freep(&ctx->slice_data);
00691 
00692     return 0;
00693 }
00694 
00695 
00696 AVCodec ff_prores_decoder = {
00697     .name           = "prores",
00698     .type           = AVMEDIA_TYPE_VIDEO,
00699     .id             = CODEC_ID_PRORES,
00700     .priv_data_size = sizeof(ProresContext),
00701     .init           = decode_init,
00702     .close          = decode_close,
00703     .decode         = decode_frame,
00704     .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_SLICE_THREADS,
00705     .long_name      = NULL_IF_CONFIG_SMALL("Apple ProRes (iCodec Pro)")
00706 };