2016-05-23 241 views
1

當我執行以下代碼:分段故障

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

如果我們提供了[最小,完整,可驗證示例](http://stackoverflow.com/help/mcve),這將非常有幫助。然而,看起來frames_video1 [k]可能導致NULL或其他無效值,並且在分配'avf1 =&tmp'之前,您沒有檢查'tmp == NULL'或做任何其他類型的理智檢查。即使它不爲null,如果你正在訪問超過'frames_video'的邊界,你可能會得到垃圾數據而不是空值。 –

+0

frames_video1 [k]不爲空,否則就不會有輸出「avf1-> side_data不是NULL !! ............」 – user273653

+0

或者是tmp。如何在分配avf1 =&tmp時執行完整性檢查? – user273653

回答

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爲空,這是不正常的。問題的原因在於其他地方。

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會導致很多悲傷。