av_frame_get_side_data中的分段错误

时间:2016-05-23 15:19:11

标签: c ffmpeg

当我执行以下代码时:

AVFrame tmp = frames_video1[k]; //AVFrame frames_video1[]
AVFrame *avf1 = &tmp;
AVFrameSideData* avfsd1=NULL;
if(avf1->side_data != NULL)
    printf("avf1->side_data is not NULL!!...........\n");
avfsd1 = av_frame_get_side_data(avf1, AV_FRAME_DATA_MOTION_VECTORS);

我遇到了在av_frame_get_side_data(avf1,AV_FRAME_DATA_MOTION_VECTORS)发生的分段错误:

avf1->side_data is not NULL!!...........
Segmentation fault (core dumped) 

为什么?

2 个答案:

答案 0 :(得分:1)

这是gdb的输出:

(gdb) print avf1->side_data->type 
Cannot access memory at address 0x0

(gdb) print frames_video1[1]->side_data->type 
Cannot access memory at address 0x0

令人惊讶的是,avf1指向一个损坏的帧,其side_data->type为空,这是异常的。问题的原因在于其他地方。

答案 1 :(得分:0)

AVFrame tmp = frames_video1[k]; //AVFrame frames_video1[]
AVFrame *avf1 = &tmp;

你不能这样做。我不知道你从哪里学到这一点,但这是不允许的,从根本上说是行不通的。您不知道应用程序中AVFrame的大小(它不是FFmpeg的ABI的一部分),因此您无法在堆栈上放置副本。相反,这样做:

AVFrame *avf1 = frames_video1[k];

不要在堆栈上复制FFmpeg对象,它将无法正常工作。这也意味着frames_video1 []需要是AVFrame *的数组,即AVFrame指针,而不是AVFrame的数组。如果你不明白为什么,请阅读C中的指针和内存,并再次记住AVFrame的大小不是FFmpeg ABI的一部分。

现在,让我们调试您的对象。首先,C堆栈的基础知识:frames_video1[]中有多少帧,k是什么?什么是frames_video1[k]->data[0]frames_video[k]->linesize[0]?他们合法吗?您确定frames_video1[k]是合法对象吗?事实上,某些不存在的内存副本是非NULL,这意味着什么。

其次,如果对象是合法的,那么AVFrame->nb_side_data是什么?您无法访问该索引之外的AVFrame->side_data[]

(gdb) print avf1->side_data->type

你也做不到。 side_data[]是一个指针数组,所以请执行以下操作:

(gdb) print avf1->side_data[0]->type

所有这一切,我再次强烈建议你阅读C指针和内存分配,我不认为你完全理解它。 FFmpeg是一个非常低级的C库,不理解C会引起很多悲伤。