X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fproresenc.c;h=09678a002f584395d27acdd08a438418c2e28ccb;hb=ca1bae3983c6592efe4635e7e35a1f85833674b8;hp=20ab4512add2fb8a60cd0d32ea41cbf611e3bcdf;hpb=5c9b9165cd82478a6d26294561767d60439040d3;p=ffmpeg diff --git a/libavcodec/proresenc.c b/libavcodec/proresenc.c index 20ab4512add..09678a002f5 100644 --- a/libavcodec/proresenc.c +++ b/libavcodec/proresenc.c @@ -27,6 +27,7 @@ #include "avcodec.h" #include "put_bits.h" +#include "bytestream.h" #include "dsputil.h" #define DEFAULT_SLICE_MB_WIDTH 8 @@ -233,10 +234,10 @@ static void encode_ac_coeffs(AVCodecContext *avctx, PutBitContext *pb, int prev_run = 4; int prev_level = 2; - int run = 0, level, code; - for (int i = 1; i < 64; i++) { + int run = 0, level, code, i, j; + for (i = 1; i < 64; i++) { int indp = progressive_scan[i]; - for (int j = 0; j < blocks_per_slice; j++) { + for (j = 0; j < blocks_per_slice; j++) { int val = QSCALE(qmat, indp, in[(j << 6) + indp]); if (val) { encode_codeword(pb, run, run_to_cb[FFMIN(prev_run, 15)]); @@ -440,21 +441,21 @@ static int prores_encode_picture(AVCodecContext *avctx, AVFrame *pic, { int mb_width = (avctx->width + 15) >> 4; int mb_height = (avctx->height + 15) >> 4; - int hdr_size, sl_size, *slice_sizes; - int sl, mb_y, sl_data_size, qp; + int hdr_size, sl_size, i; + int mb_y, sl_data_size, qp; int unsafe_bot, unsafe_right; - uint8_t *sl_data; + uint8_t *sl_data, *sl_data_sizes; int slice_per_line = 0, rem = mb_width; - for (int i = av_log2(DEFAULT_SLICE_MB_WIDTH); i >= 0; --i) { + for (i = av_log2(DEFAULT_SLICE_MB_WIDTH); i >= 0; --i) { slice_per_line += rem >> i; rem &= (1 << i) - 1; } qp = qp_start_table[avctx->profile]; - slice_sizes = av_malloc(slice_per_line * mb_height * sizeof(int)); - sl = 0; hdr_size = 8; sl_data_size = buf_size - hdr_size; - sl_data = buf + hdr_size + (slice_per_line * mb_height * 2); + hdr_size = 8; sl_data_size = buf_size - hdr_size; + sl_data_sizes = buf + hdr_size; + sl_data = sl_data_sizes + (slice_per_line * mb_height * 2); for (mb_y = 0; mb_y < mb_height; mb_y++) { int mb_x = 0; int slice_mb_count = DEFAULT_SLICE_MB_WIDTH; @@ -468,7 +469,7 @@ static int prores_encode_picture(AVCodecContext *avctx, AVFrame *pic, sl_size = encode_slice(avctx, pic, mb_x, mb_y, slice_mb_count, sl_data, sl_data_size, unsafe_bot || unsafe_right, &qp); - slice_sizes[sl++] = sl_size; + bytestream_put_be16(&sl_data_sizes, sl_size); sl_data += sl_size; sl_data_size -= sl_size; mb_x += slice_mb_count; @@ -480,11 +481,6 @@ static int prores_encode_picture(AVCodecContext *avctx, AVFrame *pic, AV_WB16(buf + 5, slice_per_line * mb_height); buf[7] = av_log2(DEFAULT_SLICE_MB_WIDTH) << 4; - for (int i = 0; i < slice_per_line * mb_height; i++) - AV_WB16(buf + hdr_size + (i << 1), slice_sizes[i]); - - av_free(slice_sizes); - return sl_data - buf; } @@ -497,31 +493,25 @@ static int prores_encode_frame(AVCodecContext *avctx, unsigned char *buf, int pic_size = prores_encode_picture(avctx, pic, buf + header_size + 8, buf_size - header_size - 8); - AV_WB32(buf, pic_size + 8 + header_size); - AV_WB8 (buf + 4, 'i'); - AV_WB8 (buf + 5, 'c'); - AV_WB8 (buf + 6, 'p'); - AV_WB8 (buf + 7, 'f'); - - AV_WB16(buf + 8, header_size); - AV_WB16(buf + 10, 0); - AV_WB8 (buf + 12, 'f'); - AV_WB8 (buf + 13, 'm'); - AV_WB8 (buf + 14, 'p'); - AV_WB8 (buf + 15, 'g'); - AV_WB16(buf + 16, pic->width); - AV_WB16(buf + 18, pic->height); - buf[20] = 0x83; // {10}(422){00}{00}(frame){11} - buf[21] = 0; - buf[22] = 2; - buf[23] = 2; - buf[24] = 6; - buf[25] = 32; - buf[26] = 0; - buf[27] = 3; - - memcpy(buf + 28, QMAT_LUMA[avctx->profile], 64); - memcpy(buf + 92, QMAT_CHROMA[avctx->profile], 64); + bytestream_put_be32(&buf, pic_size + 8 + header_size); + bytestream_put_buffer(&buf, "icpf", 4); + + bytestream_put_be16(&buf, header_size); + bytestream_put_be16(&buf, 0); + bytestream_put_buffer(&buf, "fmpg", 4); + bytestream_put_be16(&buf, avctx->width); + bytestream_put_be16(&buf, avctx->height); + *buf++ = 0x83; // {10}(422){00}{00}(frame){11} + *buf++ = 0; + *buf++ = 2; + *buf++ = 2; + *buf++ = 6; + *buf++ = 32; + *buf++ = 0; + *buf++ = 3; + + bytestream_put_buffer(&buf, QMAT_LUMA[avctx->profile], 64); + bytestream_put_buffer(&buf, QMAT_CHROMA[avctx->profile], 64); return pic_size + 8 + header_size; } @@ -538,7 +528,7 @@ static av_cold int prores_encode_init(AVCodecContext *avctx) int i; ProresContext* ctx = avctx->priv_data; - if (avctx->pix_fmt != PIX_FMT_YUV422P10LE) { + if (avctx->pix_fmt != PIX_FMT_YUV422P10) { av_log(avctx, AV_LOG_ERROR, "need YUV422P10\n"); return -1; } @@ -549,9 +539,11 @@ static av_cold int prores_encode_init(AVCodecContext *avctx) } if ((avctx->height & 0xf) || (avctx->width & 0xf)) { - ctx->fill_y = av_malloc(DEFAULT_SLICE_MB_WIDTH << 9); - ctx->fill_u = av_malloc(DEFAULT_SLICE_MB_WIDTH << 8); - ctx->fill_v = av_malloc(DEFAULT_SLICE_MB_WIDTH << 8); + ctx->fill_y = av_malloc(4 * (DEFAULT_SLICE_MB_WIDTH << 8)); + if (!ctx->fill_y) + return AVERROR(ENOMEM); + ctx->fill_u = ctx->fill_y + (DEFAULT_SLICE_MB_WIDTH << 9); + ctx->fill_v = ctx->fill_u + (DEFAULT_SLICE_MB_WIDTH << 8); } if (avctx->profile == FF_PROFILE_UNKNOWN) { @@ -587,9 +579,7 @@ static av_cold int prores_encode_close(AVCodecContext *avctx) { ProresContext* ctx = avctx->priv_data; av_freep(&avctx->coded_frame); - av_free(ctx->fill_y); - av_free(ctx->fill_u); - av_free(ctx->fill_v); + av_freep(&ctx->fill_y); return 0; } @@ -602,8 +592,7 @@ AVCodec ff_prores_encoder = { .init = prores_encode_init, .close = prores_encode_close, .encode = prores_encode_frame, - .pix_fmts = (const enum PixelFormat[]){PIX_FMT_YUV422P10LE, PIX_FMT_NONE}, + .pix_fmts = (const enum PixelFormat[]){PIX_FMT_YUV422P10, PIX_FMT_NONE}, .long_name = NULL_IF_CONFIG_SMALL("Apple ProRes"), - .capabilities = 0, .profiles = profiles };