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