mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2025-12-13 10:30:05 +01:00
Merge remote-tracking branch 'mans/dnxhd'
* mans/dnxhd:
dnxhddec: cache luma/chroma_weight*qscale tables for last qscale
dnxhddec: merge ac_{index,run}_flags
dnxhddec: store 2*level+1 in ac_level tables
dnxhddec: rearrange decode_dct_block loop
Merged-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
@@ -49,6 +49,9 @@ typedef struct DNXHDContext {
|
||||
int bit_depth; // 8, 10 or 0 if not initialized at all.
|
||||
void (*decode_dct_block)(struct DNXHDContext *ctx, DCTELEM *block,
|
||||
int n, int qscale);
|
||||
int last_qscale;
|
||||
int luma_scale[64];
|
||||
int chroma_scale[64];
|
||||
} DNXHDContext;
|
||||
|
||||
#define DNXHD_VLC_BITS 9
|
||||
@@ -186,16 +189,22 @@ static av_always_inline void dnxhd_decode_dct_block(DNXHDContext *ctx,
|
||||
int level_bias,
|
||||
int level_shift)
|
||||
{
|
||||
int i, j, index1, index2, len;
|
||||
int i, j, index1, index2, len, flags;
|
||||
int level, component, sign;
|
||||
const int *scale;
|
||||
const uint8_t *weight_matrix;
|
||||
const uint8_t *ac_level = ctx->cid_table->ac_level;
|
||||
const uint8_t *ac_flags = ctx->cid_table->ac_flags;
|
||||
const int eob_index = ctx->cid_table->eob_index;
|
||||
OPEN_READER(bs, &ctx->gb);
|
||||
|
||||
if (n&2) {
|
||||
component = 1 + (n&1);
|
||||
scale = ctx->chroma_scale;
|
||||
weight_matrix = ctx->cid_table->chroma_weight;
|
||||
} else {
|
||||
component = 0;
|
||||
scale = ctx->luma_scale;
|
||||
weight_matrix = ctx->cid_table->luma_weight;
|
||||
}
|
||||
|
||||
@@ -211,33 +220,32 @@ static av_always_inline void dnxhd_decode_dct_block(DNXHDContext *ctx,
|
||||
block[0] = ctx->last_dc[component];
|
||||
//av_log(ctx->avctx, AV_LOG_DEBUG, "dc %d\n", block[0]);
|
||||
|
||||
for (i = 1; ; i++) {
|
||||
UPDATE_CACHE(bs, &ctx->gb);
|
||||
GET_VLC(index1, bs, &ctx->gb, ctx->ac_vlc.table,
|
||||
DNXHD_VLC_BITS, 2);
|
||||
//av_log(ctx->avctx, AV_LOG_DEBUG, "index %d\n", index1);
|
||||
level = ctx->cid_table->ac_level[index1];
|
||||
if (!level) { /* EOB */
|
||||
//av_log(ctx->avctx, AV_LOG_DEBUG, "EOB\n");
|
||||
break;
|
||||
}
|
||||
i = 0;
|
||||
|
||||
UPDATE_CACHE(bs, &ctx->gb);
|
||||
GET_VLC(index1, bs, &ctx->gb, ctx->ac_vlc.table,
|
||||
DNXHD_VLC_BITS, 2);
|
||||
|
||||
while (index1 != eob_index) {
|
||||
level = ac_level[index1];
|
||||
flags = ac_flags[index1];
|
||||
|
||||
sign = SHOW_SBITS(bs, &ctx->gb, 1);
|
||||
SKIP_BITS(bs, &ctx->gb, 1);
|
||||
|
||||
if (ctx->cid_table->ac_index_flag[index1]) {
|
||||
level += SHOW_UBITS(bs, &ctx->gb, index_bits) << 6;
|
||||
if (flags & 1) {
|
||||
level += SHOW_UBITS(bs, &ctx->gb, index_bits) << 7;
|
||||
SKIP_BITS(bs, &ctx->gb, index_bits);
|
||||
}
|
||||
|
||||
if (ctx->cid_table->ac_run_flag[index1]) {
|
||||
if (flags & 2) {
|
||||
UPDATE_CACHE(bs, &ctx->gb);
|
||||
GET_VLC(index2, bs, &ctx->gb, ctx->run_vlc.table,
|
||||
DNXHD_VLC_BITS, 2);
|
||||
i += ctx->cid_table->run[index2];
|
||||
}
|
||||
|
||||
if (i > 63) {
|
||||
if (++i > 63) {
|
||||
av_log(ctx->avctx, AV_LOG_ERROR, "ac tex damaged %d, %d\n", n, i);
|
||||
break;
|
||||
}
|
||||
@@ -245,13 +253,17 @@ static av_always_inline void dnxhd_decode_dct_block(DNXHDContext *ctx,
|
||||
j = ctx->scantable.permutated[i];
|
||||
//av_log(ctx->avctx, AV_LOG_DEBUG, "j %d\n", j);
|
||||
//av_log(ctx->avctx, AV_LOG_DEBUG, "level %d, weight %d\n", level, weight_matrix[i]);
|
||||
level = (2*level+1) * qscale * weight_matrix[i];
|
||||
level *= scale[i];
|
||||
if (level_bias < 32 || weight_matrix[i] != level_bias)
|
||||
level += level_bias;
|
||||
level >>= level_shift;
|
||||
|
||||
//av_log(NULL, AV_LOG_DEBUG, "i %d, j %d, end level %d\n", i, j, level);
|
||||
block[j] = (level^sign) - sign;
|
||||
|
||||
UPDATE_CACHE(bs, &ctx->gb);
|
||||
GET_VLC(index1, bs, &ctx->gb, ctx->ac_vlc.table,
|
||||
DNXHD_VLC_BITS, 2);
|
||||
}
|
||||
|
||||
CLOSE_READER(bs, &ctx->gb);
|
||||
@@ -282,6 +294,14 @@ static int dnxhd_decode_macroblock(DNXHDContext *ctx, int x, int y)
|
||||
skip_bits1(&ctx->gb);
|
||||
//av_log(ctx->avctx, AV_LOG_DEBUG, "qscale %d\n", qscale);
|
||||
|
||||
if (qscale != ctx->last_qscale) {
|
||||
for (i = 0; i < 64; i++) {
|
||||
ctx->luma_scale[i] = qscale * ctx->cid_table->luma_weight[i];
|
||||
ctx->chroma_scale[i] = qscale * ctx->cid_table->chroma_weight[i];
|
||||
}
|
||||
ctx->last_qscale = qscale;
|
||||
}
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
ctx->dsp.clear_block(ctx->blocks[i]);
|
||||
ctx->decode_dct_block(ctx, ctx->blocks[i], i, qscale);
|
||||
|
||||
Reference in New Issue
Block a user