You've already forked FFmpeg
mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-08-10 06:10:52 +02:00
mpegvideo: support encoding with chroma intra tables that differ from luma.
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
@@ -61,8 +61,13 @@ static int dct_quantize_bfin (MpegEncContext *s,
|
|||||||
dc = block[0] = (block[0] + (q >> 1)) / q;
|
dc = block[0] = (block[0] + (q >> 1)) / q;
|
||||||
start_i = 1;
|
start_i = 1;
|
||||||
last_non_zero = 0;
|
last_non_zero = 0;
|
||||||
bias = s->q_intra_matrix16[qscale][1];
|
if(n<4){
|
||||||
qmat = s->q_intra_matrix16[qscale][0];
|
bias = s->q_intra_matrix16[qscale][1];
|
||||||
|
qmat = s->q_intra_matrix16[qscale][0];
|
||||||
|
}else{
|
||||||
|
bias = s->q_chroma_intra_matrix16[qscale][1];
|
||||||
|
qmat = s->q_chroma_intra_matrix16[qscale][0];
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
start_i = 0;
|
start_i = 0;
|
||||||
|
@@ -77,7 +77,7 @@ static int dnxhd_10bit_dct_quantize(MpegEncContext *ctx, DCTELEM *block,
|
|||||||
int n, int qscale, int *overflow)
|
int n, int qscale, int *overflow)
|
||||||
{
|
{
|
||||||
const uint8_t *scantable= ctx->intra_scantable.scantable;
|
const uint8_t *scantable= ctx->intra_scantable.scantable;
|
||||||
const int *qmat = ctx->q_intra_matrix[qscale];
|
const int *qmat = n<4 ? ctx->q_intra_matrix[qscale] : ctx->q_chroma_intra_matrix[qscale];
|
||||||
int last_non_zero = 0;
|
int last_non_zero = 0;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@@ -208,6 +208,11 @@ static int dnxhd_init_qmat(DNXHDEncContext *ctx, int lbias, int cbias)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ctx->m.q_chroma_intra_matrix16 = ctx->qmatrix_c16;
|
||||||
|
ctx->m.q_chroma_intra_matrix = ctx->qmatrix_c;
|
||||||
|
ctx->m.q_intra_matrix16 = ctx->qmatrix_l16;
|
||||||
|
ctx->m.q_intra_matrix = ctx->qmatrix_l;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
fail:
|
fail:
|
||||||
return -1;
|
return -1;
|
||||||
@@ -498,12 +503,8 @@ static av_always_inline void dnxhd_get_blocks(DNXHDEncContext *ctx, int mb_x, in
|
|||||||
static av_always_inline int dnxhd_switch_matrix(DNXHDEncContext *ctx, int i)
|
static av_always_inline int dnxhd_switch_matrix(DNXHDEncContext *ctx, int i)
|
||||||
{
|
{
|
||||||
if (i&2) {
|
if (i&2) {
|
||||||
ctx->m.q_intra_matrix16 = ctx->qmatrix_c16;
|
|
||||||
ctx->m.q_intra_matrix = ctx->qmatrix_c;
|
|
||||||
return 1 + (i&1);
|
return 1 + (i&1);
|
||||||
} else {
|
} else {
|
||||||
ctx->m.q_intra_matrix16 = ctx->qmatrix_l16;
|
|
||||||
ctx->m.q_intra_matrix = ctx->qmatrix_l;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -535,7 +536,7 @@ static int dnxhd_calc_bits_thread(AVCodecContext *avctx, void *arg, int jobnr, i
|
|||||||
int n = dnxhd_switch_matrix(ctx, i);
|
int n = dnxhd_switch_matrix(ctx, i);
|
||||||
|
|
||||||
memcpy(block, src_block, 64*sizeof(*block));
|
memcpy(block, src_block, 64*sizeof(*block));
|
||||||
last_index = ctx->m.dct_quantize(&ctx->m, block, i, qscale, &overflow);
|
last_index = ctx->m.dct_quantize(&ctx->m, block, 4&(2*i), qscale, &overflow);
|
||||||
ac_bits += dnxhd_calc_ac_bits(ctx, block, last_index);
|
ac_bits += dnxhd_calc_ac_bits(ctx, block, last_index);
|
||||||
|
|
||||||
diff = block[0] - ctx->m.last_dc[n];
|
diff = block[0] - ctx->m.last_dc[n];
|
||||||
@@ -582,7 +583,7 @@ static int dnxhd_encode_thread(AVCodecContext *avctx, void *arg, int jobnr, int
|
|||||||
DCTELEM *block = ctx->blocks[i];
|
DCTELEM *block = ctx->blocks[i];
|
||||||
int last_index, overflow;
|
int last_index, overflow;
|
||||||
int n = dnxhd_switch_matrix(ctx, i);
|
int n = dnxhd_switch_matrix(ctx, i);
|
||||||
last_index = ctx->m.dct_quantize(&ctx->m, block, i, qscale, &overflow);
|
last_index = ctx->m.dct_quantize(&ctx->m, block, 4&(2*i), qscale, &overflow);
|
||||||
//START_TIMER;
|
//START_TIMER;
|
||||||
dnxhd_encode_block(ctx, block, last_index, n);
|
dnxhd_encode_block(ctx, block, last_index, n);
|
||||||
//STOP_TIMER("encode_block");
|
//STOP_TIMER("encode_block");
|
||||||
|
@@ -687,8 +687,10 @@ av_cold int MPV_common_init(MpegEncContext *s)
|
|||||||
FF_ALLOCZ_OR_GOTO(s->avctx, s->lambda_table, mb_array_size * sizeof(int), fail)
|
FF_ALLOCZ_OR_GOTO(s->avctx, s->lambda_table, mb_array_size * sizeof(int), fail)
|
||||||
|
|
||||||
FF_ALLOCZ_OR_GOTO(s->avctx, s->q_intra_matrix , 64*32 * sizeof(int), fail)
|
FF_ALLOCZ_OR_GOTO(s->avctx, s->q_intra_matrix , 64*32 * sizeof(int), fail)
|
||||||
|
FF_ALLOCZ_OR_GOTO(s->avctx, s->q_chroma_intra_matrix , 64*32 * sizeof(int), fail)
|
||||||
FF_ALLOCZ_OR_GOTO(s->avctx, s->q_inter_matrix , 64*32 * sizeof(int), fail)
|
FF_ALLOCZ_OR_GOTO(s->avctx, s->q_inter_matrix , 64*32 * sizeof(int), fail)
|
||||||
FF_ALLOCZ_OR_GOTO(s->avctx, s->q_intra_matrix16, 64*32*2 * sizeof(uint16_t), fail)
|
FF_ALLOCZ_OR_GOTO(s->avctx, s->q_intra_matrix16, 64*32*2 * sizeof(uint16_t), fail)
|
||||||
|
FF_ALLOCZ_OR_GOTO(s->avctx, s->q_chroma_intra_matrix16, 64*32*2 * sizeof(uint16_t), fail)
|
||||||
FF_ALLOCZ_OR_GOTO(s->avctx, s->q_inter_matrix16, 64*32*2 * sizeof(uint16_t), fail)
|
FF_ALLOCZ_OR_GOTO(s->avctx, s->q_inter_matrix16, 64*32*2 * sizeof(uint16_t), fail)
|
||||||
FF_ALLOCZ_OR_GOTO(s->avctx, s->input_picture, MAX_PICTURE_COUNT * sizeof(Picture*), fail)
|
FF_ALLOCZ_OR_GOTO(s->avctx, s->input_picture, MAX_PICTURE_COUNT * sizeof(Picture*), fail)
|
||||||
FF_ALLOCZ_OR_GOTO(s->avctx, s->reordered_input_picture, MAX_PICTURE_COUNT * sizeof(Picture*), fail)
|
FF_ALLOCZ_OR_GOTO(s->avctx, s->reordered_input_picture, MAX_PICTURE_COUNT * sizeof(Picture*), fail)
|
||||||
@@ -846,6 +848,10 @@ void MPV_common_end(MpegEncContext *s)
|
|||||||
av_freep(&s->error_status_table);
|
av_freep(&s->error_status_table);
|
||||||
av_freep(&s->mb_index2xy);
|
av_freep(&s->mb_index2xy);
|
||||||
av_freep(&s->lambda_table);
|
av_freep(&s->lambda_table);
|
||||||
|
if(s->q_chroma_intra_matrix != s->q_intra_matrix ) av_freep(&s->q_chroma_intra_matrix);
|
||||||
|
if(s->q_chroma_intra_matrix16 != s->q_intra_matrix16) av_freep(&s->q_chroma_intra_matrix16);
|
||||||
|
s->q_chroma_intra_matrix= NULL;
|
||||||
|
s->q_chroma_intra_matrix16= NULL;
|
||||||
av_freep(&s->q_intra_matrix);
|
av_freep(&s->q_intra_matrix);
|
||||||
av_freep(&s->q_inter_matrix);
|
av_freep(&s->q_inter_matrix);
|
||||||
av_freep(&s->q_intra_matrix16);
|
av_freep(&s->q_intra_matrix16);
|
||||||
|
@@ -448,9 +448,11 @@ typedef struct MpegEncContext {
|
|||||||
|
|
||||||
/** precomputed matrix (combine qscale and DCT renorm) */
|
/** precomputed matrix (combine qscale and DCT renorm) */
|
||||||
int (*q_intra_matrix)[64];
|
int (*q_intra_matrix)[64];
|
||||||
|
int (*q_chroma_intra_matrix)[64];
|
||||||
int (*q_inter_matrix)[64];
|
int (*q_inter_matrix)[64];
|
||||||
/** identical to the above but for MMX & these are not permutated, second 64 entries are bias*/
|
/** identical to the above but for MMX & these are not permutated, second 64 entries are bias*/
|
||||||
uint16_t (*q_intra_matrix16)[2][64];
|
uint16_t (*q_intra_matrix16)[2][64];
|
||||||
|
uint16_t (*q_chroma_intra_matrix16)[2][64];
|
||||||
uint16_t (*q_inter_matrix16)[2][64];
|
uint16_t (*q_inter_matrix16)[2][64];
|
||||||
|
|
||||||
/* noise reduction */
|
/* noise reduction */
|
||||||
|
@@ -2825,6 +2825,13 @@ static int encode_picture(MpegEncContext *s, int picture_number)
|
|||||||
update_qscale(s);
|
update_qscale(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(s->codec_id != CODEC_ID_AMV){
|
||||||
|
if(s->q_chroma_intra_matrix != s->q_intra_matrix ) av_freep(&s->q_chroma_intra_matrix);
|
||||||
|
if(s->q_chroma_intra_matrix16 != s->q_intra_matrix16) av_freep(&s->q_chroma_intra_matrix16);
|
||||||
|
s->q_chroma_intra_matrix = s->q_intra_matrix;
|
||||||
|
s->q_chroma_intra_matrix16 = s->q_intra_matrix16;
|
||||||
|
}
|
||||||
|
|
||||||
s->mb_intra=0; //for the rate distortion & bit compare functions
|
s->mb_intra=0; //for the rate distortion & bit compare functions
|
||||||
for(i=1; i<context_count; i++){
|
for(i=1; i<context_count; i++){
|
||||||
ff_update_duplicate_context(s->thread_context[i], s);
|
ff_update_duplicate_context(s->thread_context[i], s);
|
||||||
@@ -3091,7 +3098,7 @@ static int dct_quantize_trellis_c(MpegEncContext *s,
|
|||||||
block[0] = (block[0] + (q >> 1)) / q;
|
block[0] = (block[0] + (q >> 1)) / q;
|
||||||
start_i = 1;
|
start_i = 1;
|
||||||
last_non_zero = 0;
|
last_non_zero = 0;
|
||||||
qmat = s->q_intra_matrix[qscale];
|
qmat = n < 4 ? s->q_intra_matrix[qscale] : s->q_chroma_intra_matrix[qscale];
|
||||||
if(s->mpeg_quant || s->out_format == FMT_MPEG1)
|
if(s->mpeg_quant || s->out_format == FMT_MPEG1)
|
||||||
bias= 1<<(QMAT_SHIFT-1);
|
bias= 1<<(QMAT_SHIFT-1);
|
||||||
length = s->intra_ac_vlc_length;
|
length = s->intra_ac_vlc_length;
|
||||||
@@ -3762,7 +3769,7 @@ int dct_quantize_c(MpegEncContext *s,
|
|||||||
block[0] = (block[0] + (q >> 1)) / q;
|
block[0] = (block[0] + (q >> 1)) / q;
|
||||||
start_i = 1;
|
start_i = 1;
|
||||||
last_non_zero = 0;
|
last_non_zero = 0;
|
||||||
qmat = s->q_intra_matrix[qscale];
|
qmat = n < 4 ? s->q_intra_matrix[qscale] : s->q_chroma_intra_matrix[qscale];
|
||||||
bias= s->intra_quant_bias<<(QMAT_SHIFT - QUANT_BIAS_SHIFT);
|
bias= s->intra_quant_bias<<(QMAT_SHIFT - QUANT_BIAS_SHIFT);
|
||||||
} else {
|
} else {
|
||||||
start_i = 0;
|
start_i = 0;
|
||||||
|
@@ -267,8 +267,13 @@ static int dct_quantize_altivec(MpegEncContext* s,
|
|||||||
baseVector = vec_cts(vec_splat(row0, 0), 0);
|
baseVector = vec_cts(vec_splat(row0, 0), 0);
|
||||||
vec_ste(baseVector, 0, &oldBaseValue);
|
vec_ste(baseVector, 0, &oldBaseValue);
|
||||||
|
|
||||||
qmat = (vector signed int*)s->q_intra_matrix[qscale];
|
if(n<4){
|
||||||
biasAddr = &(s->intra_quant_bias);
|
qmat = (vector signed int*)s->q_intra_matrix[qscale];
|
||||||
|
biasAddr = &(s->intra_quant_bias);
|
||||||
|
}else{
|
||||||
|
qmat = (vector signed int*)s->q_chroma_intra_matrix[qscale];
|
||||||
|
biasAddr = &(s->intra_quant_bias);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
qmat = (vector signed int*)s->q_inter_matrix[qscale];
|
qmat = (vector signed int*)s->q_inter_matrix[qscale];
|
||||||
biasAddr = &(s->inter_quant_bias);
|
biasAddr = &(s->inter_quant_bias);
|
||||||
|
@@ -110,10 +110,15 @@ static int RENAME(dct_quantize)(MpegEncContext *s,
|
|||||||
|
|
||||||
if (s->mb_intra) {
|
if (s->mb_intra) {
|
||||||
int dummy;
|
int dummy;
|
||||||
if (n < 4)
|
if (n < 4){
|
||||||
q = s->y_dc_scale;
|
q = s->y_dc_scale;
|
||||||
else
|
bias = s->q_intra_matrix16[qscale][1];
|
||||||
|
qmat = s->q_intra_matrix16[qscale][0];
|
||||||
|
}else{
|
||||||
q = s->c_dc_scale;
|
q = s->c_dc_scale;
|
||||||
|
bias = s->q_chroma_intra_matrix16[qscale][1];
|
||||||
|
qmat = s->q_chroma_intra_matrix16[qscale][0];
|
||||||
|
}
|
||||||
/* note: block[0] is assumed to be positive */
|
/* note: block[0] is assumed to be positive */
|
||||||
if (!s->h263_aic) {
|
if (!s->h263_aic) {
|
||||||
__asm__ volatile (
|
__asm__ volatile (
|
||||||
@@ -128,8 +133,6 @@ static int RENAME(dct_quantize)(MpegEncContext *s,
|
|||||||
block[0]=0; //avoid fake overflow
|
block[0]=0; //avoid fake overflow
|
||||||
// temp_block[0] = (block[0] + (q >> 1)) / q;
|
// temp_block[0] = (block[0] + (q >> 1)) / q;
|
||||||
last_non_zero_p1 = 1;
|
last_non_zero_p1 = 1;
|
||||||
bias = s->q_intra_matrix16[qscale][1];
|
|
||||||
qmat = s->q_intra_matrix16[qscale][0];
|
|
||||||
} else {
|
} else {
|
||||||
last_non_zero_p1 = 0;
|
last_non_zero_p1 = 0;
|
||||||
bias = s->q_inter_matrix16[qscale][1];
|
bias = s->q_inter_matrix16[qscale][1];
|
||||||
|
Reference in New Issue
Block a user