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     } else {
00190         ctx->picture.interlaced_frame = 0;
00191     }
00192 
00193     ctx->alpha_info = buf[17] & 0xf;
00194     if (ctx->alpha_info)
00195         av_log_missing_feature(avctx, "alpha channel", 0);
00196 
00197     ctx->qmat_changed = 0;
00198     ptr   = buf + 20;
00199     flags = buf[19];
00200     if (flags & 2) {
00201         if (ptr - buf > hdr_size - 64) {
00202             av_log(avctx, AV_LOG_ERROR, "header data too small\n");
00203             return AVERROR_INVALIDDATA;
00204         }
00205         if (memcmp(ctx->qmat_luma, ptr, 64)) {
00206             memcpy(ctx->qmat_luma, ptr, 64);
00207             ctx->qmat_changed = 1;
00208         }
00209         ptr += 64;
00210     } else {
00211         memset(ctx->qmat_luma, 4, 64);
00212         ctx->qmat_changed = 1;
00213     }
00214 
00215     if (flags & 1) {
00216         if (ptr - buf > hdr_size - 64) {
00217             av_log(avctx, AV_LOG_ERROR, "header data too small\n");
00218             return -1;
00219         }
00220         if (memcmp(ctx->qmat_chroma, ptr, 64)) {
00221             memcpy(ctx->qmat_chroma, ptr, 64);
00222             ctx->qmat_changed = 1;
00223         }
00224     } else {
00225         memset(ctx->qmat_chroma, 4, 64);
00226         ctx->qmat_changed = 1;
00227     }
00228 
00229     return hdr_size;
00230 }
00231 
00232 
00233 static int decode_picture_header(ProresContext *ctx, const uint8_t *buf,
00234                                  const int data_size, AVCodecContext *avctx)
00235 {
00236     int   i, hdr_size, pic_data_size, num_slices;
00237     int   slice_width_factor, slice_height_factor;
00238     int   remainder, num_x_slices;
00239     const uint8_t *data_ptr, *index_ptr;
00240 
00241     hdr_size = data_size > 0 ? buf[0] >> 3 : 0;
00242     if (hdr_size < 8 || hdr_size > data_size) {
00243         av_log(avctx, AV_LOG_ERROR, "picture header too small\n");
00244         return AVERROR_INVALIDDATA;
00245     }
00246 
00247     pic_data_size = AV_RB32(buf + 1);
00248     if (pic_data_size > data_size) {
00249         av_log(avctx, AV_LOG_ERROR, "picture data too small\n");
00250         return AVERROR_INVALIDDATA;
00251     }
00252 
00253     slice_width_factor  = buf[7] >> 4;
00254     slice_height_factor = buf[7] & 0xF;
00255     if (slice_width_factor > 3 || slice_height_factor) {
00256         av_log(avctx, AV_LOG_ERROR,
00257                "unsupported slice dimension: %d x %d\n",
00258                1 << slice_width_factor, 1 << slice_height_factor);
00259         return AVERROR_INVALIDDATA;
00260     }
00261 
00262     ctx->slice_width_factor  = slice_width_factor;
00263     ctx->slice_height_factor = slice_height_factor;
00264 
00265     ctx->num_x_mbs = (avctx->width + 15) >> 4;
00266     ctx->num_y_mbs = (avctx->height +
00267                       (1 << (4 + ctx->picture.interlaced_frame)) - 1) >>
00268                      (4 + ctx->picture.interlaced_frame);
00269 
00270     remainder    = ctx->num_x_mbs & ((1 << slice_width_factor) - 1);
00271     num_x_slices = (ctx->num_x_mbs >> slice_width_factor) + (remainder & 1) +
00272                    ((remainder >> 1) & 1) + ((remainder >> 2) & 1);
00273 
00274     num_slices = num_x_slices * ctx->num_y_mbs;
00275     if (num_slices != AV_RB16(buf + 5)) {
00276         av_log(avctx, AV_LOG_ERROR, "invalid number of slices\n");
00277         return AVERROR_INVALIDDATA;
00278     }
00279 
00280     if (ctx->total_slices != num_slices) {
00281         av_freep(&ctx->slice_data);
00282         ctx->slice_data = av_malloc((num_slices + 1) * sizeof(ctx->slice_data[0]));
00283         if (!ctx->slice_data)
00284             return AVERROR(ENOMEM);
00285         ctx->total_slices = num_slices;
00286     }
00287 
00288     if (hdr_size + num_slices * 2 > data_size) {
00289         av_log(avctx, AV_LOG_ERROR, "slice table too small\n");
00290         return AVERROR_INVALIDDATA;
00291     }
00292 
00293     /* parse slice table allowing quick access to the slice data */
00294     index_ptr = buf + hdr_size;
00295     data_ptr = index_ptr + num_slices * 2;
00296 
00297     for (i = 0; i < num_slices; i++) {
00298         ctx->slice_data[i].index = data_ptr;
00299         data_ptr += AV_RB16(index_ptr + i * 2);
00300     }
00301     ctx->slice_data[i].index = data_ptr;
00302 
00303     if (data_ptr > buf + data_size) {
00304         av_log(avctx, AV_LOG_ERROR, "out of slice data\n");
00305         return -1;
00306     }
00307 
00308     return pic_data_size;
00309 }
00310 
00311 
00315 static inline int decode_vlc_codeword(GetBitContext *gb, uint8_t codebook)
00316 {
00317     unsigned int rice_order, exp_order, switch_bits;
00318     unsigned int buf, code;
00319     int log, prefix_len, len;
00320 
00321     OPEN_READER(re, gb);
00322     UPDATE_CACHE(re, gb);
00323     buf = GET_CACHE(re, gb);
00324 
00325     /* number of prefix bits to switch between Rice and expGolomb */
00326     switch_bits = (codebook & 3) + 1;
00327     rice_order  = codebook >> 5;        /* rice code order */
00328     exp_order   = (codebook >> 2) & 7;  /* exp golomb code order */
00329 
00330     log = 31 - av_log2(buf); /* count prefix bits (zeroes) */
00331 
00332     if (log < switch_bits) { /* ok, we got a rice code */
00333         if (!rice_order) {
00334             /* shortcut for faster decoding of rice codes without remainder */
00335             code = log;
00336             LAST_SKIP_BITS(re, gb, log + 1);
00337         } else {
00338             prefix_len = log + 1;
00339             code = (log << rice_order) + NEG_USR32(buf << prefix_len, rice_order);
00340             LAST_SKIP_BITS(re, gb, prefix_len + rice_order);
00341         }
00342     } else { /* otherwise we got a exp golomb code */
00343         len  = (log << 1) - switch_bits + exp_order + 1;
00344         code = NEG_USR32(buf, len) - (1 << exp_order) + (switch_bits << rice_order);
00345         LAST_SKIP_BITS(re, gb, len);
00346     }
00347 
00348     CLOSE_READER(re, gb);
00349 
00350     return code;
00351 }
00352 
00353 #define LSB2SIGN(x) (-((x) & 1))
00354 #define TOSIGNED(x) (((x) >> 1) ^ LSB2SIGN(x))
00355 
00356 #define FIRST_DC_CB 0xB8 // rice_order = 5, exp_golomb_order = 6, switch_bits = 0
00357 
00358 static uint8_t dc_codebook[4] = {
00359     0x04, // rice_order = 0, exp_golomb_order = 1, switch_bits = 0
00360     0x28, // rice_order = 1, exp_golomb_order = 2, switch_bits = 0
00361     0x4D, // rice_order = 2, exp_golomb_order = 3, switch_bits = 1
00362     0x70  // rice_order = 3, exp_golomb_order = 4, switch_bits = 0
00363 };
00364 
00365 
00369 static inline void decode_dc_coeffs(GetBitContext *gb, DCTELEM *out,
00370                                     int nblocks)
00371 {
00372     DCTELEM prev_dc;
00373     int     i, sign;
00374     int16_t delta;
00375     unsigned int code;
00376 
00377     code   = decode_vlc_codeword(gb, FIRST_DC_CB);
00378     out[0] = prev_dc = TOSIGNED(code);
00379 
00380     out   += 64; /* move to the DC coeff of the next block */
00381     delta  = 3;
00382 
00383     for (i = 1; i < nblocks; i++, out += 64) {
00384         code = decode_vlc_codeword(gb, dc_codebook[FFMIN(FFABS(delta), 3)]);
00385 
00386         sign     = -(((delta >> 15) & 1) ^ (code & 1));
00387         delta    = (((code + 1) >> 1) ^ sign) - sign;
00388         prev_dc += delta;
00389         out[0]   = prev_dc;
00390     }
00391 }
00392 
00393 
00394 static uint8_t ac_codebook[7] = {
00395     0x04, // rice_order = 0, exp_golomb_order = 1, switch_bits = 0
00396     0x28, // rice_order = 1, exp_golomb_order = 2, switch_bits = 0
00397     0x4C, // rice_order = 2, exp_golomb_order = 3, switch_bits = 0
00398     0x05, // rice_order = 0, exp_golomb_order = 1, switch_bits = 1
00399     0x29, // rice_order = 1, exp_golomb_order = 2, switch_bits = 1
00400     0x06, // rice_order = 0, exp_golomb_order = 1, switch_bits = 2
00401     0x0A, // rice_order = 0, exp_golomb_order = 2, switch_bits = 2
00402 };
00403 
00408 static uint8_t run_to_cb_index[16] =
00409     { 5, 5, 3, 3, 0, 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 2 };
00410 
00411 static uint8_t lev_to_cb_index[10] = { 0, 6, 3, 5, 0, 1, 1, 1, 1, 2 };
00412 
00413 
00417 static inline void decode_ac_coeffs(GetBitContext *gb, DCTELEM *out,
00418                                     int blocks_per_slice,
00419                                     int plane_size_factor,
00420                                     const uint8_t *scan)
00421 {
00422     int pos, block_mask, run, level, sign, run_cb_index, lev_cb_index;
00423     int max_coeffs, bits_left;
00424 
00425     /* set initial prediction values */
00426     run   = 4;
00427     level = 2;
00428 
00429     max_coeffs = blocks_per_slice << 6;
00430     block_mask = blocks_per_slice - 1;
00431 
00432     for (pos = blocks_per_slice - 1; pos < max_coeffs;) {
00433         run_cb_index = run_to_cb_index[FFMIN(run, 15)];
00434         lev_cb_index = lev_to_cb_index[FFMIN(level, 9)];
00435 
00436         bits_left = get_bits_left(gb);
00437         if (bits_left <= 0 || (bits_left <= 8 && !show_bits(gb, bits_left)))
00438             return;
00439 
00440         run = decode_vlc_codeword(gb, ac_codebook[run_cb_index]);
00441 
00442         bits_left = get_bits_left(gb);
00443         if (bits_left <= 0 || (bits_left <= 8 && !show_bits(gb, bits_left)))
00444             return;
00445 
00446         level = decode_vlc_codeword(gb, ac_codebook[lev_cb_index]) + 1;
00447 
00448         pos += run + 1;
00449         if (pos >= max_coeffs)
00450             break;
00451 
00452         sign = get_sbits(gb, 1);
00453         out[((pos & block_mask) << 6) + scan[pos >> plane_size_factor]] =
00454             (level ^ sign) - sign;
00455     }
00456 }
00457 
00458 
00462 static void decode_slice_plane(ProresContext *ctx, ProresThreadData *td,
00463                                const uint8_t *buf,
00464                                int data_size, uint16_t *out_ptr,
00465                                int linesize, int mbs_per_slice,
00466                                int blocks_per_mb, int plane_size_factor,
00467                                const int16_t *qmat)
00468 {
00469     GetBitContext gb;
00470     DCTELEM *block_ptr;
00471     int mb_num, blocks_per_slice;
00472 
00473     blocks_per_slice = mbs_per_slice * blocks_per_mb;
00474 
00475     memset(td->blocks, 0, 8 * 4 * 64 * sizeof(*td->blocks));
00476 
00477     init_get_bits(&gb, buf, data_size << 3);
00478 
00479     decode_dc_coeffs(&gb, td->blocks, blocks_per_slice);
00480 
00481     decode_ac_coeffs(&gb, td->blocks, blocks_per_slice,
00482                      plane_size_factor, ctx->scantable.permutated);
00483 
00484     /* inverse quantization, inverse transform and output */
00485     block_ptr = td->blocks;
00486 
00487     for (mb_num = 0; mb_num < mbs_per_slice; mb_num++, out_ptr += blocks_per_mb * 4) {
00488         ctx->dsp.idct_put(out_ptr,                    linesize, block_ptr, qmat);
00489         block_ptr += 64;
00490         if (blocks_per_mb > 2) {
00491             ctx->dsp.idct_put(out_ptr + 8,            linesize, block_ptr, qmat);
00492             block_ptr += 64;
00493         }
00494         ctx->dsp.idct_put(out_ptr + linesize * 4,     linesize, block_ptr, qmat);
00495         block_ptr += 64;
00496         if (blocks_per_mb > 2) {
00497             ctx->dsp.idct_put(out_ptr + linesize * 4 + 8, linesize, block_ptr, qmat);
00498             block_ptr += 64;
00499         }
00500     }
00501 }
00502 
00503 
00504 static int decode_slice(AVCodecContext *avctx, void *tdata)
00505 {
00506     ProresThreadData *td = tdata;
00507     ProresContext *ctx = avctx->priv_data;
00508     int mb_x_pos  = td->x_pos;
00509     int mb_y_pos  = td->y_pos;
00510     int pic_num   = ctx->pic_num;
00511     int slice_num = td->slice_num;
00512     int mbs_per_slice = td->slice_width;
00513     const uint8_t *buf;
00514     uint8_t *y_data, *u_data, *v_data;
00515     AVFrame *pic = avctx->coded_frame;
00516     int i, sf, slice_width_factor;
00517     int slice_data_size, hdr_size, y_data_size, u_data_size, v_data_size;
00518     int y_linesize, u_linesize, v_linesize;
00519 
00520     buf             = ctx->slice_data[slice_num].index;
00521     slice_data_size = ctx->slice_data[slice_num + 1].index - buf;
00522 
00523     slice_width_factor = av_log2(mbs_per_slice);
00524 
00525     y_data     = pic->data[0];
00526     u_data     = pic->data[1];
00527     v_data     = pic->data[2];
00528     y_linesize = pic->linesize[0];
00529     u_linesize = pic->linesize[1];
00530     v_linesize = pic->linesize[2];
00531 
00532     if (pic->interlaced_frame) {
00533         if (!(pic_num ^ pic->top_field_first)) {
00534             y_data += y_linesize;
00535             u_data += u_linesize;
00536             v_data += v_linesize;
00537         }
00538         y_linesize <<= 1;
00539         u_linesize <<= 1;
00540         v_linesize <<= 1;
00541     }
00542 
00543     if (slice_data_size < 6) {
00544         av_log(avctx, AV_LOG_ERROR, "slice data too small\n");
00545         return AVERROR_INVALIDDATA;
00546     }
00547 
00548     /* parse slice header */
00549     hdr_size    = buf[0] >> 3;
00550     y_data_size = AV_RB16(buf + 2);
00551     u_data_size = AV_RB16(buf + 4);
00552     v_data_size = hdr_size > 7 ? AV_RB16(buf + 6) :
00553         slice_data_size - y_data_size - u_data_size - hdr_size;
00554 
00555     if (hdr_size + y_data_size + u_data_size + v_data_size > slice_data_size ||
00556         v_data_size < 0 || hdr_size < 6) {
00557         av_log(avctx, AV_LOG_ERROR, "invalid data size\n");
00558         return AVERROR_INVALIDDATA;
00559     }
00560 
00561     sf = av_clip(buf[1], 1, 224);
00562     sf = sf > 128 ? (sf - 96) << 2 : sf;
00563 
00564     /* scale quantization matrixes according with slice's scale factor */
00565     /* TODO: this can be SIMD-optimized a lot */
00566     if (ctx->qmat_changed || sf != ctx->prev_slice_sf) {
00567         ctx->prev_slice_sf = sf;
00568         for (i = 0; i < 64; i++) {
00569             ctx->qmat_luma_scaled[ctx->dsp.idct_permutation[i]]   = ctx->qmat_luma[i]   * sf;
00570             ctx->qmat_chroma_scaled[ctx->dsp.idct_permutation[i]] = ctx->qmat_chroma[i] * sf;
00571         }
00572     }
00573 
00574     /* decode luma plane */
00575     decode_slice_plane(ctx, td, buf + hdr_size, y_data_size,
00576                        (uint16_t*) (y_data + (mb_y_pos << 4) * y_linesize +
00577                                     (mb_x_pos << 5)), y_linesize,
00578                        mbs_per_slice, 4, slice_width_factor + 2,
00579                        ctx->qmat_luma_scaled);
00580 
00581     /* decode U chroma plane */
00582     decode_slice_plane(ctx, td, buf + hdr_size + y_data_size, u_data_size,
00583                        (uint16_t*) (u_data + (mb_y_pos << 4) * u_linesize +
00584                                     (mb_x_pos << ctx->mb_chroma_factor)),
00585                        u_linesize, mbs_per_slice, ctx->num_chroma_blocks,
00586                        slice_width_factor + ctx->chroma_factor - 1,
00587                        ctx->qmat_chroma_scaled);
00588 
00589     /* decode V chroma plane */
00590     decode_slice_plane(ctx, td, buf + hdr_size + y_data_size + u_data_size,
00591                        v_data_size,
00592                        (uint16_t*) (v_data + (mb_y_pos << 4) * v_linesize +
00593                                     (mb_x_pos << ctx->mb_chroma_factor)),
00594                        v_linesize, mbs_per_slice, ctx->num_chroma_blocks,
00595                        slice_width_factor + ctx->chroma_factor - 1,
00596                        ctx->qmat_chroma_scaled);
00597 
00598     return 0;
00599 }
00600 
00601 
00602 static int decode_picture(ProresContext *ctx, int pic_num,
00603                           AVCodecContext *avctx)
00604 {
00605     int slice_num, slice_width, x_pos, y_pos;
00606 
00607     slice_num = 0;
00608 
00609     ctx->pic_num = pic_num;
00610     for (y_pos = 0; y_pos < ctx->num_y_mbs; y_pos++) {
00611         slice_width = 1 << ctx->slice_width_factor;
00612 
00613         for (x_pos = 0; x_pos < ctx->num_x_mbs && slice_width;
00614              x_pos += slice_width) {
00615             while (ctx->num_x_mbs - x_pos < slice_width)
00616                 slice_width >>= 1;
00617 
00618             ctx->slice_data[slice_num].slice_num   = slice_num;
00619             ctx->slice_data[slice_num].x_pos       = x_pos;
00620             ctx->slice_data[slice_num].y_pos       = y_pos;
00621             ctx->slice_data[slice_num].slice_width = slice_width;
00622 
00623             slice_num++;
00624         }
00625     }
00626 
00627     return avctx->execute(avctx, decode_slice,
00628                           ctx->slice_data, NULL, slice_num,
00629                           sizeof(ctx->slice_data[0]));
00630 }
00631 
00632 
00633 #define FRAME_ID MKBETAG('i', 'c', 'p', 'f')
00634 #define MOVE_DATA_PTR(nbytes) buf += (nbytes); buf_size -= (nbytes)
00635 
00636 static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
00637                         AVPacket *avpkt)
00638 {
00639     ProresContext *ctx = avctx->priv_data;
00640     AVFrame *picture   = avctx->coded_frame;
00641     const uint8_t *buf = avpkt->data;
00642     int buf_size       = avpkt->size;
00643     int frame_hdr_size, pic_num, pic_data_size;
00644 
00645     /* check frame atom container */
00646     if (buf_size < 28 || buf_size < AV_RB32(buf) ||
00647         AV_RB32(buf + 4) != FRAME_ID) {
00648         av_log(avctx, AV_LOG_ERROR, "invalid frame\n");
00649         return AVERROR_INVALIDDATA;
00650     }
00651 
00652     MOVE_DATA_PTR(8);
00653 
00654     frame_hdr_size = decode_frame_header(ctx, buf, buf_size, avctx);
00655     if (frame_hdr_size < 0)
00656         return AVERROR_INVALIDDATA;
00657 
00658     MOVE_DATA_PTR(frame_hdr_size);
00659 
00660     if (picture->data[0])
00661         avctx->release_buffer(avctx, picture);
00662 
00663     picture->reference = 0;
00664     if (avctx->get_buffer(avctx, picture) < 0)
00665         return -1;
00666 
00667     for (pic_num = 0; ctx->picture.interlaced_frame - pic_num + 1; pic_num++) {
00668         pic_data_size = decode_picture_header(ctx, buf, buf_size, avctx);
00669         if (pic_data_size < 0)
00670             return AVERROR_INVALIDDATA;
00671 
00672         if (decode_picture(ctx, pic_num, avctx))
00673             return -1;
00674 
00675         MOVE_DATA_PTR(pic_data_size);
00676     }
00677 
00678     *data_size       = sizeof(AVPicture);
00679     *(AVFrame*) data = *avctx->coded_frame;
00680 
00681     return avpkt->size;
00682 }
00683 
00684 
00685 static av_cold int decode_close(AVCodecContext *avctx)
00686 {
00687     ProresContext *ctx = avctx->priv_data;
00688 
00689     if (ctx->picture.data[0])
00690         avctx->release_buffer(avctx, &ctx->picture);
00691 
00692     av_freep(&ctx->slice_data);
00693 
00694     return 0;
00695 }
00696 
00697 
00698 AVCodec ff_prores_decoder = {
00699     .name           = "prores",
00700     .type           = AVMEDIA_TYPE_VIDEO,
00701     .id             = CODEC_ID_PRORES,
00702     .priv_data_size = sizeof(ProresContext),
00703     .init           = decode_init,
00704     .close          = decode_close,
00705     .decode         = decode_frame,
00706     .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_SLICE_THREADS,
00707     .long_name      = NULL_IF_CONFIG_SMALL("Apple ProRes (iCodec Pro)")
00708 };