ffmpeg 1.0 filter的picref流程分析

2014 10 19
ffmpeg 1.0 filter的picref流程分析:

 

ffmpeg -y -i vga.3gp -vcodec libx264 -an -strict -2 merge.3gp
該命令產生4個filter:buffer->null->format->ffbuffersink.

分析:
解碼一幀數據後會調用av_buffersrc_add_ref來將其推入filter系統進行處理,
sink_buffer.c文件裏 request_frame函數調用ff_start_frame 後到遞歸結束,堆棧如下:
 testffmpeg.exe!default_start_frame(AVFilterLink * inlink, AVFilterBufferRef * picref)  行 215 C
  testffmpeg.exe!ff_start_frame(AVFilterLink * link, AVFilterBufferRef * picref)  行 306 + 0x10 字節 C
  testffmpeg.exe!ff_null_start_frame(AVFilterLink * link, AVFilterBufferRef * picref)  行 169 + 0x15 字節 C
  testffmpeg.exe!ff_start_frame(AVFilterLink * link, AVFilterBufferRef * picref)  行 306 + 0x10 字節 C
  testffmpeg.exe!ff_null_start_frame(AVFilterLink * link, AVFilterBufferRef * picref)  行 169 + 0x15 字節 C
  testffmpeg.exe!ff_start_frame(AVFilterLink * link, AVFilterBufferRef * picref)  行 306 + 0x10 字節 C
  testffmpeg.exe!request_frame(AVFilterLink * link)  行 432 + 0xd 字節 C
  testffmpeg.exe!av_buffersrc_add_ref(AVFilterContext * s, AVFilterBufferRef * buf, int flags)  行 165 + 0x16 字節 C
  testffmpeg.exe!decode_video(InputStream * ist, AVPacket * pkt, int * got_output)  行 1766 + 0x20 字節 C
  testffmpeg.exe!output_packet(InputStream * ist, const AVPacket * pkt)  行 1883 + 0x18 字節 C
  testffmpeg.exe!process_input(int file_index)  行 3022 + 0xd 字節 C
  testffmpeg.exe!transcode_step()  行 3132 + 0xb 字節 C
  testffmpeg.exe!transcode()  行 3189 + 0x5 字節 C
  testffmpeg.exe!wmain(int argc, char * * argv)  行 329 + 0xd 字節 C++
  testffmpeg.exe!__tmainCRTStartup()  行 552 + 0x19 字節 C
  testffmpeg.exe!wmainCRTStartup()  行 371 C
在該過程中,分別對buffer/null/format的outlink->cur_buf進行賦值。其中buffer的outlink->cur_buf
是由decode_video調用avfilter_get_video_buffer_ref_from_arrays來獲取
並作爲av_buffersrc_add_ref函數的參數傳入的。而null/format的outlink->cur_buf則是由
ff_null_start_frame函數調用avfilter_ref_buffer來產生的一個新的reference(通過
ff_start_frame(link->dst->outputs[0], buf_out)來傳遞給下一個filter的outlink->cur_buf)
。產生一個新的 reference估計是爲了下一個filter處理方便,不影響上一個filtrer.

sink_buffer.c文件裏request_frame函數調用 ff_end_frame 後到遞歸結束,堆棧如下:
  testffmpeg.exe!end_frame(AVFilterLink * inlink)  行 134 C
  testffmpeg.exe!ff_end_frame(AVFilterLink * link)  行 344 + 0x9 字節 C
  testffmpeg.exe!ff_null_end_frame(AVFilterLink * link)  行 320 + 0x11 字節 C
  testffmpeg.exe!ff_end_frame(AVFilterLink * link)  行 344 + 0x9 字節 C
  testffmpeg.exe!ff_null_end_frame(AVFilterLink * link)  行 320 + 0x11 字節 C
  testffmpeg.exe!ff_end_frame(AVFilterLink * link)  行 344 + 0x9 字節 C
  testffmpeg.exe!request_frame(AVFilterLink * link)  行 434 + 0x9 字節 C
  testffmpeg.exe!av_buffersrc_add_ref(AVFilterContext * s, AVFilterBufferRef * buf, int flags)  行 165 + 0x16 字節 C
  testffmpeg.exe!decode_video(InputStream * ist, AVPacket * pkt, int * got_output)  行 1766 + 0x20 字節 C
  testffmpeg.exe!output_packet(InputStream * ist, const AVPacket * pkt)  行 1883 + 0x18 字節 C
  testffmpeg.exe!process_input(int file_index)  行 3022 + 0xd 字節 C
  testffmpeg.exe!transcode_step()  行 3132 + 0xb 字節 C
  testffmpeg.exe!transcode()  行 3189 + 0x5 字節 C
  testffmpeg.exe!wmain(int argc, char * * argv)  行 329 + 0xd 字節 C++
  testffmpeg.exe!__tmainCRTStartup()  行 552 + 0x19 字節 C
  testffmpeg.exe!wmainCRTStartup()  行 371 C
  
在sink_buffer文件的end_frame 函數裏,inlink->cur_buf被add_buffer_ref,並將inlink->cur_buf = NULL,
所以format的outlink->cur_buf不會被釋放。
接下來調用clear_link(link)將null和format的outlink->cur_buf釋放(由於是遞歸,所以順序相反)

綜上,通過ff_start_frame/ff_end_frame的配對處理,已經將picref成功推入了sink_buffer的fifo裏。
傳入的以及null產生的picref被unref了。最後在reap_filters函數裏調用av_buffersink_get_buffer_ref進行編碼處理
並調用avfilter_unref_buffer最終將其釋放。

 


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章