libavcodec/proresdec2.c
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2010-2011 Maxim Poliakovski
00003  * Copyright (c) 2010-2011 Elvis Presley
00004  *
00005  * This file is part of FFmpeg.
00006  *
00007  * FFmpeg is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * FFmpeg is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with FFmpeg; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00020  */
00021 
00027 //#define DEBUG
00028 
00029 #define LONG_BITSTREAM_READER
00030 
00031 #include "avcodec.h"
00032 #include "get_bits.h"
00033 #include "simple_idct.h"
00034 #include "proresdec.h"
00035 
00036 static void permute(uint8_t *dst, const uint8_t *src, const uint8_t permutation[64])
00037 {
00038     int i;
00039     for (i = 0; i < 64; i++)
00040         dst[i] = permutation[src[i]];
00041 }
00042 
00043 static const uint8_t progressive_scan[64] = {
00044      0,  1,  8,  9,  2,  3, 10, 11,
00045     16, 17, 24, 25, 18, 19, 26, 27,
00046      4,  5, 12, 20, 13,  6,  7, 14,
00047     21, 28, 29, 22, 15, 23, 30, 31,
00048     32, 33, 40, 48, 41, 34, 35, 42,
00049     49, 56, 57, 50, 43, 36, 37, 44,
00050     51, 58, 59, 52, 45, 38, 39, 46,
00051     53, 60, 61, 54, 47, 55, 62, 63
00052 };
00053 
00054 static const uint8_t interlaced_scan[64] = {
00055      0,  8,  1,  9, 16, 24, 17, 25,
00056      2, 10,  3, 11, 18, 26, 19, 27,
00057     32, 40, 33, 34, 41, 48, 56, 49,
00058     42, 35, 43, 50, 57, 58, 51, 59,
00059      4, 12,  5,  6, 13, 20, 28, 21,
00060     14,  7, 15, 22, 29, 36, 44, 37,
00061     30, 23, 31, 38, 45, 52, 60, 53,
00062     46, 39, 47, 54, 61, 62, 55, 63,
00063 };
00064 
00065 static av_cold int decode_init(AVCodecContext *avctx)
00066 {
00067     ProresContext *ctx = avctx->priv_data;
00068     uint8_t idct_permutation[64];
00069 
00070     avctx->bits_per_raw_sample = 10;
00071 
00072     dsputil_init(&ctx->dsp, avctx);
00073     ff_proresdsp_init(&ctx->prodsp, avctx);
00074 
00075     avctx->coded_frame = &ctx->frame;
00076     ctx->frame.type = AV_PICTURE_TYPE_I;
00077     ctx->frame.key_frame = 1;
00078 
00079     ff_init_scantable_permutation(idct_permutation,
00080                                   ctx->prodsp.idct_permutation_type);
00081 
00082     permute(ctx->progressive_scan, progressive_scan, idct_permutation);
00083     permute(ctx->interlaced_scan, interlaced_scan, idct_permutation);
00084 
00085     return 0;
00086 }
00087 
00088 static int decode_frame_header(ProresContext *ctx, const uint8_t *buf,
00089                                const int data_size, AVCodecContext *avctx)
00090 {
00091     int hdr_size, width, height, flags;
00092     int version;
00093     const uint8_t *ptr;
00094 
00095     hdr_size = AV_RB16(buf);
00096     av_dlog(avctx, "header size %d\n", hdr_size);
00097     if (hdr_size > data_size) {
00098         av_log(avctx, AV_LOG_ERROR, "error, wrong header size\n");
00099         return -1;
00100     }
00101 
00102     version = AV_RB16(buf + 2);
00103     av_dlog(avctx, "%.4s version %d\n", buf+4, version);
00104     if (version > 1) {
00105         av_log(avctx, AV_LOG_ERROR, "unsupported version: %d\n", version);
00106         return -1;
00107     }
00108 
00109     width  = AV_RB16(buf + 8);
00110     height = AV_RB16(buf + 10);
00111     if (width != avctx->width || height != avctx->height) {
00112         av_log(avctx, AV_LOG_ERROR, "picture resolution change: %dx%d -> %dx%d\n",
00113                avctx->width, avctx->height, width, height);
00114         return -1;
00115     }
00116 
00117     ctx->frame_type = (buf[12] >> 2) & 3;
00118 
00119     av_dlog(avctx, "frame type %d\n", ctx->frame_type);
00120 
00121     if (ctx->frame_type == 0) {
00122         ctx->scan = ctx->progressive_scan; // permuted
00123     } else {
00124         ctx->scan = ctx->interlaced_scan; // permuted
00125         ctx->frame.interlaced_frame = 1;
00126         ctx->frame.top_field_first = ctx->frame_type == 1;
00127     }
00128 
00129     avctx->pix_fmt = (buf[12] & 0xC0) == 0xC0 ? PIX_FMT_YUV444P10 : PIX_FMT_YUV422P10;
00130 
00131     ptr   = buf + 20;
00132     flags = buf[19];
00133     av_dlog(avctx, "flags %x\n", flags);
00134 
00135     if (flags & 2) {
00136         permute(ctx->qmat_luma, ctx->prodsp.idct_permutation, ptr);
00137         ptr += 64;
00138     } else {
00139         memset(ctx->qmat_luma, 4, 64);
00140     }
00141 
00142     if (flags & 1) {
00143         permute(ctx->qmat_chroma, ctx->prodsp.idct_permutation, ptr);
00144     } else {
00145         memset(ctx->qmat_chroma, 4, 64);
00146     }
00147 
00148     return hdr_size;
00149 }
00150 
00151 static int decode_picture_header(AVCodecContext *avctx, const uint8_t *buf, const int buf_size)
00152 {
00153     ProresContext *ctx = avctx->priv_data;
00154     int i, hdr_size, slice_count;
00155     unsigned pic_data_size;
00156     int log2_slice_mb_width, log2_slice_mb_height;
00157     int slice_mb_count, mb_x, mb_y;
00158     const uint8_t *data_ptr, *index_ptr;
00159 
00160     hdr_size = buf[0] >> 3;
00161     if (hdr_size < 8 || hdr_size > buf_size) {
00162         av_log(avctx, AV_LOG_ERROR, "error, wrong picture header size\n");
00163         return -1;
00164     }
00165 
00166     pic_data_size = AV_RB32(buf + 1);
00167     if (pic_data_size > buf_size) {
00168         av_log(avctx, AV_LOG_ERROR, "error, wrong picture data size\n");
00169         return -1;
00170     }
00171 
00172     log2_slice_mb_width  = buf[7] >> 4;
00173     log2_slice_mb_height = buf[7] & 0xF;
00174     if (log2_slice_mb_width > 3 || log2_slice_mb_height) {
00175         av_log(avctx, AV_LOG_ERROR, "unsupported slice resolution: %dx%d\n",
00176                1 << log2_slice_mb_width, 1 << log2_slice_mb_height);
00177         return -1;
00178     }
00179 
00180     ctx->mb_width  = (avctx->width  + 15) >> 4;
00181     if (ctx->frame_type)
00182         ctx->mb_height = (avctx->height + 31) >> 5;
00183     else
00184         ctx->mb_height = (avctx->height + 15) >> 4;
00185 
00186     slice_count = AV_RB16(buf + 5);
00187 
00188     if (ctx->slice_count != slice_count || !ctx->slices) {
00189         av_freep(&ctx->slices);
00190         ctx->slices = av_mallocz(slice_count * sizeof(*ctx->slices));
00191         if (!ctx->slices)
00192             return AVERROR(ENOMEM);
00193         ctx->slice_count = slice_count;
00194     }
00195 
00196     if (!slice_count)
00197         return AVERROR(EINVAL);
00198 
00199     if (hdr_size + slice_count*2 > buf_size) {
00200         av_log(avctx, AV_LOG_ERROR, "error, wrong slice count\n");
00201         return -1;
00202     }
00203 
00204     // parse slice information
00205     index_ptr = buf + hdr_size;
00206     data_ptr  = index_ptr + slice_count*2;
00207 
00208     slice_mb_count = 1 << log2_slice_mb_width;
00209     mb_x = 0;
00210     mb_y = 0;
00211 
00212     for (i = 0; i < slice_count; i++) {
00213         SliceContext *slice = &ctx->slices[i];
00214 
00215         slice->data = data_ptr;
00216         data_ptr += AV_RB16(index_ptr + i*2);
00217 
00218         while (ctx->mb_width - mb_x < slice_mb_count)
00219             slice_mb_count >>= 1;
00220 
00221         slice->mb_x = mb_x;
00222         slice->mb_y = mb_y;
00223         slice->mb_count = slice_mb_count;
00224         slice->data_size = data_ptr - slice->data;
00225 
00226         if (slice->data_size < 6) {
00227             av_log(avctx, AV_LOG_ERROR, "error, wrong slice data size\n");
00228             return -1;
00229         }
00230 
00231         mb_x += slice_mb_count;
00232         if (mb_x == ctx->mb_width) {
00233             slice_mb_count = 1 << log2_slice_mb_width;
00234             mb_x = 0;
00235             mb_y++;
00236         }
00237         if (data_ptr > buf + buf_size) {
00238             av_log(avctx, AV_LOG_ERROR, "error, slice out of bounds\n");
00239             return -1;
00240         }
00241     }
00242 
00243     if (mb_x || mb_y != ctx->mb_height) {
00244         av_log(avctx, AV_LOG_ERROR, "error wrong mb count y %d h %d\n",
00245                mb_y, ctx->mb_height);
00246         return -1;
00247     }
00248 
00249     return pic_data_size;
00250 }
00251 
00252 #define DECODE_CODEWORD(val, codebook)                                  \
00253     do {                                                                \
00254         unsigned int rice_order, exp_order, switch_bits;                \
00255         unsigned int q, buf, bits;                                      \
00256                                                                         \
00257         UPDATE_CACHE(re, gb);                                           \
00258         buf = GET_CACHE(re, gb);                                        \
00259                                                                         \
00260         /* number of bits to switch between rice and exp golomb */      \
00261         switch_bits =  codebook & 3;                                    \
00262         rice_order  =  codebook >> 5;                                   \
00263         exp_order   = (codebook >> 2) & 7;                              \
00264                                                                         \
00265         q = 31 - av_log2(buf);                                          \
00266                                                                         \
00267         if (q > switch_bits) { /* exp golomb */                         \
00268             bits = exp_order - switch_bits + (q<<1);                    \
00269             val = SHOW_UBITS(re, gb, bits) - (1 << exp_order) +         \
00270                 ((switch_bits + 1) << rice_order);                      \
00271             SKIP_BITS(re, gb, bits);                                    \
00272         } else if (rice_order) {                                        \
00273             SKIP_BITS(re, gb, q+1);                                     \
00274             val = (q << rice_order) + SHOW_UBITS(re, gb, rice_order);   \
00275             SKIP_BITS(re, gb, rice_order);                              \
00276         } else {                                                        \
00277             val = q;                                                    \
00278             SKIP_BITS(re, gb, q+1);                                     \
00279         }                                                               \
00280     } while (0)
00281 
00282 #define TOSIGNED(x) (((x) >> 1) ^ (-((x) & 1)))
00283 
00284 #define FIRST_DC_CB 0xB8
00285 
00286 static const uint8_t dc_codebook[7] = { 0x04, 0x28, 0x28, 0x4D, 0x4D, 0x70, 0x70};
00287 
00288 static av_always_inline void decode_dc_coeffs(GetBitContext *gb, DCTELEM *out,
00289                                               int blocks_per_slice)
00290 {
00291     DCTELEM prev_dc;
00292     int code, i, sign;
00293 
00294     OPEN_READER(re, gb);
00295 
00296     DECODE_CODEWORD(code, FIRST_DC_CB);
00297     prev_dc = TOSIGNED(code);
00298     out[0] = prev_dc;
00299 
00300     out += 64; // dc coeff for the next block
00301 
00302     code = 5;
00303     sign = 0;
00304     for (i = 1; i < blocks_per_slice; i++, out += 64) {
00305         DECODE_CODEWORD(code, dc_codebook[FFMIN(code, 6U)]);
00306         if(code) sign ^= -(code & 1);
00307         else     sign  = 0;
00308         prev_dc += (((code + 1) >> 1) ^ sign) - sign;
00309         out[0] = prev_dc;
00310     }
00311     CLOSE_READER(re, gb);
00312 }
00313 
00314 // adaptive codebook switching lut according to previous run/level values
00315 static const uint8_t run_to_cb[16] = { 0x06, 0x06, 0x05, 0x05, 0x04, 0x29, 0x29, 0x29, 0x29, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x4C };
00316 static const uint8_t lev_to_cb[10] = { 0x04, 0x0A, 0x05, 0x06, 0x04, 0x28, 0x28, 0x28, 0x28, 0x4C };
00317 
00318 static av_always_inline void decode_ac_coeffs(AVCodecContext *avctx, GetBitContext *gb,
00319                                               DCTELEM *out, int blocks_per_slice)
00320 {
00321     ProresContext *ctx = avctx->priv_data;
00322     int block_mask, sign;
00323     unsigned pos, run, level;
00324     int max_coeffs, i, bits_left;
00325     int log2_block_count = av_log2(blocks_per_slice);
00326 
00327     OPEN_READER(re, gb);
00328     UPDATE_CACHE(re, gb);                                           \
00329     run   = 4;
00330     level = 2;
00331 
00332     max_coeffs = 64 << log2_block_count;
00333     block_mask = blocks_per_slice - 1;
00334 
00335     for (pos = block_mask;;) {
00336         bits_left = gb->size_in_bits - re_index;
00337         if (!bits_left || (bits_left < 32 && !SHOW_UBITS(re, gb, bits_left)))
00338             break;
00339 
00340         DECODE_CODEWORD(run, run_to_cb[FFMIN(run,  15)]);
00341         pos += run + 1;
00342         if (pos >= max_coeffs) {
00343             av_log(avctx, AV_LOG_ERROR, "ac tex damaged %d, %d\n", pos, max_coeffs);
00344             return;
00345         }
00346 
00347         DECODE_CODEWORD(level, lev_to_cb[FFMIN(level, 9)]);
00348         level += 1;
00349 
00350         i = pos >> log2_block_count;
00351 
00352         sign = SHOW_SBITS(re, gb, 1);
00353         SKIP_BITS(re, gb, 1);
00354         out[((pos & block_mask) << 6) + ctx->scan[i]] = ((level ^ sign) - sign);
00355     }
00356 
00357     CLOSE_READER(re, gb);
00358 }
00359 
00360 static void decode_slice_luma(AVCodecContext *avctx, SliceContext *slice,
00361                               uint8_t *dst, int dst_stride,
00362                               const uint8_t *buf, unsigned buf_size,
00363                               const int16_t *qmat)
00364 {
00365     ProresContext *ctx = avctx->priv_data;
00366     LOCAL_ALIGNED_16(DCTELEM, blocks, [8*4*64]);
00367     DCTELEM *block;
00368     GetBitContext gb;
00369     int i, blocks_per_slice = slice->mb_count<<2;
00370 
00371     for (i = 0; i < blocks_per_slice; i++)
00372         ctx->dsp.clear_block(blocks+(i<<6));
00373 
00374     init_get_bits(&gb, buf, buf_size << 3);
00375 
00376     decode_dc_coeffs(&gb, blocks, blocks_per_slice);
00377     decode_ac_coeffs(avctx, &gb, blocks, blocks_per_slice);
00378 
00379     block = blocks;
00380     for (i = 0; i < slice->mb_count; i++) {
00381         ctx->prodsp.idct_put(dst, dst_stride, block+(0<<6), qmat);
00382         ctx->prodsp.idct_put(dst+16, dst_stride, block+(1<<6), qmat);
00383         ctx->prodsp.idct_put(dst+8*dst_stride, dst_stride, block+(2<<6), qmat);
00384         ctx->prodsp.idct_put(dst+8*dst_stride+16, dst_stride, block+(3<<6), qmat);
00385         block += 4*64;
00386         dst += 32;
00387     }
00388 }
00389 
00390 static void decode_slice_chroma(AVCodecContext *avctx, SliceContext *slice,
00391                                 uint8_t *dst, int dst_stride,
00392                                 const uint8_t *buf, unsigned buf_size,
00393                                 const int16_t *qmat, int log2_blocks_per_mb)
00394 {
00395     ProresContext *ctx = avctx->priv_data;
00396     LOCAL_ALIGNED_16(DCTELEM, blocks, [8*4*64]);
00397     DCTELEM *block;
00398     GetBitContext gb;
00399     int i, j, blocks_per_slice = slice->mb_count << log2_blocks_per_mb;
00400 
00401     for (i = 0; i < blocks_per_slice; i++)
00402         ctx->dsp.clear_block(blocks+(i<<6));
00403 
00404     init_get_bits(&gb, buf, buf_size << 3);
00405 
00406     decode_dc_coeffs(&gb, blocks, blocks_per_slice);
00407     decode_ac_coeffs(avctx, &gb, blocks, blocks_per_slice);
00408 
00409     block = blocks;
00410     for (i = 0; i < slice->mb_count; i++) {
00411         for (j = 0; j < log2_blocks_per_mb; j++) {
00412             ctx->prodsp.idct_put(dst,              dst_stride, block+(0<<6), qmat);
00413             ctx->prodsp.idct_put(dst+8*dst_stride, dst_stride, block+(1<<6), qmat);
00414             block += 2*64;
00415             dst += 16;
00416         }
00417     }
00418 }
00419 
00420 static int decode_slice_thread(AVCodecContext *avctx, void *arg, int jobnr, int threadnr)
00421 {
00422     ProresContext *ctx = avctx->priv_data;
00423     SliceContext *slice = &ctx->slices[jobnr];
00424     const uint8_t *buf = slice->data;
00425     AVFrame *pic = avctx->coded_frame;
00426     int i, hdr_size, qscale, log2_chroma_blocks_per_mb;
00427     int luma_stride, chroma_stride;
00428     int y_data_size, u_data_size, v_data_size;
00429     uint8_t *dest_y, *dest_u, *dest_v;
00430     int16_t qmat_luma_scaled[64];
00431     int16_t qmat_chroma_scaled[64];
00432     int mb_x_shift;
00433 
00434     //av_log(avctx, AV_LOG_INFO, "slice %d mb width %d mb x %d y %d\n",
00435     //       jobnr, slice->mb_count, slice->mb_x, slice->mb_y);
00436 
00437     // slice header
00438     hdr_size = buf[0] >> 3;
00439     qscale = av_clip(buf[1], 1, 224);
00440     qscale = qscale > 128 ? qscale - 96 << 2: qscale;
00441     y_data_size = AV_RB16(buf + 2);
00442     u_data_size = AV_RB16(buf + 4);
00443     v_data_size = slice->data_size - y_data_size - u_data_size - hdr_size;
00444     if (hdr_size > 7) v_data_size = AV_RB16(buf + 6);
00445 
00446     if (y_data_size < 0 || u_data_size < 0 || v_data_size < 0
00447         || hdr_size+y_data_size+u_data_size+v_data_size > slice->data_size){
00448         av_log(avctx, AV_LOG_ERROR, "invalid plane data size\n");
00449         return -1;
00450     }
00451 
00452     buf += hdr_size;
00453 
00454     for (i = 0; i < 64; i++) {
00455         qmat_luma_scaled  [i] = ctx->qmat_luma  [i] * qscale;
00456         qmat_chroma_scaled[i] = ctx->qmat_chroma[i] * qscale;
00457     }
00458 
00459     if (ctx->frame_type == 0) {
00460         luma_stride   = pic->linesize[0];
00461         chroma_stride = pic->linesize[1];
00462     } else {
00463         luma_stride   = pic->linesize[0] << 1;
00464         chroma_stride = pic->linesize[1] << 1;
00465     }
00466 
00467     if (avctx->pix_fmt == PIX_FMT_YUV444P10) {
00468         mb_x_shift = 5;
00469         log2_chroma_blocks_per_mb = 2;
00470     } else {
00471         mb_x_shift = 4;
00472         log2_chroma_blocks_per_mb = 1;
00473     }
00474 
00475     dest_y = pic->data[0] + (slice->mb_y << 4) * luma_stride + (slice->mb_x << 5);
00476     dest_u = pic->data[1] + (slice->mb_y << 4) * chroma_stride + (slice->mb_x << mb_x_shift);
00477     dest_v = pic->data[2] + (slice->mb_y << 4) * chroma_stride + (slice->mb_x << mb_x_shift);
00478 
00479     if (ctx->frame_type && ctx->first_field ^ ctx->frame.top_field_first) {
00480         dest_y += pic->linesize[0];
00481         dest_u += pic->linesize[1];
00482         dest_v += pic->linesize[2];
00483     }
00484 
00485     decode_slice_luma(avctx, slice, dest_y, luma_stride,
00486                       buf, y_data_size, qmat_luma_scaled);
00487 
00488     if (!(avctx->flags & CODEC_FLAG_GRAY)) {
00489         decode_slice_chroma(avctx, slice, dest_u, chroma_stride,
00490                             buf + y_data_size, u_data_size,
00491                             qmat_chroma_scaled, log2_chroma_blocks_per_mb);
00492         decode_slice_chroma(avctx, slice, dest_v, chroma_stride,
00493                             buf + y_data_size + u_data_size, v_data_size,
00494                             qmat_chroma_scaled, log2_chroma_blocks_per_mb);
00495     }
00496 
00497     return 0;
00498 }
00499 
00500 static int decode_picture(AVCodecContext *avctx)
00501 {
00502     ProresContext *ctx = avctx->priv_data;
00503     int i, threads_ret[ctx->slice_count];
00504 
00505     avctx->execute2(avctx, decode_slice_thread, NULL, threads_ret, ctx->slice_count);
00506 
00507     for (i = 0; i < ctx->slice_count; i++)
00508         if (threads_ret[i] < 0)
00509             return threads_ret[i];
00510 
00511     return 0;
00512 }
00513 
00514 static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
00515                         AVPacket *avpkt)
00516 {
00517     ProresContext *ctx = avctx->priv_data;
00518     AVFrame *frame = avctx->coded_frame;
00519     const uint8_t *buf = avpkt->data;
00520     int buf_size = avpkt->size;
00521     int frame_hdr_size, pic_size;
00522 
00523     if (buf_size < 28 || AV_RL32(buf + 4) != AV_RL32("icpf")) {
00524         av_log(avctx, AV_LOG_ERROR, "invalid frame header\n");
00525         return -1;
00526     }
00527 
00528     ctx->first_field = 1;
00529 
00530     buf += 8;
00531     buf_size -= 8;
00532 
00533     frame_hdr_size = decode_frame_header(ctx, buf, buf_size, avctx);
00534     if (frame_hdr_size < 0)
00535         return -1;
00536 
00537     buf += frame_hdr_size;
00538     buf_size -= frame_hdr_size;
00539 
00540     if (frame->data[0])
00541         avctx->release_buffer(avctx, frame);
00542 
00543     if (avctx->get_buffer(avctx, frame) < 0)
00544         return -1;
00545 
00546  decode_picture:
00547     pic_size = decode_picture_header(avctx, buf, buf_size);
00548     if (pic_size < 0) {
00549         av_log(avctx, AV_LOG_ERROR, "error decoding picture header\n");
00550         return -1;
00551     }
00552 
00553     if (decode_picture(avctx)) {
00554         av_log(avctx, AV_LOG_ERROR, "error decoding picture\n");
00555         return -1;
00556     }
00557 
00558     buf += pic_size;
00559     buf_size -= pic_size;
00560 
00561     if (ctx->frame_type && buf_size > 0 && ctx->first_field) {
00562         ctx->first_field = 0;
00563         goto decode_picture;
00564     }
00565 
00566     *data_size = sizeof(AVFrame);
00567     *(AVFrame*)data = *frame;
00568 
00569     return avpkt->size;
00570 }
00571 
00572 static av_cold int decode_close(AVCodecContext *avctx)
00573 {
00574     ProresContext *ctx = avctx->priv_data;
00575 
00576     AVFrame *frame = avctx->coded_frame;
00577     if (frame->data[0])
00578         avctx->release_buffer(avctx, frame);
00579     av_freep(&ctx->slices);
00580 
00581     return 0;
00582 }
00583 
00584 AVCodec ff_prores_decoder = {
00585     .name           = "prores",
00586     .type           = AVMEDIA_TYPE_VIDEO,
00587     .id             = CODEC_ID_PRORES,
00588     .priv_data_size = sizeof(ProresContext),
00589     .init           = decode_init,
00590     .close          = decode_close,
00591     .decode         = decode_frame,
00592     .long_name      = NULL_IF_CONFIG_SMALL("ProRes"),
00593     .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_SLICE_THREADS,
00594 };