#include "avcodec.h"
#include "put_bits.h"
+#include "bytestream.h"
#include "dsputil.h"
#define DEFAULT_SLICE_MB_WIDTH 8
unsigned* y_data_size, unsigned* u_data_size, unsigned* v_data_size,
int qp)
{
- ProresContext* ctx = (ProresContext*) avctx->priv_data;
+ ProresContext* ctx = avctx->priv_data;
*y_data_size = encode_slice_plane(avctx, mb_count, dest_y, luma_stride,
buf, data_size, ctx->qmat_luma[qp - 1], 0);
int hdr_size = 6, slice_size;
uint8_t *dest_y, *dest_u, *dest_v;
unsigned y_data_size = 0, u_data_size = 0, v_data_size = 0;
- ProresContext* ctx = (ProresContext*)avctx->priv_data;
+ ProresContext* ctx = avctx->priv_data;
int tgt_bits = (mb_count * bitrate_table[avctx->profile]) >> 2;
int low_bytes = (tgt_bits - (tgt_bits >> 3)) >> 3; // 12% bitrate fluctuation
int high_bytes = (tgt_bits + (tgt_bits >> 3)) >> 3;
{
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;
+ 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) {
}
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;
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;
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;
}
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;
}
static av_cold int prores_encode_init(AVCodecContext *avctx)
{
int i;
- ProresContext* ctx = (ProresContext*)avctx->priv_data;
+ 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;
}
return -1;
}
- memset(ctx, 0, sizeof(ProresContext));
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) {
static av_cold int prores_encode_close(AVCodecContext *avctx)
{
- ProresContext* ctx = (ProresContext*)avctx->priv_data;
+ 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;
}
.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