Skip to content

Instantly share code, notes, and snippets.

@jamiehodge
Created December 9, 2012 22:44
Show Gist options
  • Save jamiehodge/4247332 to your computer and use it in GitHub Desktop.
Save jamiehodge/4247332 to your computer and use it in GitHub Desktop.
Prores 4444 patch
diff --git a/libavcodec/proresenc_kostya.c b/libavcodec/proresenc_kostya.c
index 375dc52..4a27841 100644
--- a/libavcodec/proresenc_kostya.c
+++ b/libavcodec/proresenc_kostya.c
@@ -40,6 +40,7 @@ enum {
PRORES_PROFILE_LT,
PRORES_PROFILE_STANDARD,
PRORES_PROFILE_HQ,
+ PRORES_PROFILE_4444,
};
#define NUM_MB_LIMITS 4
@@ -57,7 +58,7 @@ static const struct prores_profile {
int max_quant;
int br_tab[NUM_MB_LIMITS];
uint8_t quant[64];
-} prores_profile_info[4] = {
+} prores_profile_info[5] = {
{
.full_name = "proxy",
.tag = MKTAG('a', 'p', 'c', 'o'),
@@ -125,8 +126,24 @@ static const struct prores_profile {
4, 4, 4, 4, 5, 5, 6, 7,
4, 4, 4, 4, 5, 6, 7, 7,
},
+ },
+ {
+ .full_name = "4444",
+ .tag = MKTAG('a', 'p', '4', 'h'),
+ .min_quant = 1, // TODO
+ .max_quant = 6, // TODO
+ .br_tab = { 2350, 1828, 1600, 1425 },
+ .quant = {
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ },
}
-// for 4444 profile bitrate numbers are { 2350, 1828, 1600, 1425 }
};
#define TRELLIS_WIDTH 16
@@ -171,7 +188,7 @@ typedef struct ProresContext {
static void get_slice_data(ProresContext *ctx, const uint16_t *src,
int linesize, int x, int y, int w, int h,
DCTELEM *blocks,
- int mbs_per_slice, int blocks_per_mb)
+ int mbs_per_slice, int blocks_per_mb, int is_chroma)
{
const uint16_t *esrc;
const int mb_width = 4 * blocks_per_mb;
@@ -189,38 +206,50 @@ static void get_slice_data(ProresContext *ctx, const uint16_t *src,
elinesize = linesize;
} else {
int bw, bh, pix;
- const int estride = 16 / sizeof(*ctx->emu_buf);
esrc = ctx->emu_buf;
- elinesize = 16;
+ elinesize = 16 * sizeof(*ctx->emu_buf);
bw = FFMIN(w - x, mb_width);
bh = FFMIN(h - y, 16);
for (j = 0; j < bh; j++) {
- memcpy(ctx->emu_buf + j * estride, src + j * linesize,
+ memcpy(ctx->emu_buf + j * 16,
+ (const uint8_t *)src + j * linesize,
bw * sizeof(*src));
- pix = ctx->emu_buf[j * estride + bw - 1];
+ pix = ctx->emu_buf[j * 16 + bw - 1];
for (k = bw; k < mb_width; k++)
- ctx->emu_buf[j * estride + k] = pix;
+ ctx->emu_buf[j * 16 + k] = pix;
}
for (; j < 16; j++)
- memcpy(ctx->emu_buf + j * estride,
- ctx->emu_buf + (bh - 1) * estride,
+ memcpy(ctx->emu_buf + j * 16,
+ ctx->emu_buf + (bh - 1) * 16,
mb_width * sizeof(*ctx->emu_buf));
}
- ctx->dsp.fdct(esrc, elinesize, blocks);
- blocks += 64;
- if (blocks_per_mb > 2) {
- ctx->dsp.fdct(src + 8, linesize, blocks);
- blocks += 64;
- }
- ctx->dsp.fdct(src + linesize * 4, linesize, blocks);
- blocks += 64;
- if (blocks_per_mb > 2) {
- ctx->dsp.fdct(src + linesize * 4 + 8, linesize, blocks);
- blocks += 64;
- }
+ if(!is_chroma) { /* luma */
+ ctx->dsp.fdct(esrc, elinesize, blocks);
+ blocks += 64;
+ ctx->dsp.fdct(esrc + 8, elinesize, blocks);
+ blocks += 64;
+ ctx->dsp.fdct(esrc + elinesize * 4, elinesize, blocks);
+ blocks += 64;
+ ctx->dsp.fdct(esrc + elinesize * 4 + 8, elinesize, blocks);
+ blocks += 64;
+ } else if(blocks_per_mb == 2) { /* 4:2:2 chroma */
+ ctx->dsp.fdct(esrc, elinesize, blocks);
+ blocks += 64;
+ ctx->dsp.fdct(esrc + elinesize * 4, elinesize, blocks);
+ blocks += 64;
+ } else { /* 4:4:4 chroma */
+ ctx->dsp.fdct(esrc, elinesize, blocks);
+ blocks += 64;
+ ctx->dsp.fdct(esrc + elinesize * 4, elinesize, blocks);
+ blocks += 64;
+ ctx->dsp.fdct(esrc + 8, elinesize, blocks);
+ blocks += 64;
+ ctx->dsp.fdct(esrc + elinesize * 4 + 8, elinesize, blocks);
+ blocks += 64;
+ }
x += mb_width;
}
@@ -366,14 +395,13 @@ static int encode_slice(AVCodecContext *avctx, const AVFrame *pic,
for (i = 0; i < ctx->num_planes; i++) {
is_chroma = (i == 1 || i == 2);
plane_factor = slice_width_factor + 2;
- if (is_chroma)
- plane_factor += ctx->chroma_factor - 3;
if (!is_chroma || ctx->chroma_factor == CFACTOR_Y444) {
xp = x << 4;
yp = y << 4;
num_cblocks = 4;
pwidth = avctx->width;
} else {
+ plane_factor += ctx->chroma_factor - 3;
xp = x << 3;
yp = y << 4;
num_cblocks = 2;
@@ -383,7 +411,7 @@ static int encode_slice(AVCodecContext *avctx, const AVFrame *pic,
get_slice_data(ctx, src, pic->linesize[i], xp, yp,
pwidth, avctx->height, ctx->blocks[0],
- mbs_per_slice, num_cblocks);
+ mbs_per_slice, num_cblocks, is_chroma);
sizes[i] = encode_slice_plane(ctx, pb, src, pic->linesize[i],
mbs_per_slice, ctx->blocks[0],
num_cblocks, plane_factor,
@@ -522,14 +550,13 @@ static int find_slice_quant(AVCodecContext *avctx, const AVFrame *pic,
for (i = 0; i < ctx->num_planes; i++) {
is_chroma[i] = (i == 1 || i == 2);
plane_factor[i] = slice_width_factor + 2;
- if (is_chroma[i])
- plane_factor[i] += ctx->chroma_factor - 3;
if (!is_chroma[i] || ctx->chroma_factor == CFACTOR_Y444) {
xp = x << 4;
yp = y << 4;
num_cblocks[i] = 4;
pwidth = avctx->width;
} else {
+ plane_factor[i] += ctx->chroma_factor - 3;
xp = x << 3;
yp = y << 4;
num_cblocks[i] = 2;
@@ -539,7 +566,7 @@ static int find_slice_quant(AVCodecContext *avctx, const AVFrame *pic,
get_slice_data(ctx, src, pic->linesize[i], xp, yp,
pwidth, avctx->height, ctx->blocks[i],
- mbs_per_slice, num_cblocks[i]);
+ mbs_per_slice, num_cblocks[i], is_chroma[i]);
}
for (q = min_quant; q < max_quant + 2; q++) {
@@ -676,9 +703,9 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
bytestream_put_be16 (&buf, avctx->height);
bytestream_put_byte (&buf, ctx->chroma_factor << 6); // frame flags
bytestream_put_byte (&buf, 0); // reserved
- bytestream_put_byte (&buf, 0); // primaries
- bytestream_put_byte (&buf, 0); // transfer function
- bytestream_put_byte (&buf, 6); // colour matrix - ITU-R BT.601-4
+ bytestream_put_byte (&buf, avctx->color_primaries);
+ bytestream_put_byte (&buf, avctx->color_trc);
+ bytestream_put_byte (&buf, avctx->colorspace);
bytestream_put_byte (&buf, 0x40); // source format and alpha information
bytestream_put_byte (&buf, 0); // reserved
bytestream_put_byte (&buf, 0x03); // matrix flags - both matrices are present
@@ -855,7 +882,7 @@ static const AVOption options[] = {
AV_OPT_TYPE_INT, { 8 }, 1, MAX_MBS_PER_SLICE, VE },
{ "profile", NULL, OFFSET(profile), AV_OPT_TYPE_INT,
{ PRORES_PROFILE_STANDARD },
- PRORES_PROFILE_PROXY, PRORES_PROFILE_HQ, VE, "profile" },
+ PRORES_PROFILE_PROXY, PRORES_PROFILE_4444, VE, "profile" },
{ "proxy", NULL, 0, AV_OPT_TYPE_CONST, { PRORES_PROFILE_PROXY },
0, 0, VE, "profile" },
{ "lt", NULL, 0, AV_OPT_TYPE_CONST, { PRORES_PROFILE_LT },
@@ -864,6 +891,8 @@ static const AVOption options[] = {
0, 0, VE, "profile" },
{ "hq", NULL, 0, AV_OPT_TYPE_CONST, { PRORES_PROFILE_HQ },
0, 0, VE, "profile" },
+ { "4444", NULL, 0, AV_OPT_TYPE_CONST, { PRORES_PROFILE_4444 },
+ 0, 0, VE, "profile" },
{ NULL }
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment