Profiles 1256 & 1270 (currently) signal at the frame header and MB levels the colorspace used, either RGB or YUV. While a MB-level varying colorspace is not supported, whether it is constant can be tracked so as to determine the exact colorspace.
It is not tested against a true RGB sequence, though. --- libavcodec/dnxhddec.c | 82 ++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 62 insertions(+), 20 deletions(-) diff --git a/libavcodec/dnxhddec.c b/libavcodec/dnxhddec.c index fec9aac..52fd334 100644 --- a/libavcodec/dnxhddec.c +++ b/libavcodec/dnxhddec.c @@ -43,6 +43,8 @@ typedef struct RowContext { int last_dc[3]; int last_qscale; int errors; + /** -1:not set yet 0:off=RGB 1:on=YUV 2:variable */ + int format; } RowContext; typedef struct DNXHDContext { @@ -202,6 +204,18 @@ static int dnxhd_decode_header(DNXHDContext *ctx, AVFrame *frame, } ctx->avctx->bits_per_raw_sample = ctx->bit_depth; + cid = AV_RB32(buf + 0x28); + if ((ret = dnxhd_init_vlc(ctx, cid)) < 0) + return ret; + if (ctx->mbaff && ctx->cid_table->cid != 1260) + av_log(ctx->avctx, AV_LOG_WARNING, + "Adaptive MB interlace flag in an unsupported profile.\n"); + + ctx->act = buf[0x2C] & 7; + if (ctx->act && ctx->cid_table->cid != 1256 && ctx->cid_table->cid != 1270) + av_log(ctx->avctx, AV_LOG_WARNING, + "Adaptive color transform in an unsupported profile.\n"); + ctx->is_444 = (buf[0x2C] >> 6) & 1; if (ctx->is_444) { if (ctx->bit_depth == 8) { @@ -209,10 +223,12 @@ static int dnxhd_decode_header(DNXHDContext *ctx, AVFrame *frame, return AVERROR_INVALIDDATA; } else if (ctx->bit_depth == 10) { ctx->decode_dct_block = dnxhd_decode_dct_block_10_444; - ctx->pix_fmt = AV_PIX_FMT_YUV444P10; + ctx->pix_fmt = ctx->act ? AV_PIX_FMT_YUV444P10 + : AV_PIX_FMT_GBRP10; } else { ctx->decode_dct_block = dnxhd_decode_dct_block_12_444; - ctx->pix_fmt = AV_PIX_FMT_YUV444P12; + ctx->pix_fmt = ctx->act ? AV_PIX_FMT_YUV444P12 + : AV_PIX_FMT_GBRP12; } } else if (ctx->bit_depth == 12) { ctx->decode_dct_block = dnxhd_decode_dct_block_12; @@ -231,19 +247,6 @@ static int dnxhd_decode_header(DNXHDContext *ctx, AVFrame *frame, ff_zigzag_direct); } - cid = AV_RB32(buf + 0x28); - - if ((ret = dnxhd_init_vlc(ctx, cid)) < 0) - return ret; - if (ctx->mbaff && ctx->cid_table->cid != 1260) - av_log(ctx->avctx, AV_LOG_WARNING, - "Adaptive MB interlace flag in an unsupported profile.\n"); - - ctx->act = buf[0x2C] & 7; - if (ctx->act && ctx->cid_table->cid != 1256 && ctx->cid_table->cid != 1270) - av_log(ctx->avctx, AV_LOG_WARNING, - "Adaptive color transform in an unsupported profile.\n"); - // make sure profile size constraints are respected // DNx100 allows 1920->1440 and 1280->960 subsampling if (ctx->width != ctx->cid_table->width && @@ -462,11 +465,17 @@ static int dnxhd_decode_macroblock(const DNXHDContext *ctx, RowContext *row, } act = get_bits1(&row->gb); if (act) { - static int warned = 0; - if (!warned) { - warned = 1; - av_log(ctx->avctx, AV_LOG_ERROR, - "Unsupported adaptive color transform, patch welcome.\n"); + if (!ctx->act) { + static int act_warned = 0; + 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) { + row->format = act; + } else if (row->format != act) { + row->format = 2; // Variable } } @@ -577,6 +586,9 @@ static int dnxhd_decode_frame(AVCodecContext *avctx, void *data, ff_dlog(avctx, "frame size %d\n", buf_size); + for (i = 0; i < avctx->thread_count; i++) + ctx->rows[i].format = -1; + decode_coding_unit: if ((ret = dnxhd_decode_header(ctx, picture, buf, buf_size, first_field)) < 0) return ret; @@ -622,6 +634,36 @@ decode_coding_unit: ctx->rows[i].errors = 0; } + if (ctx->act) { + static int act_warned = 0; + 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 */) { + format = 2; + break; + } + } + switch (format) { + case -1: + case 2: + if (!act_warned) { + act_warned = 1; + av_log(ctx->avctx, AV_LOG_ERROR, + "Unsupported: variable ACT flag.\n"); + } + break; + case 0: + ctx->pix_fmt = ctx->bit_depth==10 + ? AV_PIX_FMT_GBRP10 : AV_PIX_FMT_GBRP12; + break; + case 1: + ctx->pix_fmt = ctx->bit_depth==10 + ? AV_PIX_FMT_YUV444P10 : AV_PIX_FMT_YUV444P12; + 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; -- 2.5.2 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel