00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
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
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) {
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;
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;
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 .capabilities = 0,
00598 .profiles = profiles
00599 };