Я пытаюсь получить векторы движения видео в формате MPEG через ffmpeg (в C ++).
У меня проблема в том, что motion_val вместе с motion_subsample_log2 и mb_type класса AVFrame остаются пустыми и / или не инициализируются (отладчик сообщает 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"},
Я полагаю, что эта строка влияет на 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.
Кстати, мой код основан на кодекс Виктора Се и Джиаси Чена и этот код в основном является исходным кодом ffmpeg (libavcodec \ mpegvideo.c). Я также пытался найти (также с помощью документации) фрагмент кода, который запускает вычисления, но из-за сложности кода я не получил никаких результатов.
Теперь вопрос в том, есть ли возможность заполнить эти переменные или начать вычисление таблицы векторов движения, или есть какой-нибудь другой альтернативный способ получить векторы движения каждого блока mpeg-кадров.
Редактировать:
Я забыл упомянуть мою версию ffmpeg
Версия Zeranoe’s FFmpeg: 2014-07-08 git-14e2406
Изменилась на более новую версию (2.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);
и оттуда:
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
}
}