当我执行以下代码时:
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)
为什么?
答案 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会引起很多悲伤。