Created
December 9, 2012 22:44
-
-
Save jamiehodge/4247332 to your computer and use it in GitHub Desktop.
Prores 4444 patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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