From: Christophe Gisquet <c.gisq...@ateme.com> Fix the logic around checking the ACT flag per MB and row. This also requires adding a 444 path to swap channels into the ffmpeg formats, as they are GBR, and not RGB. --- libavcodec/dnxhddec.c | 64 +++++++++++++++++++++++++++++++------------ 1 file changed, 47 insertions(+), 17 deletions(-)
diff --git a/libavcodec/dnxhddec.c b/libavcodec/dnxhddec.c index 359588f963..11da1c286c 100644 --- a/libavcodec/dnxhddec.c +++ b/libavcodec/dnxhddec.c @@ -249,12 +249,10 @@ static int dnxhd_decode_header(DNXHDContext *ctx, AVFrame *frame, return AVERROR_INVALIDDATA; } else if (bitdepth == 10) { ctx->decode_dct_block = dnxhd_decode_dct_block_10_444; - ctx->pix_fmt = ctx->act ? AV_PIX_FMT_YUV444P10 - : AV_PIX_FMT_GBRP10; + ctx->pix_fmt = ctx->act ? AV_PIX_FMT_GBRP10 : AV_PIX_FMT_YUV444P10; } else { ctx->decode_dct_block = dnxhd_decode_dct_block_12_444; - ctx->pix_fmt = ctx->act ? AV_PIX_FMT_YUV444P12 - : AV_PIX_FMT_GBRP12; + ctx->pix_fmt = ctx->act ? AV_PIX_FMT_GBRP12 : AV_PIX_FMT_YUV444P12; } } else if (bitdepth == 12) { ctx->decode_dct_block = dnxhd_decode_dct_block_12; @@ -504,19 +502,19 @@ static int dnxhd_decode_macroblock(const DNXHDContext *ctx, RowContext *row, qscale = get_bits(&row->gb, 11); } act = get_bits1(&row->gb); - if (act) { - if (!ctx->act) { - static int act_warned; - if (!act_warned) { - act_warned = 1; - av_log(ctx->avctx, AV_LOG_ERROR, - "ACT flag set, in violation of frame header.\n"); - } - } else if (row->format == -1) { + if (ctx->act) { + if (row->format == -1) { row->format = act; } else if (row->format != act) { row->format = 2; // Variable } + } else if (act) { + static int act_warned; + if (!act_warned) { + act_warned = 1; + av_log(ctx->avctx, AV_LOG_ERROR, + "ACT flag set, in violation of frame header.\n"); + } } if (qscale != row->last_qscale) { @@ -569,6 +567,21 @@ static int dnxhd_decode_macroblock(const DNXHDContext *ctx, RowContext *row, } break; case DNX_CHROMAFORMAT_444: + if (ctx->avctx->profile == FF_PROFILE_DNXHD) { + ctx->idsp.idct_put(dest_y, dct_linesize_luma, row->blocks[2]); + ctx->idsp.idct_put(dest_y + dct_x_offset, dct_linesize_luma, row->blocks[3]); + ctx->idsp.idct_put(dest_y + dct_y_offset, dct_linesize_luma, row->blocks[8]); + ctx->idsp.idct_put(dest_y + dct_y_offset + dct_x_offset, dct_linesize_luma, row->blocks[9]); + + ctx->idsp.idct_put(dest_u, dct_linesize_luma, row->blocks[4]); + ctx->idsp.idct_put(dest_u + dct_x_offset, dct_linesize_luma, row->blocks[5]); + ctx->idsp.idct_put(dest_u + dct_y_offset, dct_linesize_luma, row->blocks[10]); + ctx->idsp.idct_put(dest_u + dct_y_offset + dct_x_offset, dct_linesize_luma, row->blocks[11]); + ctx->idsp.idct_put(dest_v, dct_linesize_luma, row->blocks[0]); + ctx->idsp.idct_put(dest_v + dct_x_offset, dct_linesize_luma, row->blocks[1]); + ctx->idsp.idct_put(dest_v + dct_y_offset, dct_linesize_luma, row->blocks[6]); + ctx->idsp.idct_put(dest_v + dct_y_offset + dct_x_offset, dct_linesize_luma, row->blocks[7]); + } else { ctx->idsp.idct_put(dest_y, dct_linesize_luma, row->blocks[0]); ctx->idsp.idct_put(dest_y + dct_x_offset, dct_linesize_luma, row->blocks[1]); ctx->idsp.idct_put(dest_y + dct_y_offset, dct_linesize_luma, row->blocks[6]); @@ -585,6 +598,7 @@ static int dnxhd_decode_macroblock(const DNXHDContext *ctx, RowContext *row, ctx->idsp.idct_put(dest_v + dct_y_offset, dct_linesize_chroma, row->blocks[10]); ctx->idsp.idct_put(dest_v + dct_y_offset + dct_x_offset, dct_linesize_chroma, row->blocks[11]); } + } break; case DNX_CHROMAFORMAT_420: ctx->idsp.idct_put(dest_y, dct_linesize_luma, row->blocks[0]); @@ -610,6 +624,8 @@ static int dnxhd_decode_row(AVCodecContext *avctx, void *data, RowContext *row = ctx->rows + threadnb; int x, ret; + row->format = -1; + row->last_dc[0] = row->last_dc[1] = row->last_dc[2] = 1 << (ctx->bit_depth + 2); // for levels +2^(bitdepth-1) @@ -694,14 +710,21 @@ decode_coding_unit: static int act_warned; int format = ctx->rows[0].format; for (i = 1; i < avctx->thread_count; i++) { - if (ctx->rows[i].format != format && - ctx->rows[i].format != -1 /* not run */) { + if (ctx->rows[i].format == -1) + continue; + if (format == -1) { + format = ctx->rows[i].format; + continue; + } + if (ctx->rows[i].format != format) { + av_log(ctx->avctx, AV_LOG_ERROR, + "Format changed from %d to %d.\n", format, ctx->rows[i].format); format = 2; break; } } + switch (format) { - case -1: case 2: if (!act_warned) { act_warned = 1; @@ -709,6 +732,7 @@ decode_coding_unit: "Unsupported: variable ACT flag.\n"); } break; + case -1: case 0: ctx->pix_fmt = ctx->bit_depth==10 ? AV_PIX_FMT_GBRP10 : AV_PIX_FMT_GBRP12; @@ -719,12 +743,18 @@ decode_coding_unit: break; } } - avctx->pix_fmt = ctx->pix_fmt; if (ret) { av_log(ctx->avctx, AV_LOG_ERROR, "%d lines with errors\n", ret); return AVERROR_INVALIDDATA; } + if (avctx->pix_fmt != ctx->pix_fmt) { + picture->format = avctx->pix_fmt = ctx->pix_fmt; + ret = ff_set_dimensions(avctx, ctx->width, ctx->height); + if (ret < 0) + return ret; + } + *got_frame = 1; return avpkt->size; } -- 2.29.2 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".