summaryrefslogtreecommitdiff
path: root/libavcodec/proresenc_anatoliy.c (plain)
blob: 0516066163a51ec5cd58f876fd4ae78167498fb3
1/*
2 * Apple ProRes encoder
3 *
4 * Copyright (c) 2011 Anatoliy Wasserman
5 *
6 * This file is part of FFmpeg.
7 *
8 * FFmpeg is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * FFmpeg is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with FFmpeg; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23/**
24 * @file
25 * Apple ProRes encoder (Anatoliy Wasserman version)
26 * Known FOURCCs: 'apch' (HQ), 'apcn' (SD), 'apcs' (LT), 'acpo' (Proxy)
27 */
28
29#include "avcodec.h"
30#include "dct.h"
31#include "internal.h"
32#include "put_bits.h"
33#include "bytestream.h"
34#include "fdctdsp.h"
35
36#define DEFAULT_SLICE_MB_WIDTH 8
37
38#define FF_PROFILE_PRORES_PROXY 0
39#define FF_PROFILE_PRORES_LT 1
40#define FF_PROFILE_PRORES_STANDARD 2
41#define FF_PROFILE_PRORES_HQ 3
42
43static const AVProfile profiles[] = {
44 { FF_PROFILE_PRORES_PROXY, "apco"},
45 { FF_PROFILE_PRORES_LT, "apcs"},
46 { FF_PROFILE_PRORES_STANDARD, "apcn"},
47 { FF_PROFILE_PRORES_HQ, "apch"},
48 { FF_PROFILE_UNKNOWN }
49};
50
51static const int qp_start_table[4] = { 4, 1, 1, 1 };
52static const int qp_end_table[4] = { 8, 9, 6, 6 };
53static const int bitrate_table[5] = { 1000, 2100, 3500, 5400 };
54
55static const uint8_t progressive_scan[64] = {
56 0, 1, 8, 9, 2, 3, 10, 11,
57 16, 17, 24, 25, 18, 19, 26, 27,
58 4, 5, 12, 20, 13, 6, 7, 14,
59 21, 28, 29, 22, 15, 23, 30, 31,
60 32, 33, 40, 48, 41, 34, 35, 42,
61 49, 56, 57, 50, 43, 36, 37, 44,
62 51, 58, 59, 52, 45, 38, 39, 46,
63 53, 60, 61, 54, 47, 55, 62, 63
64};
65
66static const uint8_t QMAT_LUMA[4][64] = {
67 {
68 4, 7, 9, 11, 13, 14, 15, 63,
69 7, 7, 11, 12, 14, 15, 63, 63,
70 9, 11, 13, 14, 15, 63, 63, 63,
71 11, 11, 13, 14, 63, 63, 63, 63,
72 11, 13, 14, 63, 63, 63, 63, 63,
73 13, 14, 63, 63, 63, 63, 63, 63,
74 13, 63, 63, 63, 63, 63, 63, 63,
75 63, 63, 63, 63, 63, 63, 63, 63
76 }, {
77 4, 5, 6, 7, 9, 11, 13, 15,
78 5, 5, 7, 8, 11, 13, 15, 17,
79 6, 7, 9, 11, 13, 15, 15, 17,
80 7, 7, 9, 11, 13, 15, 17, 19,
81 7, 9, 11, 13, 14, 16, 19, 23,
82 9, 11, 13, 14, 16, 19, 23, 29,
83 9, 11, 13, 15, 17, 21, 28, 35,
84 11, 13, 16, 17, 21, 28, 35, 41
85 }, {
86 4, 4, 5, 5, 6, 7, 7, 9,
87 4, 4, 5, 6, 7, 7, 9, 9,
88 5, 5, 6, 7, 7, 9, 9, 10,
89 5, 5, 6, 7, 7, 9, 9, 10,
90 5, 6, 7, 7, 8, 9, 10, 12,
91 6, 7, 7, 8, 9, 10, 12, 15,
92 6, 7, 7, 9, 10, 11, 14, 17,
93 7, 7, 9, 10, 11, 14, 17, 21
94 }, {
95 4, 4, 4, 4, 4, 4, 4, 4,
96 4, 4, 4, 4, 4, 4, 4, 4,
97 4, 4, 4, 4, 4, 4, 4, 4,
98 4, 4, 4, 4, 4, 4, 4, 5,
99 4, 4, 4, 4, 4, 4, 5, 5,
100 4, 4, 4, 4, 4, 5, 5, 6,
101 4, 4, 4, 4, 5, 5, 6, 7,
102 4, 4, 4, 4, 5, 6, 7, 7
103 }
104};
105
106static const uint8_t QMAT_CHROMA[4][64] = {
107 {
108 4, 7, 9, 11, 13, 14, 63, 63,
109 7, 7, 11, 12, 14, 63, 63, 63,
110 9, 11, 13, 14, 63, 63, 63, 63,
111 11, 11, 13, 14, 63, 63, 63, 63,
112 11, 13, 14, 63, 63, 63, 63, 63,
113 13, 14, 63, 63, 63, 63, 63, 63,
114 13, 63, 63, 63, 63, 63, 63, 63,
115 63, 63, 63, 63, 63, 63, 63, 63
116 }, {
117 4, 5, 6, 7, 9, 11, 13, 15,
118 5, 5, 7, 8, 11, 13, 15, 17,
119 6, 7, 9, 11, 13, 15, 15, 17,
120 7, 7, 9, 11, 13, 15, 17, 19,
121 7, 9, 11, 13, 14, 16, 19, 23,
122 9, 11, 13, 14, 16, 19, 23, 29,
123 9, 11, 13, 15, 17, 21, 28, 35,
124 11, 13, 16, 17, 21, 28, 35, 41
125 }, {
126 4, 4, 5, 5, 6, 7, 7, 9,
127 4, 4, 5, 6, 7, 7, 9, 9,
128 5, 5, 6, 7, 7, 9, 9, 10,
129 5, 5, 6, 7, 7, 9, 9, 10,
130 5, 6, 7, 7, 8, 9, 10, 12,
131 6, 7, 7, 8, 9, 10, 12, 15,
132 6, 7, 7, 9, 10, 11, 14, 17,
133 7, 7, 9, 10, 11, 14, 17, 21
134 }, {
135 4, 4, 4, 4, 4, 4, 4, 4,
136 4, 4, 4, 4, 4, 4, 4, 4,
137 4, 4, 4, 4, 4, 4, 4, 4,
138 4, 4, 4, 4, 4, 4, 4, 5,
139 4, 4, 4, 4, 4, 4, 5, 5,
140 4, 4, 4, 4, 4, 5, 5, 6,
141 4, 4, 4, 4, 5, 5, 6, 7,
142 4, 4, 4, 4, 5, 6, 7, 7
143 }
144};
145
146
147typedef struct {
148 FDCTDSPContext fdsp;
149 uint8_t* fill_y;
150 uint8_t* fill_u;
151 uint8_t* fill_v;
152
153 int qmat_luma[16][64];
154 int qmat_chroma[16][64];
155} ProresContext;
156
157static void encode_codeword(PutBitContext *pb, int val, int codebook)
158{
159 unsigned int rice_order, exp_order, switch_bits, first_exp, exp, zeros;
160
161 /* number of bits to switch between rice and exp golomb */
162 switch_bits = codebook & 3;
163 rice_order = codebook >> 5;
164 exp_order = (codebook >> 2) & 7;
165
166 first_exp = ((switch_bits + 1) << rice_order);
167
168 if (val >= first_exp) { /* exp golomb */
169 val -= first_exp;
170 val += (1 << exp_order);
171 exp = av_log2(val);
172 zeros = exp - exp_order + switch_bits + 1;
173 put_bits(pb, zeros, 0);
174 put_bits(pb, exp + 1, val);
175 } else if (rice_order) {
176 put_bits(pb, (val >> rice_order), 0);
177 put_bits(pb, 1, 1);
178 put_sbits(pb, rice_order, val);
179 } else {
180 put_bits(pb, val, 0);
181 put_bits(pb, 1, 1);
182 }
183}
184
185#define QSCALE(qmat,ind,val) ((val) / ((qmat)[ind]))
186#define TO_GOLOMB(val) (((val) << 1) ^ ((val) >> 31))
187#define DIFF_SIGN(val, sign) (((val) >> 31) ^ (sign))
188#define IS_NEGATIVE(val) ((((val) >> 31) ^ -1) + 1)
189#define TO_GOLOMB2(val,sign) ((val)==0 ? 0 : ((val) << 1) + (sign))
190
191static av_always_inline int get_level(int val)
192{
193 int sign = (val >> 31);
194 return (val ^ sign) - sign;
195}
196
197#define FIRST_DC_CB 0xB8
198
199static const uint8_t dc_codebook[7] = { 0x04, 0x28, 0x28, 0x4D, 0x4D, 0x70, 0x70};
200
201static void encode_dc_coeffs(PutBitContext *pb, int16_t *in,
202 int blocks_per_slice, int *qmat)
203{
204 int prev_dc, code;
205 int i, sign, idx;
206 int new_dc, delta, diff_sign, new_code;
207
208 prev_dc = QSCALE(qmat, 0, in[0] - 16384);
209 code = TO_GOLOMB(prev_dc);
210 encode_codeword(pb, code, FIRST_DC_CB);
211
212 code = 5; sign = 0; idx = 64;
213 for (i = 1; i < blocks_per_slice; i++, idx += 64) {
214 new_dc = QSCALE(qmat, 0, in[idx] - 16384);
215 delta = new_dc - prev_dc;
216 diff_sign = DIFF_SIGN(delta, sign);
217 new_code = TO_GOLOMB2(get_level(delta), diff_sign);
218
219 encode_codeword(pb, new_code, dc_codebook[FFMIN(code, 6)]);
220
221 code = new_code;
222 sign = delta >> 31;
223 prev_dc = new_dc;
224 }
225}
226
227static const uint8_t run_to_cb[16] = { 0x06, 0x06, 0x05, 0x05, 0x04, 0x29,
228 0x29, 0x29, 0x29, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x4C };
229static const uint8_t lev_to_cb[10] = { 0x04, 0x0A, 0x05, 0x06, 0x04, 0x28,
230 0x28, 0x28, 0x28, 0x4C };
231
232static void encode_ac_coeffs(AVCodecContext *avctx, PutBitContext *pb,
233 int16_t *in, int blocks_per_slice, int *qmat)
234{
235 int prev_run = 4;
236 int prev_level = 2;
237
238 int run = 0, level, code, i, j;
239 for (i = 1; i < 64; i++) {
240 int indp = progressive_scan[i];
241 for (j = 0; j < blocks_per_slice; j++) {
242 int val = QSCALE(qmat, indp, in[(j << 6) + indp]);
243 if (val) {
244 encode_codeword(pb, run, run_to_cb[FFMIN(prev_run, 15)]);
245
246 prev_run = run;
247 run = 0;
248 level = get_level(val);
249 code = level - 1;
250
251 encode_codeword(pb, code, lev_to_cb[FFMIN(prev_level, 9)]);
252
253 prev_level = level;
254
255 put_bits(pb, 1, IS_NEGATIVE(val));
256 } else {
257 ++run;
258 }
259 }
260 }
261}
262
263static void get(uint8_t *pixels, int stride, int16_t* block)
264{
265 int i;
266
267 for (i = 0; i < 8; i++) {
268 AV_WN64(block, AV_RN64(pixels));
269 AV_WN64(block+4, AV_RN64(pixels+8));
270 pixels += stride;
271 block += 8;
272 }
273}
274
275static void fdct_get(FDCTDSPContext *fdsp, uint8_t *pixels, int stride, int16_t* block)
276{
277 get(pixels, stride, block);
278 fdsp->fdct(block);
279}
280
281static int encode_slice_plane(AVCodecContext *avctx, int mb_count,
282 uint8_t *src, int src_stride, uint8_t *buf, unsigned buf_size,
283 int *qmat, int chroma)
284{
285 ProresContext* ctx = avctx->priv_data;
286 FDCTDSPContext *fdsp = &ctx->fdsp;
287 LOCAL_ALIGNED(16, int16_t, blocks, [DEFAULT_SLICE_MB_WIDTH << 8]);
288 int16_t *block;
289 int i, blocks_per_slice;
290 PutBitContext pb;
291
292 block = blocks;
293 for (i = 0; i < mb_count; i++) {
294 fdct_get(fdsp, src, src_stride, block + (0 << 6));
295 fdct_get(fdsp, src + 8 * src_stride, src_stride, block + ((2 - chroma) << 6));
296 if (!chroma) {
297 fdct_get(fdsp, src + 16, src_stride, block + (1 << 6));
298 fdct_get(fdsp, src + 16 + 8 * src_stride, src_stride, block + (3 << 6));
299 }
300
301 block += (256 >> chroma);
302 src += (32 >> chroma);
303 }
304
305 blocks_per_slice = mb_count << (2 - chroma);
306 init_put_bits(&pb, buf, buf_size);
307
308 encode_dc_coeffs(&pb, blocks, blocks_per_slice, qmat);
309 encode_ac_coeffs(avctx, &pb, blocks, blocks_per_slice, qmat);
310
311 flush_put_bits(&pb);
312 return put_bits_ptr(&pb) - pb.buf;
313}
314
315static av_always_inline unsigned encode_slice_data(AVCodecContext *avctx,
316 uint8_t *dest_y, uint8_t *dest_u, uint8_t *dest_v, int luma_stride,
317 int chroma_stride, unsigned mb_count, uint8_t *buf, unsigned data_size,
318 unsigned* y_data_size, unsigned* u_data_size, unsigned* v_data_size,
319 int qp)
320{
321 ProresContext* ctx = avctx->priv_data;
322
323 *y_data_size = encode_slice_plane(avctx, mb_count, dest_y, luma_stride,
324 buf, data_size, ctx->qmat_luma[qp - 1], 0);
325
326 if (!(avctx->flags & AV_CODEC_FLAG_GRAY)) {
327 *u_data_size = encode_slice_plane(avctx, mb_count, dest_u,
328 chroma_stride, buf + *y_data_size, data_size - *y_data_size,
329 ctx->qmat_chroma[qp - 1], 1);
330
331 *v_data_size = encode_slice_plane(avctx, mb_count, dest_v,
332 chroma_stride, buf + *y_data_size + *u_data_size,
333 data_size - *y_data_size - *u_data_size,
334 ctx->qmat_chroma[qp - 1], 1);
335 }
336
337 return *y_data_size + *u_data_size + *v_data_size;
338}
339
340static void subimage_with_fill(uint16_t *src, unsigned x, unsigned y,
341 unsigned stride, unsigned width, unsigned height, uint16_t *dst,
342 unsigned dst_width, unsigned dst_height)
343{
344
345 int box_width = FFMIN(width - x, dst_width);
346 int box_height = FFMIN(height - y, dst_height);
347 int i, j, src_stride = stride >> 1;
348 uint16_t last_pix, *last_line;
349
350 src += y * src_stride + x;
351 for (i = 0; i < box_height; ++i) {
352 for (j = 0; j < box_width; ++j) {
353 dst[j] = src[j];
354 }
355 last_pix = dst[j - 1];
356 for (; j < dst_width; j++)
357 dst[j] = last_pix;
358 src += src_stride;
359 dst += dst_width;
360 }
361 last_line = dst - dst_width;
362 for (; i < dst_height; i++) {
363 for (j = 0; j < dst_width; ++j) {
364 dst[j] = last_line[j];
365 }
366 dst += dst_width;
367 }
368}
369
370static int encode_slice(AVCodecContext *avctx, const AVFrame *pic, int mb_x,
371 int mb_y, unsigned mb_count, uint8_t *buf, unsigned data_size,
372 int unsafe, int *qp)
373{
374 int luma_stride, chroma_stride;
375 int hdr_size = 6, slice_size;
376 uint8_t *dest_y, *dest_u, *dest_v;
377 unsigned y_data_size = 0, u_data_size = 0, v_data_size = 0;
378 ProresContext* ctx = avctx->priv_data;
379 int tgt_bits = (mb_count * bitrate_table[avctx->profile]) >> 2;
380 int low_bytes = (tgt_bits - (tgt_bits >> 3)) >> 3; // 12% bitrate fluctuation
381 int high_bytes = (tgt_bits + (tgt_bits >> 3)) >> 3;
382
383 luma_stride = pic->linesize[0];
384 chroma_stride = pic->linesize[1];
385
386 dest_y = pic->data[0] + (mb_y << 4) * luma_stride + (mb_x << 5);
387 dest_u = pic->data[1] + (mb_y << 4) * chroma_stride + (mb_x << 4);
388 dest_v = pic->data[2] + (mb_y << 4) * chroma_stride + (mb_x << 4);
389
390 if (unsafe) {
391
392 subimage_with_fill((uint16_t *) pic->data[0], mb_x << 4, mb_y << 4,
393 luma_stride, avctx->width, avctx->height,
394 (uint16_t *) ctx->fill_y, mb_count << 4, 16);
395 subimage_with_fill((uint16_t *) pic->data[1], mb_x << 3, mb_y << 4,
396 chroma_stride, avctx->width >> 1, avctx->height,
397 (uint16_t *) ctx->fill_u, mb_count << 3, 16);
398 subimage_with_fill((uint16_t *) pic->data[2], mb_x << 3, mb_y << 4,
399 chroma_stride, avctx->width >> 1, avctx->height,
400 (uint16_t *) ctx->fill_v, mb_count << 3, 16);
401
402 encode_slice_data(avctx, ctx->fill_y, ctx->fill_u, ctx->fill_v,
403 mb_count << 5, mb_count << 4, mb_count, buf + hdr_size,
404 data_size - hdr_size, &y_data_size, &u_data_size, &v_data_size,
405 *qp);
406 } else {
407 slice_size = encode_slice_data(avctx, dest_y, dest_u, dest_v,
408 luma_stride, chroma_stride, mb_count, buf + hdr_size,
409 data_size - hdr_size, &y_data_size, &u_data_size, &v_data_size,
410 *qp);
411
412 if (slice_size > high_bytes && *qp < qp_end_table[avctx->profile]) {
413 do {
414 *qp += 1;
415 slice_size = encode_slice_data(avctx, dest_y, dest_u, dest_v,
416 luma_stride, chroma_stride, mb_count, buf + hdr_size,
417 data_size - hdr_size, &y_data_size, &u_data_size,
418 &v_data_size, *qp);
419 } while (slice_size > high_bytes && *qp < qp_end_table[avctx->profile]);
420 } else if (slice_size < low_bytes && *qp
421 > qp_start_table[avctx->profile]) {
422 do {
423 *qp -= 1;
424 slice_size = encode_slice_data(avctx, dest_y, dest_u, dest_v,
425 luma_stride, chroma_stride, mb_count, buf + hdr_size,
426 data_size - hdr_size, &y_data_size, &u_data_size,
427 &v_data_size, *qp);
428 } while (slice_size < low_bytes && *qp > qp_start_table[avctx->profile]);
429 }
430 }
431
432 buf[0] = hdr_size << 3;
433 buf[1] = *qp;
434 AV_WB16(buf + 2, y_data_size);
435 AV_WB16(buf + 4, u_data_size);
436
437 return hdr_size + y_data_size + u_data_size + v_data_size;
438}
439
440static int prores_encode_picture(AVCodecContext *avctx, const AVFrame *pic,
441 uint8_t *buf, const int buf_size)
442{
443 int mb_width = (avctx->width + 15) >> 4;
444 int mb_height = (avctx->height + 15) >> 4;
445 int hdr_size, sl_size, i;
446 int mb_y, sl_data_size, qp;
447 int unsafe_bot, unsafe_right;
448 uint8_t *sl_data, *sl_data_sizes;
449 int slice_per_line = 0, rem = mb_width;
450
451 for (i = av_log2(DEFAULT_SLICE_MB_WIDTH); i >= 0; --i) {
452 slice_per_line += rem >> i;
453 rem &= (1 << i) - 1;
454 }
455
456 qp = qp_start_table[avctx->profile];
457 hdr_size = 8; sl_data_size = buf_size - hdr_size;
458 sl_data_sizes = buf + hdr_size;
459 sl_data = sl_data_sizes + (slice_per_line * mb_height * 2);
460 for (mb_y = 0; mb_y < mb_height; mb_y++) {
461 int mb_x = 0;
462 int slice_mb_count = DEFAULT_SLICE_MB_WIDTH;
463 while (mb_x < mb_width) {
464 while (mb_width - mb_x < slice_mb_count)
465 slice_mb_count >>= 1;
466
467 unsafe_bot = (avctx->height & 0xf) && (mb_y == mb_height - 1);
468 unsafe_right = (avctx->width & 0xf) && (mb_x + slice_mb_count == mb_width);
469
470 sl_size = encode_slice(avctx, pic, mb_x, mb_y, slice_mb_count,
471 sl_data, sl_data_size, unsafe_bot || unsafe_right, &qp);
472
473 bytestream_put_be16(&sl_data_sizes, sl_size);
474 sl_data += sl_size;
475 sl_data_size -= sl_size;
476 mb_x += slice_mb_count;
477 }
478 }
479
480 buf[0] = hdr_size << 3;
481 AV_WB32(buf + 1, sl_data - buf);
482 AV_WB16(buf + 5, slice_per_line * mb_height);
483 buf[7] = av_log2(DEFAULT_SLICE_MB_WIDTH) << 4;
484
485 return sl_data - buf;
486}
487
488static int prores_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
489 const AVFrame *pict, int *got_packet)
490{
491 int header_size = 148;
492 uint8_t *buf;
493 int pic_size, ret;
494 int frame_size = FFALIGN(avctx->width, 16) * FFALIGN(avctx->height, 16)*16 + 500 + AV_INPUT_BUFFER_MIN_SIZE; //FIXME choose tighter limit
495
496
497 if ((ret = ff_alloc_packet2(avctx, pkt, frame_size + AV_INPUT_BUFFER_MIN_SIZE, 0)) < 0)
498 return ret;
499
500 buf = pkt->data;
501 pic_size = prores_encode_picture(avctx, pict, buf + header_size + 8,
502 pkt->size - header_size - 8);
503
504 bytestream_put_be32(&buf, pic_size + 8 + header_size);
505 bytestream_put_buffer(&buf, "icpf", 4);
506
507 bytestream_put_be16(&buf, header_size);
508 bytestream_put_be16(&buf, 0);
509 bytestream_put_buffer(&buf, "fmpg", 4);
510 bytestream_put_be16(&buf, avctx->width);
511 bytestream_put_be16(&buf, avctx->height);
512 *buf++ = 0x83; // {10}(422){00}{00}(frame){11}
513 *buf++ = 0;
514 *buf++ = 2;
515 *buf++ = 2;
516 *buf++ = 6;
517 *buf++ = 32;
518 *buf++ = 0;
519 *buf++ = 3;
520
521 bytestream_put_buffer(&buf, QMAT_LUMA[avctx->profile], 64);
522 bytestream_put_buffer(&buf, QMAT_CHROMA[avctx->profile], 64);
523
524 pkt->flags |= AV_PKT_FLAG_KEY;
525 pkt->size = pic_size + 8 + header_size;
526 *got_packet = 1;
527
528 return 0;
529}
530
531static void scale_mat(const uint8_t* src, int* dst, int scale)
532{
533 int i;
534 for (i = 0; i < 64; i++)
535 dst[i] = src[i] * scale;
536}
537
538static av_cold int prores_encode_init(AVCodecContext *avctx)
539{
540 int i;
541 ProresContext* ctx = avctx->priv_data;
542
543 if (avctx->pix_fmt != AV_PIX_FMT_YUV422P10) {
544 av_log(avctx, AV_LOG_ERROR, "need YUV422P10\n");
545 return AVERROR_PATCHWELCOME;
546 }
547 avctx->bits_per_raw_sample = 10;
548
549 if (avctx->width & 0x1) {
550 av_log(avctx, AV_LOG_ERROR,
551 "frame width needs to be multiple of 2\n");
552 return AVERROR(EINVAL);
553 }
554
555 if (avctx->width > 65534 || avctx->height > 65535) {
556 av_log(avctx, AV_LOG_ERROR,
557 "The maximum dimensions are 65534x65535\n");
558 return AVERROR(EINVAL);
559 }
560
561 if ((avctx->height & 0xf) || (avctx->width & 0xf)) {
562 ctx->fill_y = av_malloc(4 * (DEFAULT_SLICE_MB_WIDTH << 8));
563 if (!ctx->fill_y)
564 return AVERROR(ENOMEM);
565 ctx->fill_u = ctx->fill_y + (DEFAULT_SLICE_MB_WIDTH << 9);
566 ctx->fill_v = ctx->fill_u + (DEFAULT_SLICE_MB_WIDTH << 8);
567 }
568
569 if (avctx->profile == FF_PROFILE_UNKNOWN) {
570 avctx->profile = FF_PROFILE_PRORES_STANDARD;
571 av_log(avctx, AV_LOG_INFO,
572 "encoding with ProRes standard (apcn) profile\n");
573
574 } else if (avctx->profile < FF_PROFILE_PRORES_PROXY
575 || avctx->profile > FF_PROFILE_PRORES_HQ) {
576 av_log(
577 avctx,
578 AV_LOG_ERROR,
579 "unknown profile %d, use [0 - apco, 1 - apcs, 2 - apcn (default), 3 - apch]\n",
580 avctx->profile);
581 return AVERROR(EINVAL);
582 }
583
584 ff_fdctdsp_init(&ctx->fdsp, avctx);
585
586 avctx->codec_tag = AV_RL32((const uint8_t*)profiles[avctx->profile].name);
587
588 for (i = 1; i <= 16; i++) {
589 scale_mat(QMAT_LUMA[avctx->profile] , ctx->qmat_luma[i - 1] , i);
590 scale_mat(QMAT_CHROMA[avctx->profile], ctx->qmat_chroma[i - 1], i);
591 }
592
593 return 0;
594}
595
596static av_cold int prores_encode_close(AVCodecContext *avctx)
597{
598 ProresContext* ctx = avctx->priv_data;
599 av_freep(&ctx->fill_y);
600
601 return 0;
602}
603
604AVCodec ff_prores_aw_encoder = {
605 .name = "prores_aw",
606 .long_name = NULL_IF_CONFIG_SMALL("Apple ProRes"),
607 .type = AVMEDIA_TYPE_VIDEO,
608 .id = AV_CODEC_ID_PRORES,
609 .priv_data_size = sizeof(ProresContext),
610 .init = prores_encode_init,
611 .close = prores_encode_close,
612 .encode2 = prores_encode_frame,
613 .pix_fmts = (const enum AVPixelFormat[]){AV_PIX_FMT_YUV422P10, AV_PIX_FMT_NONE},
614 .capabilities = AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_INTRA_ONLY,
615 .profiles = profiles
616};
617
618AVCodec ff_prores_encoder = {
619 .name = "prores",
620 .long_name = NULL_IF_CONFIG_SMALL("Apple ProRes"),
621 .type = AVMEDIA_TYPE_VIDEO,
622 .id = AV_CODEC_ID_PRORES,
623 .priv_data_size = sizeof(ProresContext),
624 .init = prores_encode_init,
625 .close = prores_encode_close,
626 .encode2 = prores_encode_frame,
627 .pix_fmts = (const enum AVPixelFormat[]){AV_PIX_FMT_YUV422P10, AV_PIX_FMT_NONE},
628 .capabilities = AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_INTRA_ONLY,
629 .profiles = profiles
630};
631