如何在 FFMPEG 中 fill/calculate motion_val?

How to fill/calculate motion_val in FFMPEG?

我正在尝试通过 ffmpeg(在 C++ 中)获取 mpeg 视频的运动矢量。 我遇到的问题是,AVFrame class 的 motion_val 以及 motion_subsample_log2 和 mb_type 保持为空 and/or 未初始化(调试器说 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"},   

我想这行会以某种方式影响 debug_mv AVCodecContext。有了这个假设,我搜索了更多信息,并找到了一些我认为可能有用的代码片段。

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)。我也试图找到(也在文档的帮助下)触发计算的代码片段,但由于代码的复杂性,我没有得到任何结果。 现在的问题是,是否有可能填充此变量或开始计算运动矢量 table 或是否有任何其他替代方法来获取 mpeg 帧的每个块的运动矢量。

编辑:

我忘了说我的 ffmpeg 版本

Zeranoe 的 FFmpeg 版本:2014-07-08 git-14e2406

已更改为较新的版本 (2.5),但没有 change/solve 问题。

文件 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
        }
    }