如何在FFMPEG中填充/计算motion_val?

Men*_*m42 3 c++ video ffmpeg vector motion-detection

我试图通过ffmpeg(在c ++中)获取mpeg视频的运动矢量.我遇到的问题是,motion_val以及AVFrame类的motion_subsample_log2和mb_type保持为空和/或未初始化(调试器显示为0x0)并且似乎它们仅在我阅读的兼容性原因中可用ffmpeg wiki,你可以通过命令行调试视频的运动矢量

ffmpeg -vismv pf -i input.mp4 output.mp4
Run Code Online (Sandbox Code Playgroud)

结果是output.mp4具有运动矢量箭头.所以我在代码中搜索了-vismv参数,并在libavcodec\options.ca中找到了很长的选项列表:

{"vismv", "visualize motion vectors (MVs)", OFFSET(debug_mv), FF_OPT_TYPE_INT, DEFAULT, 0, INT_MAX, V|D, "debug_mv"},   
Run Code Online (Sandbox Code Playgroud)

我想这行会以某种方式影响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;
Run Code Online (Sandbox Code Playgroud)

pAVCodecContext->debug |= FF_DEBUG_MV;    
Run Code Online (Sandbox Code Playgroud)

但两者都没有触发计算或填充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. 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),但它没有更改/解决问题.

slh*_*hck 5

运动矢量av_frame_get_side_data()在文件中的函数中可用frame.c.

此外,该vf_codecview.c文件定义了绘制运动矢量的过滤器 - 请参阅该功能filter_frame().

例如,如果你有AVFrame,你可以这样做:

AVFrameSideData *sd = av_frame_get_side_data(frame, AV_FRAME_DATA_MOTION_VECTORS);
Run Code Online (Sandbox Code Playgroud)

从那里:

 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
        }
    }
Run Code Online (Sandbox Code Playgroud)