From 2aaf32f52f25ac7b3b18606a00953c0aa8e2e7bd Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sun, 25 Sep 2011 06:46:39 +0200 Subject: [PATCH] mpegvideo: support encoding with chroma intra tables that differ from luma. Signed-off-by: Michael Niedermayer --- libavcodec/bfin/mpegvideo_bfin.c | 9 +++++++-- libavcodec/dnxhdenc.c | 15 ++++++++------- libavcodec/mpegvideo.c | 6 ++++++ libavcodec/mpegvideo.h | 2 ++ libavcodec/mpegvideo_enc.c | 11 +++++++++-- libavcodec/ppc/mpegvideo_altivec.c | 9 +++++++-- libavcodec/x86/mpegvideo_mmx_template.c | 11 +++++++---- 7 files changed, 46 insertions(+), 17 deletions(-) diff --git a/libavcodec/bfin/mpegvideo_bfin.c b/libavcodec/bfin/mpegvideo_bfin.c index 0373e22ff8..996290a52d 100644 --- a/libavcodec/bfin/mpegvideo_bfin.c +++ b/libavcodec/bfin/mpegvideo_bfin.c @@ -61,8 +61,13 @@ static int dct_quantize_bfin (MpegEncContext *s, dc = block[0] = (block[0] + (q >> 1)) / q; start_i = 1; last_non_zero = 0; - bias = s->q_intra_matrix16[qscale][1]; - qmat = s->q_intra_matrix16[qscale][0]; + if(n<4){ + 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 { start_i = 0; diff --git a/libavcodec/dnxhdenc.c b/libavcodec/dnxhdenc.c index d6506a2c7f..1461222110 100644 --- a/libavcodec/dnxhdenc.c +++ b/libavcodec/dnxhdenc.c @@ -77,7 +77,7 @@ static int dnxhd_10bit_dct_quantize(MpegEncContext *ctx, DCTELEM *block, int n, int qscale, int *overflow) { 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 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; fail: 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) { if (i&2) { - ctx->m.q_intra_matrix16 = ctx->qmatrix_c16; - ctx->m.q_intra_matrix = ctx->qmatrix_c; return 1 + (i&1); } else { - ctx->m.q_intra_matrix16 = ctx->qmatrix_l16; - ctx->m.q_intra_matrix = ctx->qmatrix_l; 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); 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); 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]; int last_index, overflow; 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; dnxhd_encode_block(ctx, block, last_index, n); //STOP_TIMER("encode_block"); diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c index da06bee28a..9dfd26e5a3 100644 --- a/libavcodec/mpegvideo.c +++ b/libavcodec/mpegvideo.c @@ -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->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_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->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->mb_index2xy); 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_inter_matrix); av_freep(&s->q_intra_matrix16); diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h index 39efc1e3c1..731bda3bab 100644 --- a/libavcodec/mpegvideo.h +++ b/libavcodec/mpegvideo.h @@ -448,9 +448,11 @@ typedef struct MpegEncContext { /** precomputed matrix (combine qscale and DCT renorm) */ int (*q_intra_matrix)[64]; + int (*q_chroma_intra_matrix)[64]; int (*q_inter_matrix)[64]; /** 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_chroma_intra_matrix16)[2][64]; uint16_t (*q_inter_matrix16)[2][64]; /* noise reduction */ diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c index 14a94154ed..ab27e4626d 100644 --- a/libavcodec/mpegvideo_enc.c +++ b/libavcodec/mpegvideo_enc.c @@ -2825,6 +2825,13 @@ static int encode_picture(MpegEncContext *s, int picture_number) 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 for(i=1; ithread_context[i], s); @@ -3091,7 +3098,7 @@ static int dct_quantize_trellis_c(MpegEncContext *s, block[0] = (block[0] + (q >> 1)) / q; start_i = 1; 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) bias= 1<<(QMAT_SHIFT-1); length = s->intra_ac_vlc_length; @@ -3762,7 +3769,7 @@ int dct_quantize_c(MpegEncContext *s, block[0] = (block[0] + (q >> 1)) / q; start_i = 1; 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); } else { start_i = 0; diff --git a/libavcodec/ppc/mpegvideo_altivec.c b/libavcodec/ppc/mpegvideo_altivec.c index 465971653d..0ba532ec26 100644 --- a/libavcodec/ppc/mpegvideo_altivec.c +++ b/libavcodec/ppc/mpegvideo_altivec.c @@ -267,8 +267,13 @@ static int dct_quantize_altivec(MpegEncContext* s, baseVector = vec_cts(vec_splat(row0, 0), 0); vec_ste(baseVector, 0, &oldBaseValue); - qmat = (vector signed int*)s->q_intra_matrix[qscale]; - biasAddr = &(s->intra_quant_bias); + if(n<4){ + 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 { qmat = (vector signed int*)s->q_inter_matrix[qscale]; biasAddr = &(s->inter_quant_bias); diff --git a/libavcodec/x86/mpegvideo_mmx_template.c b/libavcodec/x86/mpegvideo_mmx_template.c index de6a4724b6..6569ba41eb 100644 --- a/libavcodec/x86/mpegvideo_mmx_template.c +++ b/libavcodec/x86/mpegvideo_mmx_template.c @@ -110,10 +110,15 @@ static int RENAME(dct_quantize)(MpegEncContext *s, if (s->mb_intra) { int dummy; - if (n < 4) + if (n < 4){ 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; + bias = s->q_chroma_intra_matrix16[qscale][1]; + qmat = s->q_chroma_intra_matrix16[qscale][0]; + } /* note: block[0] is assumed to be positive */ if (!s->h263_aic) { __asm__ volatile ( @@ -128,8 +133,6 @@ static int RENAME(dct_quantize)(MpegEncContext *s, block[0]=0; //avoid fake overflow // temp_block[0] = (block[0] + (q >> 1)) / q; last_non_zero_p1 = 1; - bias = s->q_intra_matrix16[qscale][1]; - qmat = s->q_intra_matrix16[qscale][0]; } else { last_non_zero_p1 = 0; bias = s->q_inter_matrix16[qscale][1];