• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

libavcodec/proresenc.c

Go to the documentation of this file.
00001 /*
00002  * Apple ProRes encoder
00003  *
00004  * Copyright (c) 2011 Anatoliy Wasserman
00005  *
00006  * This file is part of FFmpeg.
00007  *
00008  * FFmpeg 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  * FFmpeg 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 FFmpeg; if not, write to the Free Software
00020  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00021  */
00022 
00028 #include "avcodec.h"
00029 #include "put_bits.h"
00030 #include "bytestream.h"
00031 #include "dsputil.h"
00032 
00033 #define DEFAULT_SLICE_MB_WIDTH 8
00034 
00035 #define FF_PROFILE_PRORES_PROXY     0
00036 #define FF_PROFILE_PRORES_LT        1
00037 #define FF_PROFILE_PRORES_STANDARD  2
00038 #define FF_PROFILE_PRORES_HQ        3
00039 
00040 static const AVProfile profiles[] = {
00041     { FF_PROFILE_PRORES_PROXY,    "apco"},
00042     { FF_PROFILE_PRORES_LT,       "apcs"},
00043     { FF_PROFILE_PRORES_STANDARD, "apcn"},
00044     { FF_PROFILE_PRORES_HQ,       "apch"},
00045     { FF_PROFILE_UNKNOWN }
00046 };
00047 
00048 static const int qp_start_table[4] = { 4, 1, 1, 1 };
00049 static const int qp_end_table[4]   = { 8, 9, 6, 6 };
00050 static const int bitrate_table[5]  = { 1000, 2100, 3500, 5400 };
00051 
00052 static const uint8_t progressive_scan[64] = {
00053      0,  1,  8,  9,  2,  3, 10, 11,
00054     16, 17, 24, 25, 18, 19, 26, 27,
00055      4,  5, 12, 20, 13,  6,  7, 14,
00056     21, 28, 29, 22, 15, 23, 30, 31,
00057     32, 33, 40, 48, 41, 34, 35, 42,
00058     49, 56, 57, 50, 43, 36, 37, 44,
00059     51, 58, 59, 52, 45, 38, 39, 46,
00060     53, 60, 61, 54, 47, 55, 62, 63
00061 };
00062 
00063 static const uint8_t QMAT_LUMA[4][64] = {
00064     {
00065          4,  7,  9, 11, 13, 14, 15, 63,
00066          7,  7, 11, 12, 14, 15, 63, 63,
00067          9, 11, 13, 14, 15, 63, 63, 63,
00068         11, 11, 13, 14, 63, 63, 63, 63,
00069         11, 13, 14, 63, 63, 63, 63, 63,
00070         13, 14, 63, 63, 63, 63, 63, 63,
00071         13, 63, 63, 63, 63, 63, 63, 63,
00072         63, 63, 63, 63, 63, 63, 63, 63
00073     }, {
00074          4,  5,  6,  7,  9, 11, 13, 15,
00075          5,  5,  7,  8, 11, 13, 15, 17,
00076          6,  7,  9, 11, 13, 15, 15, 17,
00077          7,  7,  9, 11, 13, 15, 17, 19,
00078          7,  9, 11, 13, 14, 16, 19, 23,
00079          9, 11, 13, 14, 16, 19, 23, 29,
00080          9, 11, 13, 15, 17, 21, 28, 35,
00081         11, 13, 16, 17, 21, 28, 35, 41
00082     }, {
00083          4,  4,  5,  5,  6,  7,  7,  9,
00084          4,  4,  5,  6,  7,  7,  9,  9,
00085          5,  5,  6,  7,  7,  9,  9, 10,
00086          5,  5,  6,  7,  7,  9,  9, 10,
00087          5,  6,  7,  7,  8,  9, 10, 12,
00088          6,  7,  7,  8,  9, 10, 12, 15,
00089          6,  7,  7,  9, 10, 11, 14, 17,
00090          7,  7,  9, 10, 11, 14, 17, 21
00091     }, {
00092          4,  4,  4,  4,  4,  4,  4,  4,
00093          4,  4,  4,  4,  4,  4,  4,  4,
00094          4,  4,  4,  4,  4,  4,  4,  4,
00095          4,  4,  4,  4,  4,  4,  4,  5,
00096          4,  4,  4,  4,  4,  4,  5,  5,
00097          4,  4,  4,  4,  4,  5,  5,  6,
00098          4,  4,  4,  4,  5,  5,  6,  7,
00099          4,  4,  4,  4,  5,  6,  7,  7
00100     }
00101 };
00102 
00103 static const uint8_t QMAT_CHROMA[4][64] = {
00104     {
00105          4,  7,  9, 11, 13, 14, 63, 63,
00106          7,  7, 11, 12, 14, 63, 63, 63,
00107          9, 11, 13, 14, 63, 63, 63, 63,
00108         11, 11, 13, 14, 63, 63, 63, 63,
00109         11, 13, 14, 63, 63, 63, 63, 63,
00110         13, 14, 63, 63, 63, 63, 63, 63,
00111         13, 63, 63, 63, 63, 63, 63, 63,
00112         63, 63, 63, 63, 63, 63, 63, 63
00113     }, {
00114          4,  5,  6,  7,  9, 11, 13, 15,
00115          5,  5,  7,  8, 11, 13, 15, 17,
00116          6,  7,  9, 11, 13, 15, 15, 17,
00117          7,  7,  9, 11, 13, 15, 17, 19,
00118          7,  9, 11, 13, 14, 16, 19, 23,
00119          9, 11, 13, 14, 16, 19, 23, 29,
00120          9, 11, 13, 15, 17, 21, 28, 35,
00121         11, 13, 16, 17, 21, 28, 35, 41
00122     }, {
00123          4,  4,  5,  5,  6,  7,  7,  9,
00124          4,  4,  5,  6,  7,  7,  9,  9,
00125          5,  5,  6,  7,  7,  9,  9, 10,
00126          5,  5,  6,  7,  7,  9,  9, 10,
00127          5,  6,  7,  7,  8,  9, 10, 12,
00128          6,  7,  7,  8,  9, 10, 12, 15,
00129          6,  7,  7,  9, 10, 11, 14, 17,
00130          7,  7,  9, 10, 11, 14, 17, 21
00131     }, {
00132          4,  4,  4,  4,  4,  4,  4,  4,
00133          4,  4,  4,  4,  4,  4,  4,  4,
00134          4,  4,  4,  4,  4,  4,  4,  4,
00135          4,  4,  4,  4,  4,  4,  4,  5,
00136          4,  4,  4,  4,  4,  4,  5,  5,
00137          4,  4,  4,  4,  4,  5,  5,  6,
00138          4,  4,  4,  4,  5,  5,  6,  7,
00139          4,  4,  4,  4,  5,  6,  7,  7
00140     }
00141 };
00142 
00143 
00144 typedef struct {
00145     uint8_t* fill_y;
00146     uint8_t* fill_u;
00147     uint8_t* fill_v;
00148 
00149     int qmat_luma[16][64];
00150     int qmat_chroma[16][64];
00151 } ProresContext;
00152 
00153 static void encode_codeword(PutBitContext *pb, int val, int codebook)
00154 {
00155     unsigned int rice_order, exp_order, switch_bits, first_exp, exp, zeros,
00156             mask;
00157 
00158     /* number of bits to switch between rice and exp golomb */
00159     switch_bits = codebook & 3;
00160     rice_order  = codebook >> 5;
00161     exp_order   = (codebook >> 2) & 7;
00162 
00163     first_exp = ((switch_bits + 1) << rice_order);
00164 
00165     if (val >= first_exp) { /* exp golomb */
00166         val -= first_exp;
00167         val += (1 << exp_order);
00168         exp = av_log2(val);
00169         zeros = exp - exp_order + switch_bits + 1;
00170         put_bits(pb, zeros, 0);
00171         put_bits(pb, 1, 1);
00172         put_bits(pb, exp, val);
00173     } else if (rice_order) {
00174         mask = (1 << rice_order) - 1;
00175         put_bits(pb, (val >> rice_order), 0);
00176         put_bits(pb, 1, 1);
00177         put_bits(pb, rice_order, val & mask);
00178     } else {
00179         put_bits(pb, val, 0);
00180         put_bits(pb, 1, 1);
00181     }
00182 }
00183 
00184 #define QSCALE(qmat,ind,val) ((val) / (qmat[ind]))
00185 #define TO_GOLOMB(val) ((val << 1) ^ (val >> 31))
00186 #define DIFF_SIGN(val, sign) ((val >> 31) ^ sign)
00187 #define IS_NEGATIVE(val) (((val >> 31) ^ -1) + 1)
00188 #define TO_GOLOMB2(val,sign) (val==0 ? 0 : (val << 1) + sign)
00189 
00190 static av_always_inline int get_level(int val)
00191 {
00192     int sign = (val >> 31);
00193     return (val ^ sign) - sign;
00194 }
00195 
00196 #define FIRST_DC_CB 0xB8
00197 
00198 static const uint8_t dc_codebook[7] = { 0x04, 0x28, 0x28, 0x4D, 0x4D, 0x70, 0x70};
00199 
00200 static void encode_dc_coeffs(PutBitContext *pb, DCTELEM *in,
00201         int blocks_per_slice, int *qmat)
00202 {
00203     int prev_dc, code;
00204     int i, sign, idx;
00205     int new_dc, delta, diff_sign, new_code;
00206 
00207     prev_dc = QSCALE(qmat, 0, in[0] - 16384);
00208     code = TO_GOLOMB(prev_dc);
00209     encode_codeword(pb, code, FIRST_DC_CB);
00210 
00211     code = 5; sign = 0; idx = 64;
00212     for (i = 1; i < blocks_per_slice; i++, idx += 64) {
00213         new_dc    = QSCALE(qmat, 0, in[idx] - 16384);
00214         delta     = new_dc - prev_dc;
00215         diff_sign = DIFF_SIGN(delta, sign);
00216         new_code  = TO_GOLOMB2(get_level(delta), diff_sign);
00217 
00218         encode_codeword(pb, new_code, dc_codebook[FFMIN(code, 6)]);
00219 
00220         code      = new_code;
00221         sign      = delta >> 31;
00222         prev_dc   = new_dc;
00223     }
00224 }
00225 
00226 static const uint8_t run_to_cb[16] = { 0x06, 0x06, 0x05, 0x05, 0x04, 0x29,
00227         0x29, 0x29, 0x29, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x4C };
00228 static const uint8_t lev_to_cb[10] = { 0x04, 0x0A, 0x05, 0x06, 0x04, 0x28,
00229         0x28, 0x28, 0x28, 0x4C };
00230 
00231 static void encode_ac_coeffs(AVCodecContext *avctx, PutBitContext *pb,
00232         DCTELEM *in, int blocks_per_slice, int *qmat)
00233 {
00234     int prev_run = 4;
00235     int prev_level = 2;
00236 
00237     int run = 0, level, code, i, j;
00238     for (i = 1; i < 64; i++) {
00239         int indp = progressive_scan[i];
00240         for (j = 0; j < blocks_per_slice; j++) {
00241             int val = QSCALE(qmat, indp, in[(j << 6) + indp]);
00242             if (val) {
00243                 encode_codeword(pb, run, run_to_cb[FFMIN(prev_run, 15)]);
00244 
00245                 prev_run   = run;
00246                 run        = 0;
00247                 level      = get_level(val);
00248                 code       = level - 1;
00249 
00250                 encode_codeword(pb, code, lev_to_cb[FFMIN(prev_level, 9)]);
00251 
00252                 prev_level = level;
00253 
00254                 put_bits(pb, 1, IS_NEGATIVE(val));
00255             } else {
00256                 ++run;
00257             }
00258         }
00259     }
00260 }
00261 
00262 static void get(uint8_t *pixels, int stride, DCTELEM* block)
00263 {
00264     int16_t *p = (int16_t*)pixels;
00265     int i, j;
00266 
00267     stride >>= 1;
00268     for (i = 0; i < 8; i++) {
00269         for (j = 0; j < 8; j++) {
00270             block[j] = p[j];
00271         }
00272         p += stride;
00273         block += 8;
00274     }
00275 }
00276 
00277 static void fdct_get(uint8_t *pixels, int stride, DCTELEM* block)
00278 {
00279     get(pixels, stride, block);
00280     ff_jpeg_fdct_islow_10(block);
00281 }
00282 
00283 static int encode_slice_plane(AVCodecContext *avctx, int mb_count,
00284         uint8_t *src, int src_stride, uint8_t *buf, unsigned buf_size,
00285         int *qmat, int chroma)
00286 {
00287     DECLARE_ALIGNED(16, DCTELEM, blocks)[DEFAULT_SLICE_MB_WIDTH << 8], *block;
00288     int i, blocks_per_slice;
00289     PutBitContext pb;
00290 
00291     block = blocks;
00292     for (i = 0; i < mb_count; i++) {
00293         fdct_get(src,                  src_stride, block + (0 << 6));
00294         fdct_get(src + 8 * src_stride, src_stride, block + ((2 - chroma) << 6));
00295         if (!chroma) {
00296             fdct_get(src + 16,                  src_stride, block + (1 << 6));
00297             fdct_get(src + 16 + 8 * src_stride, src_stride, block + (3 << 6));
00298         }
00299 
00300         block += (256 >> chroma);
00301         src   += (32  >> chroma);
00302     }
00303 
00304     blocks_per_slice = mb_count << (2 - chroma);
00305     init_put_bits(&pb, buf, buf_size << 3);
00306 
00307     encode_dc_coeffs(&pb, blocks, blocks_per_slice, qmat);
00308     encode_ac_coeffs(avctx, &pb, blocks, blocks_per_slice, qmat);
00309 
00310     flush_put_bits(&pb);
00311     return put_bits_ptr(&pb) - pb.buf;
00312 }
00313 
00314 static av_always_inline unsigned encode_slice_data(AVCodecContext *avctx,
00315         uint8_t *dest_y, uint8_t *dest_u, uint8_t *dest_v, int luma_stride,
00316         int chroma_stride, unsigned mb_count, uint8_t *buf, unsigned data_size,
00317         unsigned* y_data_size, unsigned* u_data_size, unsigned* v_data_size,
00318         int qp)
00319 {
00320     ProresContext* ctx = avctx->priv_data;
00321 
00322     *y_data_size = encode_slice_plane(avctx, mb_count, dest_y, luma_stride,
00323             buf, data_size, ctx->qmat_luma[qp - 1], 0);
00324 
00325     if (!(avctx->flags & CODEC_FLAG_GRAY)) {
00326         *u_data_size = encode_slice_plane(avctx, mb_count, dest_u,
00327                 chroma_stride, buf + *y_data_size, data_size - *y_data_size,
00328                 ctx->qmat_chroma[qp - 1], 1);
00329 
00330         *v_data_size = encode_slice_plane(avctx, mb_count, dest_v,
00331                 chroma_stride, buf + *y_data_size + *u_data_size,
00332                 data_size - *y_data_size - *u_data_size,
00333                 ctx->qmat_chroma[qp - 1], 1);
00334     }
00335 
00336     return *y_data_size + *u_data_size + *v_data_size;
00337 }
00338 
00339 static void subimage_with_fill(uint16_t *src, unsigned x, unsigned y,
00340         unsigned stride, unsigned width, unsigned height, uint16_t *dst,
00341         unsigned dst_width, unsigned dst_height)
00342 {
00343 
00344     int box_width = FFMIN(width - x, dst_width);
00345     int box_height = FFMIN(height - y, dst_height);
00346     int i, j, src_stride = stride >> 1;
00347     uint16_t last_pix, *last_line;
00348 
00349     src += y * src_stride + x;
00350     for (i = 0; i < box_height; ++i) {
00351         for (j = 0; j < box_width; ++j) {
00352             dst[j] = src[j];
00353         }
00354         last_pix = dst[j - 1];
00355         for (; j < dst_width; j++)
00356             dst[j] = last_pix;
00357         src += src_stride;
00358         dst += dst_width;
00359     }
00360     last_line = dst - dst_width;
00361     for (; i < dst_height; i++) {
00362         for (j = 0; j < dst_width; ++j) {
00363             dst[j] = last_line[j];
00364         }
00365         dst += dst_width;
00366     }
00367 }
00368 
00369 static int encode_slice(AVCodecContext *avctx, AVFrame *pic, int mb_x,
00370         int mb_y, unsigned mb_count, uint8_t *buf, unsigned data_size,
00371         int unsafe, int *qp)
00372 {
00373     int luma_stride, chroma_stride;
00374     int hdr_size = 6, slice_size;
00375     uint8_t *dest_y, *dest_u, *dest_v;
00376     unsigned y_data_size = 0, u_data_size = 0, v_data_size = 0;
00377     ProresContext* ctx = avctx->priv_data;
00378     int tgt_bits   = (mb_count * bitrate_table[avctx->profile]) >> 2;
00379     int low_bytes  = (tgt_bits - (tgt_bits >> 3)) >> 3; // 12% bitrate fluctuation
00380     int high_bytes = (tgt_bits + (tgt_bits >> 3)) >> 3;
00381 
00382     luma_stride   = pic->linesize[0];
00383     chroma_stride = pic->linesize[1];
00384 
00385     dest_y = pic->data[0] + (mb_y << 4) * luma_stride   + (mb_x << 5);
00386     dest_u = pic->data[1] + (mb_y << 4) * chroma_stride + (mb_x << 4);
00387     dest_v = pic->data[2] + (mb_y << 4) * chroma_stride + (mb_x << 4);
00388 
00389     if (unsafe) {
00390 
00391         subimage_with_fill((uint16_t *) pic->data[0], mb_x << 4, mb_y << 4,
00392                 luma_stride, avctx->width, avctx->height,
00393                 (uint16_t *) ctx->fill_y, mb_count << 4, 16);
00394         subimage_with_fill((uint16_t *) pic->data[1], mb_x << 3, mb_y << 4,
00395                 chroma_stride, avctx->width >> 1, avctx->height,
00396                 (uint16_t *) ctx->fill_u, mb_count << 3, 16);
00397         subimage_with_fill((uint16_t *) pic->data[2], mb_x << 3, mb_y << 4,
00398                 chroma_stride, avctx->width >> 1, avctx->height,
00399                 (uint16_t *) ctx->fill_v, mb_count << 3, 16);
00400 
00401         encode_slice_data(avctx, ctx->fill_y, ctx->fill_u, ctx->fill_v,
00402                 mb_count << 5, mb_count << 4, mb_count, buf + hdr_size,
00403                 data_size - hdr_size, &y_data_size, &u_data_size, &v_data_size,
00404                 *qp);
00405     } else {
00406         slice_size = encode_slice_data(avctx, dest_y, dest_u, dest_v,
00407                 luma_stride, chroma_stride, mb_count, buf + hdr_size,
00408                 data_size - hdr_size, &y_data_size, &u_data_size, &v_data_size,
00409                 *qp);
00410 
00411         if (slice_size > high_bytes && *qp < qp_end_table[avctx->profile]) {
00412             do {
00413                 *qp += 1;
00414                 slice_size = encode_slice_data(avctx, dest_y, dest_u, dest_v,
00415                         luma_stride, chroma_stride, mb_count, buf + hdr_size,
00416                         data_size - hdr_size, &y_data_size, &u_data_size,
00417                         &v_data_size, *qp);
00418             } while (slice_size > high_bytes && *qp < qp_end_table[avctx->profile]);
00419         } else if (slice_size < low_bytes && *qp
00420                 > qp_start_table[avctx->profile]) {
00421             do {
00422                 *qp -= 1;
00423                 slice_size = encode_slice_data(avctx, dest_y, dest_u, dest_v,
00424                         luma_stride, chroma_stride, mb_count, buf + hdr_size,
00425                         data_size - hdr_size, &y_data_size, &u_data_size,
00426                         &v_data_size, *qp);
00427             } while (slice_size < low_bytes && *qp > qp_start_table[avctx->profile]);
00428         }
00429     }
00430 
00431     buf[0] = hdr_size << 3;
00432     buf[1] = *qp;
00433     AV_WB16(buf + 2, y_data_size);
00434     AV_WB16(buf + 4, u_data_size);
00435 
00436     return hdr_size + y_data_size + u_data_size + v_data_size;
00437 }
00438 
00439 static int prores_encode_picture(AVCodecContext *avctx, AVFrame *pic,
00440         uint8_t *buf, const int buf_size)
00441 {
00442     int mb_width = (avctx->width + 15) >> 4;
00443     int mb_height = (avctx->height + 15) >> 4;
00444     int hdr_size, sl_size, i;
00445     int mb_y, sl_data_size, qp;
00446     int unsafe_bot, unsafe_right;
00447     uint8_t *sl_data, *sl_data_sizes;
00448     int slice_per_line = 0, rem = mb_width;
00449 
00450     for (i = av_log2(DEFAULT_SLICE_MB_WIDTH); i >= 0; --i) {
00451         slice_per_line += rem >> i;
00452         rem &= (1 << i) - 1;
00453     }
00454 
00455     qp = qp_start_table[avctx->profile];
00456     hdr_size = 8; sl_data_size = buf_size - hdr_size;
00457     sl_data_sizes = buf + hdr_size;
00458     sl_data = sl_data_sizes + (slice_per_line * mb_height * 2);
00459     for (mb_y = 0; mb_y < mb_height; mb_y++) {
00460         int mb_x = 0;
00461         int slice_mb_count = DEFAULT_SLICE_MB_WIDTH;
00462         while (mb_x < mb_width) {
00463             while (mb_width - mb_x < slice_mb_count)
00464                 slice_mb_count >>= 1;
00465 
00466             unsafe_bot = (avctx->height & 0xf) && (mb_y == mb_height - 1);
00467             unsafe_right = (avctx->width & 0xf) && (mb_x + slice_mb_count == mb_width);
00468 
00469             sl_size = encode_slice(avctx, pic, mb_x, mb_y, slice_mb_count,
00470                     sl_data, sl_data_size, unsafe_bot || unsafe_right, &qp);
00471 
00472             bytestream_put_be16(&sl_data_sizes, sl_size);
00473             sl_data           += sl_size;
00474             sl_data_size      -= sl_size;
00475             mb_x              += slice_mb_count;
00476         }
00477     }
00478 
00479     buf[0] = hdr_size << 3;
00480     AV_WB32(buf + 1, sl_data - buf);
00481     AV_WB16(buf + 5, slice_per_line * mb_height);
00482     buf[7] = av_log2(DEFAULT_SLICE_MB_WIDTH) << 4;
00483 
00484     return sl_data - buf;
00485 }
00486 
00487 static int prores_encode_frame(AVCodecContext *avctx, unsigned char *buf,
00488         int buf_size, void *data)
00489 {
00490     AVFrame *pic = data;
00491 
00492     int header_size = 148;
00493     int pic_size = prores_encode_picture(avctx, pic, buf + header_size + 8,
00494             buf_size - header_size - 8);
00495 
00496     bytestream_put_be32(&buf, pic_size + 8 + header_size);
00497     bytestream_put_buffer(&buf, "icpf", 4);
00498 
00499     bytestream_put_be16(&buf, header_size);
00500     bytestream_put_be16(&buf, 0);
00501     bytestream_put_buffer(&buf, "fmpg", 4);
00502     bytestream_put_be16(&buf, avctx->width);
00503     bytestream_put_be16(&buf, avctx->height);
00504     *buf++ = 0x83; // {10}(422){00}{00}(frame){11}
00505     *buf++ = 0;
00506     *buf++ = 2;
00507     *buf++ = 2;
00508     *buf++ = 6;
00509     *buf++ = 32;
00510     *buf++ = 0;
00511     *buf++ = 3;
00512 
00513     bytestream_put_buffer(&buf, QMAT_LUMA[avctx->profile],   64);
00514     bytestream_put_buffer(&buf, QMAT_CHROMA[avctx->profile], 64);
00515 
00516     return pic_size + 8 + header_size;
00517 }
00518 
00519 static void scale_mat(const uint8_t* src, int* dst, int scale)
00520 {
00521     int i;
00522     for (i = 0; i < 64; i++)
00523         dst[i] = src[i] * scale;
00524 }
00525 
00526 static av_cold int prores_encode_init(AVCodecContext *avctx)
00527 {
00528     int i;
00529     ProresContext* ctx = avctx->priv_data;
00530 
00531     if (avctx->pix_fmt != PIX_FMT_YUV422P10) {
00532         av_log(avctx, AV_LOG_ERROR, "need YUV422P10\n");
00533         return -1;
00534     }
00535     if (avctx->width & 0x1) {
00536         av_log(avctx, AV_LOG_ERROR,
00537                 "frame width needs to be multiple of 2\n");
00538         return -1;
00539     }
00540 
00541     if ((avctx->height & 0xf) || (avctx->width & 0xf)) {
00542         ctx->fill_y = av_malloc(4 * (DEFAULT_SLICE_MB_WIDTH << 8));
00543         if (!ctx->fill_y)
00544             return AVERROR(ENOMEM);
00545         ctx->fill_u = ctx->fill_y + (DEFAULT_SLICE_MB_WIDTH << 9);
00546         ctx->fill_v = ctx->fill_u + (DEFAULT_SLICE_MB_WIDTH << 8);
00547     }
00548 
00549     if (avctx->profile == FF_PROFILE_UNKNOWN) {
00550         avctx->profile = FF_PROFILE_PRORES_STANDARD;
00551         av_log(avctx, AV_LOG_INFO,
00552                 "encoding with ProRes standard (apcn) profile\n");
00553 
00554     } else if (avctx->profile < FF_PROFILE_PRORES_PROXY
00555             || avctx->profile > FF_PROFILE_PRORES_HQ) {
00556         av_log(
00557                 avctx,
00558                 AV_LOG_ERROR,
00559                 "unknown profile %d, use [0 - apco, 1 - apcs, 2 - apcn (default), 3 - apch]\n",
00560                 avctx->profile);
00561         return -1;
00562     }
00563 
00564     avctx->codec_tag = AV_RL32((const uint8_t*)profiles[avctx->profile].name);
00565 
00566     for (i = 1; i <= 16; i++) {
00567         scale_mat(QMAT_LUMA[avctx->profile]  , ctx->qmat_luma[i - 1]  , i);
00568         scale_mat(QMAT_CHROMA[avctx->profile], ctx->qmat_chroma[i - 1], i);
00569     }
00570 
00571     avctx->coded_frame = avcodec_alloc_frame();
00572     avctx->coded_frame->key_frame = 1;
00573     avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
00574 
00575     return 0;
00576 }
00577 
00578 static av_cold int prores_encode_close(AVCodecContext *avctx)
00579 {
00580     ProresContext* ctx = avctx->priv_data;
00581     av_freep(&avctx->coded_frame);
00582     av_freep(&ctx->fill_y);
00583 
00584     return 0;
00585 }
00586 
00587 AVCodec ff_prores_encoder = {
00588     .name           = "prores",
00589     .type           = AVMEDIA_TYPE_VIDEO,
00590     .id             = CODEC_ID_PRORES,
00591     .priv_data_size = sizeof(ProresContext),
00592     .init           = prores_encode_init,
00593     .close          = prores_encode_close,
00594     .encode         = prores_encode_frame,
00595     .pix_fmts       = (const enum PixelFormat[]){PIX_FMT_YUV422P10, PIX_FMT_NONE},
00596     .long_name      = NULL_IF_CONFIG_SMALL("Apple ProRes"),
00597     .profiles       = profiles
00598 };
Generated on Fri Feb 1 2013 14:34:41 for FFmpeg by doxygen 1.7.1