如何在 FFMPEG 中填充/计算motion_val?
Posted
技术标签:
【中文标题】如何在 FFMPEG 中填充/计算motion_val?【英文标题】:How to fill/calculate motion_val in FFMPEG? 【发布时间】:2015-02-06 11:18:58 【问题描述】:我正在尝试通过 ffmpeg(在 C++ 中)获取 mpeg 视频的运动矢量。 我遇到的问题是,motion_val 以及 AVFrame 类的 motion_subsample_log2 和 mb_type 保持为空和/或未初始化(调试器说 0x0)并且似乎它们仅由于兼容性原因才可用 我在ffmpeg wiki 中读到,您可以通过命令行调试视频的运动矢量
ffmpeg -vismv pf -i input.mp4 output.mp4
结果是 output.mp4 有运动矢量箭头。于是我在代码中搜索了–vismv参数,在libavcodec\options.c中发现了一长串选项:
"vismv", "visualize motion vectors (MVs)", OFFSET(debug_mv), FF_OPT_TYPE_INT, DEFAULT, 0, INT_MAX, V|D, "debug_mv",
我想这条线会以某种方式影响 AVCodecContext 的 debug_mv。有了这个假设,我搜索了更多信息,发现了一些我认为可能有帮助的代码 sn-ps。
pAVCodecContext->debug_mv = FF_DEBUG_VIS_MV_P_FOR | FF_DEBUG_VIS_MV_B_FOR | FF_DEBUG_MB_TYPE | FF_DEBUG_MV;
和
pAVCodecContext->debug |= FF_DEBUG_MV;
但两者都没有触发motion_val数组的计算或填充。 顺便说一句,我的代码基于the code by Victor Hsieh and Jiasi Chen,而这段代码基本上是 ffmpeg 源代码 (libavcodec\mpegvideo.c)。我还尝试(也借助文档)找到触发计算的代码段,但由于代码的复杂性,我没有得到任何结果。 现在的问题是,是否有可能填充这些变量或开始计算运动矢量表,或者是否有任何其他替代方法来获取 mpeg 帧的每个块的运动矢量。
编辑:
我忘了说我的ffmpeg版本
Zeranoe 的 FFmpeg 版本:2014-07-08 git-14e2406
libavutil 52. 91.100 / 52. 91.100 libavcodec 55. 68.102 / 55. 68.102 libavformat 55. 45.100 / 55. 45.100 libavdevice 55. 13.101 / 55. 13.101 libavfilter 4.10.100 / 4.10.100 libswscale 2. 6.100 / 2. 6.100 libswresample 0. 19.100 / 0. 19.100 libpostproc 52. 3.100 / 52. 3.100已更改为较新的版本 (2.5),但并未更改/解决问题。
【问题讨论】:
您可能正在寻找frame.c
中的函数av_frame_get_side_data()
以及vf_codecview.c
中与函数filter_frame
相关的一些代码。 codecview 过滤器更适合此目的,因为不推荐使用 vismv
。我必须在某个时候更新 wiki 页面。
同时在mpegvideo.c
中检查ff_print_debug_info2
。每张图片都应该填写motion_val
。
非常感谢,您是对的。 av_frame_get_side_data()
是有帮助的方法。您对vf_codecview.c
和filter_frame
的提示也帮助了我很多。
太好了,我发布了官方答案 :) 随意使用您使用的确切代码对其进行编辑。
【参考方案1】:
运动矢量在文件frame.c
中的函数av_frame_get_side_data()
中可用。
此外,vf_codecview.c
文件定义了绘制运动矢量的过滤器 - 请参阅函数 filter_frame()
。
例如,如果你有一个AVFrame
,你可以这样做:
AVFrameSideData *sd = av_frame_get_side_data(frame, AV_FRAME_DATA_MOTION_VECTORS);
从那里开始:
if (sd)
int i;
const AVMotionVector *mvs = (const AVMotionVector *)sd->data;
for (i = 0; i < sd->size / sizeof(*mvs); i++)
const AVMotionVector *mv = &mvs[i];
const int direction = mv->source > 0;
// do something with motion vector
【讨论】:
以上是关于如何在 FFMPEG 中填充/计算motion_val?的主要内容,如果未能解决你的问题,请参考以下文章