From 8e036016fa93033404d2b08db970ceb7ce589122 Mon Sep 17 00:00:00 2001
From: Christophe Gisquet <christophe.gisquet@gmail.com>
Date: Thu, 24 Sep 2015 09:04:48 +0200
Subject: [PATCH] dnxhddec: skip an unknown bit
This bit is 1 in some samples, and seems to coincide with interlaced
mbs. Currently, it leads to an obviously incorrect qscale value;
The encoder writes 12 bits of syntax, last bit always 0, which is now
somewhat inconsistent, but ends up with the same effect. The encoder
does not attempt to encode as interlaced content.
The qscale syntax in general seems oversized, maybe to support higher
bitdepths.
Fixes ticket #4876.
---
libavcodec/dnxhddec.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/libavcodec/dnxhddec.c b/libavcodec/dnxhddec.c
index ccb61eb..4270b69 100644
|
a
|
b
|
static int dnxhd_decode_macroblock(DNXHDContext *ctx, AVFrame *frame,
|
| 348 | 348 | uint8_t *dest_y, *dest_u, *dest_v; |
| 349 | 349 | int dct_y_offset, dct_x_offset; |
| 350 | 350 | int qscale, i; |
| | 351 | int interlaced_mb = get_bits1(&ctx->gb); |
| 351 | 352 | |
| 352 | | qscale = get_bits(&ctx->gb, 11); |
| | 353 | qscale = get_bits(&ctx->gb, 10); |
| 353 | 354 | skip_bits1(&ctx->gb); |
| 354 | 355 | |
| 355 | 356 | if (qscale != ctx->last_qscale) { |
| … |
… |
static int dnxhd_decode_macroblock(DNXHDContext *ctx, AVFrame *frame,
|
| 385 | 386 | dest_u += frame->linesize[1]; |
| 386 | 387 | dest_v += frame->linesize[2]; |
| 387 | 388 | } |
| | 389 | if (interlaced_mb) { |
| | 390 | dct_linesize_luma <<= 1; |
| | 391 | dct_linesize_chroma <<= 1; |
| | 392 | } |
| 388 | 393 | |
| 389 | | dct_y_offset = dct_linesize_luma << 3; |
| | 394 | dct_y_offset = interlaced_mb ? frame->linesize[0] : (dct_linesize_luma << 3); |
| 390 | 395 | dct_x_offset = 8 << shift1; |
| 391 | 396 | if (!ctx->is_444) { |
| 392 | 397 | ctx->idsp.idct_put(dest_y, dct_linesize_luma, ctx->blocks[0]); |
| … |
… |
static int dnxhd_decode_macroblock(DNXHDContext *ctx, AVFrame *frame,
|
| 395 | 400 | ctx->idsp.idct_put(dest_y + dct_y_offset + dct_x_offset, dct_linesize_luma, ctx->blocks[5]); |
| 396 | 401 | |
| 397 | 402 | if (!(ctx->avctx->flags & AV_CODEC_FLAG_GRAY)) { |
| 398 | | dct_y_offset = dct_linesize_chroma << 3; |
| | 403 | dct_y_offset = interlaced_mb ? frame->linesize[1] : (dct_linesize_chroma << 3); |
| 399 | 404 | ctx->idsp.idct_put(dest_u, dct_linesize_chroma, ctx->blocks[2]); |
| 400 | 405 | ctx->idsp.idct_put(dest_v, dct_linesize_chroma, ctx->blocks[3]); |
| 401 | 406 | ctx->idsp.idct_put(dest_u + dct_y_offset, dct_linesize_chroma, ctx->blocks[6]); |
| … |
… |
static int dnxhd_decode_macroblock(DNXHDContext *ctx, AVFrame *frame,
|
| 408 | 413 | ctx->idsp.idct_put(dest_y + dct_y_offset + dct_x_offset, dct_linesize_luma, ctx->blocks[7]); |
| 409 | 414 | |
| 410 | 415 | if (!(ctx->avctx->flags & AV_CODEC_FLAG_GRAY)) { |
| 411 | | dct_y_offset = dct_linesize_chroma << 3; |
| | 416 | dct_y_offset = interlaced_mb ? frame->linesize[1] : (dct_linesize_chroma << 3); |
| 412 | 417 | ctx->idsp.idct_put(dest_u, dct_linesize_chroma, ctx->blocks[2]); |
| 413 | 418 | ctx->idsp.idct_put(dest_u + dct_x_offset, dct_linesize_chroma, ctx->blocks[3]); |
| 414 | 419 | ctx->idsp.idct_put(dest_u + dct_y_offset, dct_linesize_chroma, ctx->blocks[8]); |