]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/dnxhddec.c
ljpegdec: fix point transform injection.
[ffmpeg] / libavcodec / dnxhddec.c
index ad56aabd0ede626b9b938465a96838bf95db5d2c..2548614e9066433f2c0c8a56acfb9eeb5f6e7d5f 100644 (file)
@@ -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);