[FFmpeg-cvslog] dnxhddec: decode and use interlace mb flag

Christophe Gisquet git at videolan.org
Fri Sep 25 20:44:03 CEST 2015


ffmpeg | branch: master | Christophe Gisquet <christophe.gisquet at gmail.com> | Fri Sep 25 18:57:17 2015 +0200| [2801a1352dc8682b028e53880f9847fcb2116947] | committer: Michael Niedermayer

dnxhddec: decode and use interlace mb flag

This bit is 1 in some samples, and seems to coincide with interlaced
mbs and CID1260. 2008 specs do not know about it, and maintain qscale
is 11 bits. This looks oversized, but may help larger bitdepths.

Currently, it leads to an obviously incorrect qscale value, meaning
its syntax is shifted by 1. However, reading 11 bits also leads to
obviously incorrect decoding: qscale seems to be 10 bits.

However, as most profiles still have 11bits qscale, the feature is
restricted to the CID1260 profile.

The encoder writes 12 bits of syntax, last and first bits always 0,
which is now somewhat inconsistent with the decoder, but ends up with
the same effect (progressive + reserved bit).

Partially fixes ticket #4876.

Signed-off-by: Michael Niedermayer <michael at niedermayer.cc>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=2801a1352dc8682b028e53880f9847fcb2116947
---

 libavcodec/dnxhddec.c |   15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/libavcodec/dnxhddec.c b/libavcodec/dnxhddec.c
index 1034d89..4a42360 100644
--- a/libavcodec/dnxhddec.c
+++ b/libavcodec/dnxhddec.c
@@ -349,7 +349,12 @@ static int dnxhd_decode_macroblock(DNXHDContext *ctx, AVFrame *frame,
     uint8_t *dest_y, *dest_u, *dest_v;
     int dct_y_offset, dct_x_offset;
     int qscale, i;
+    int interlaced_mb = 0;
 
+    if (ctx->cid_table->cid == 1260) {
+        interlaced_mb = get_bits1(&ctx->gb);
+        qscale = get_bits(&ctx->gb, 10);
+    } else
     qscale = get_bits(&ctx->gb, 11);
     skip_bits1(&ctx->gb);
 
@@ -386,8 +391,12 @@ static int dnxhd_decode_macroblock(DNXHDContext *ctx, AVFrame *frame,
         dest_u += frame->linesize[1];
         dest_v += frame->linesize[2];
     }
+    if (interlaced_mb) {
+        dct_linesize_luma   <<= 1;
+        dct_linesize_chroma <<= 1;
+    }
 
-    dct_y_offset = dct_linesize_luma << 3;
+    dct_y_offset = interlaced_mb ? frame->linesize[0] : (dct_linesize_luma << 3);
     dct_x_offset = 8 << shift1;
     if (!ctx->is_444) {
         ctx->idsp.idct_put(dest_y,                               dct_linesize_luma, ctx->blocks[0]);
@@ -396,7 +405,7 @@ static int dnxhd_decode_macroblock(DNXHDContext *ctx, AVFrame *frame,
         ctx->idsp.idct_put(dest_y + dct_y_offset + dct_x_offset, dct_linesize_luma, ctx->blocks[5]);
 
         if (!(ctx->avctx->flags & AV_CODEC_FLAG_GRAY)) {
-            dct_y_offset = dct_linesize_chroma << 3;
+            dct_y_offset = interlaced_mb ? frame->linesize[1] : (dct_linesize_chroma << 3);
             ctx->idsp.idct_put(dest_u,                dct_linesize_chroma, ctx->blocks[2]);
             ctx->idsp.idct_put(dest_v,                dct_linesize_chroma, ctx->blocks[3]);
             ctx->idsp.idct_put(dest_u + dct_y_offset, dct_linesize_chroma, ctx->blocks[6]);
@@ -409,7 +418,7 @@ static int dnxhd_decode_macroblock(DNXHDContext *ctx, AVFrame *frame,
         ctx->idsp.idct_put(dest_y + dct_y_offset + dct_x_offset, dct_linesize_luma, ctx->blocks[7]);
 
         if (!(ctx->avctx->flags & AV_CODEC_FLAG_GRAY)) {
-            dct_y_offset = dct_linesize_chroma << 3;
+            dct_y_offset = interlaced_mb ? frame->linesize[1] : (dct_linesize_chroma << 3);
             ctx->idsp.idct_put(dest_u,                               dct_linesize_chroma, ctx->blocks[2]);
             ctx->idsp.idct_put(dest_u + dct_x_offset,                dct_linesize_chroma, ctx->blocks[3]);
             ctx->idsp.idct_put(dest_u + dct_y_offset,                dct_linesize_chroma, ctx->blocks[8]);



More information about the ffmpeg-cvslog mailing list