我们一直在使用 ffmpeg/ffprobe 检查视频文件的完整性。如果 ffmpeg 在其 stderr 中返回任何内容,我们就知道有些不对劲。
对于某些视频,类似的错误将会显示在 stderr 中。
[dnxhd @ 00000212f6fc3e80] ACT 标志设置,违反帧头。
但我不知道 ACT 标志实际上是什么。
深入研究 ffmpeg 代码会返回此块(dnxhddec.c):
static int dnxhd_decode_macroblock(const DNXHDContext *ctx, RowContext *row,
AVFrame *frame, int x, int y)
{
...
if (ctx->mbaff) {
interlaced_mb = get_bits1(&row->gb);
qscale = get_bits(&row->gb, 10);
} else {
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) {
row->format = act;
} else if (row->format != act) {
row->format = 2; // Variable
}
}
...
在同一个文件中,另一段代码显示:
static int dnxhd_decode_header(DNXHDContext *ctx, AVFrame *frame,
const uint8_t *buf, int buf_size,
int first_field)
{
...
ctx->act = buf[0x2C] & 1;
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");
...
所以我猜 ACT = 自适应色彩变换
以下是修改该行的提交消息:
Christophe Gisquet Christophe Gisquet,5 年前 (2015 年 10 月 4 日下午 4:06)
dnxhddec:更好地支持 4:4:4
配置文件 1256 和 1270(当前)在帧头和 MB 级别发出信号,指示所使用的色彩空间,RGB 或 YUV。虽然不支持 MB 级别变化的色彩空间,但可以跟踪它是否恒定,以确定确切的色彩空间。
这需要有位深度和 ACT 以及 4:4:4 标志,进而需要 CID。由于在验证足够多的内容之前设置这些可能会导致无效/未设置的 DSP 功能,因此在上下文中设置位深度会延迟。
但它并未针对真正的 RGB 序列进行测试。
通过阅读提交,这似乎只会影响 4:4:4 视频,但实际上我们所有出现此错误的视频目前都是 4:2:2。(编解码器 ID 1237 1242 1080i)
到目前为止,我能找到的有关配置文件(编解码器 ID)的
唯一第一个有用的结果是:http://docs.red.com/955-0192_v7.3/RANGER_GEMINI_HTML_v7.3/Content/5_Advanced_Menus/1_Settings/Recording/Avid_Info.htm
我查看的另一个地方是 AAFSDK (CAAFDNxHDCodec.cpp):
switch(_ComprID)
{
case 1235: FormatNumber=DNX_220X_1080p_COMPRESSION_ID; break;
case 1237: FormatNumber=DNX_145_1080p_COMPRESSION_ID; break;
case 1238: FormatNumber=DNX_220_1080p_COMPRESSION_ID; break;
case 1241: FormatNumber=DNX_220X_1080i_COMPRESSION_ID; break;
case 1242: FormatNumber=DNX_145_1080i_COMPRESSION_ID; break;
case 1243: FormatNumber=DNX_220_1080i_COMPRESSION_ID; break;
case 1244: FormatNumber=DNX_145_1440_1080i_COMPRESSION_ID; break;
case 1250: FormatNumber=DNX_220X_720p_COMPRESSION_ID; break;
case 1251: FormatNumber=DNX_220_720p_COMPRESSION_ID; break;
case 1252: FormatNumber=DNX_145_720p_COMPRESSION_ID; break;
case 1253: FormatNumber=DNX_36_1080p_COMPRESSION_ID; break;
//case 1254: FormatNumber=DNX_50_1080i_COMPRESSION_ID; break;
default:
FormatNumber=DNX_36_1080p_COMPRESSION_ID; //make any guess
break;
}
另请查看 dnxhddec.c 的早期提交:
static int dnxhd_decode_macroblock(const DNXHDContext *ctx, RowContext *row,
AVFrame *frame, int x, int y)
{
...
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");
}
}
...
其提交信息如下:
Christophe Gisquet Christophe Gisquet,5 年前 (2015 年 9 月 25 日晚上 11:07)
dnxhddec:解析并打印自适应颜色变换
表示块级别的 YCbCr->RGB 变换。虽然没有明确说明,但这会假设实际内容是平面 RGB。
目前不受支持,但我发现使用它的一个序列以这种方式标记每个 mb,实际上意味着内容是 YCbCr,因此最好留给输出格式来决定如何处理它。
编辑:
我仍在寻找 DNxHD 编解码器规范。
我还没有完全理解代码。但是如果作者说它目前不受支持(5 年前),并且某些序列显示出相互冲突的含义,那么不应该忽略它而不是生成错误吗?
在我们的案例中,并不是每个 mb 都被标记。它可能在视频的某个特定镜头中被标记,因此错误只会在镜头的第一帧中弹出。这也意味着我们的管道可以以某种方式创建带有标记和未标记的输出,其中似乎所有 YCbCr 素材都是如此。并且序列的混合版本保留了所有带有标记和未标记的宏块。
感谢您读到这里。
问题:
- 在 YCbCr 4:2:2 视频中将 ACT 标志设置为 true 是什么意思?
- 如果在 RGB 4:4:4 视频中设置为 true,是否意味着相反?
- 是否可以安全地忽略此错误?为什么?
- 是否应该修改 ffmpeg 以忽略该标志?
非常感谢!
附言:
虽然不是完全相同的错误,但我遇到了这个从未回答的问题: https://www.mail-archive.com/[电子邮件保护]/msg23397.html
和楼主一样,我目前也无法提供样本。我正在尝试用一些公共领域的材料重现这样的视频,以便以后分享。不过,到那时,我可能已经知道问题的答案了。
编辑2:
仍然在努力从头开始制作样本视频。但我重新包装了视频的一部分,10 帧黑色,我们发现 ACT 标志被设置了。
我怀疑这与一些颜色分级插件有关,但我无法验证,因为通常当我们检测到错误时,只剩下混音版本,而所有的素材都已被删除。
编辑3:
我正在查看第一帧的宏块。我相信这是它的开始。
文件偏移量 0x4094:00 3F87 FA 28 A2 8A 28 A2 80 18 A2 8A 28 A2 8A
我相信这个加粗的 1 位是 ACT 标志?
0000 0000 00111111
我尝试将第一帧中的每个宏块(1080i 视频,每场 34 个宏块)更改为:
00 2F或 0000 0000 00101111
但是 ffmpeg 仍然认为宏块“ACT 标记”,尽管它没有抱怨我的更改。
我是否遗漏了什么?
非常感激!