我正在尝试通过ffmpeg(在c++中)获取mpeg视频的运动矢量。我遇到的问题是,motion_val以及AVFrame类的motion\usubsample_log2和mb_type保持为空和/或未初始化(调试器显示0x0),而且它们似乎只是由于兼容性原因才可用我在ffmpeg维基上读到,你可以通过的命令行调试视频的运动矢量
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。有了这个假设,我搜索了更多的信息,发现了一些我认为可能有帮助的代码片段。
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数组的计算或填充。顺便说一句,我的代码是基于Victor Hsieh和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。55年1月13日。2001年13月13日
- libavfilter 4。10.100/4。10.100
- libswscale 2。6.100/2。6.100
- libswresample 0。19.100/0。19.100
- libpostdoc 52。3.100/52。3.100
更改为更新的版本(2.5),但没有改变/解决问题。
运动矢量在文件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
}
}