日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

ffmpeg API 笔记:使用libavcodec/libavformat/libswscale ffmpeg例子

發布時間:2025/3/21 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ffmpeg API 笔记:使用libavcodec/libavformat/libswscale ffmpeg例子 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
ffmpeg API 筆記:使用libavcodec/libavformat/libswscale December 11, 2009

Update 2010.1.5: 其實研究ffmpeg不用找什么教程,第一步應該是下載ffmpeg的源碼包。下面提到的An FFmpeg and SDL Tutorial確實有講解,但是教程總是跟不上代碼的變化的,所以直接看可工作代碼最好;ffmpeg的結構很分明,后臺是幾個庫:libxxx,前臺是三個程序ffmpeg, ffplay, ffserver,那篇教程說的就是ffplay的實現。一個播放器,其實重點不是解碼,解碼的東西是lib去做的,主要是做聲音視頻的時鐘同步。ffplay的代碼可以說是一個可用播放器最簡單的實現了,源碼里面有個output_example.c,可以說是最基本的api示范吧。ffmpeg是轉換編碼解碼轉換程序,因為涉及重新采樣等等,所以代碼量也不少的。


這兩天"調研"了下ffmpeg的API,不得不承認被雷倒:ffmpeg又是一個很geek的項目,純社區開發,基于逆向,功能強大,但是文檔極度有限,想了解API?看源碼去…… 網上關于ffmpeg API的資料,無非是ffmpeg文檔里面的兩個鏈接,Using libavformat and libavcodec by
Martin B?hme(以及其Update,介紹了新引入的API)跟An FFmpeg and SDL Tutorial
by Stephen Dranger;兩個tutorial基于ffmpeg 0.4.8,現在ffmpeg發布的版本是0.5.0,好像數值相差不大,不過0.4.8是5年前的了(相比之下wine用了15年版本號才到達1.0,有過之余無不及),兩個教程里面的代碼在0.5.0下一編譯,哇,一堆錯誤,可不僅有些api函數變了,有些結構成員壓根就沒了,頭文件的位置更是不一樣(各個庫分家了)……所以我調試了好幾個小時,終于把例子的代碼弄好(其實Martin B?hme那篇有一段09年加入的更新說明,鏈接了有相關的解決辦法,我一開始沒注意,幾個小時自己解決,不過也有收獲)。

最后我調試好的代碼流程:打開一個視頻文件,抓取前5幀保存為文件;
基于Stephen Dranger的Tutorial1源碼在此:GoogleCode

av_register_all();//初始化ffmpeg庫,如果系統里面的ffmpeg沒配置好這里會出錯 av_open_input_file(); av_find_stream_info();//查找文件的流信息 dump_format();//dump只是個調試函數,輸出文件的音、視頻流的基本信息了,幀率、分辨率、音頻采樣等等 for(...);//遍歷文件的各個流,找到第一個視頻流,并記錄該流的編碼信息 sws_getContext();//根據編碼信息設置渲染格式 avcodec_find_decoder();//在庫里面查找支持該格式的解碼器 avcodec_open();//打開解碼器 pFrame=avcodec_alloc_frame();//分配一個幀指針,指向解碼后的原始幀 pFrameRGB=avcodec_alloc_frame();//分配一個幀指針,指向存放轉換成RGB后的幀 avpicture_fill(pFrameRGB);//給pFrameRGB幀加上分配的內存; while true{av_read_frame();//讀取一個幀(到最后幀則break)avcodec_decode_video();//解碼該幀sws_scale();//把該幀轉換(渲染)成RGBSaveFrame();//對前5幀保存成ppm圖形文件(這個是自定義函數,非API)av_free_packet();//釋放本次讀取的幀內存 } avcodec_close(); av_close_input_file();

用到的API就這么多,當然實際代碼稍復雜一點;ppm圖像是類似BMP的非壓縮格式,SaveFrame就是相當于把pFrameRGB的內存拷貝進文件,寫文件并不復雜;

調試過程的問題,首先是頭文件,ffmpeg 0.5.0的API已經拆分成好幾個獨立的庫,用pacman -Ql ffmpeg看了下文件分布,在include下好幾個目錄都是它的,看名字可以大概猜出他們的功能:

libavcodec:CODEC其實是Coder/Decoder的縮寫,也就是編碼解碼器;
libavdevice:對輸出輸入設備的支持;
libavformat:對音頻視頻格式的解析
libavutil:集項工具;
libpostproc:后期效果處理;
libswscale:視頻場景比例縮放、色彩映射轉換;

?

修改好頭文件包含,終于少了些not declared錯誤;

Martin B?hme那篇教程的代碼是使用g++編譯的,雖然代碼是C風格;在我修改了頭文件以及一些錯誤之后,居然鏈接出錯,av_register_all什么的函數統統undefined reference,想到ffmpeg是純C實現,以及以前用g++編譯GTK出現回呼函數找不到的經歷,相信又是g++的function mangling搞的,Google了一下,解決方法是把幾個頭文件包含在exterc "C"里面

代碼里面的錯誤還涉及一些結構成員的變化,比如

pFormatCtx->streams[i]->codec.codec_type==CODEC_TYPE_VIDEO

就有個類型錯誤,因為0.5.0里面的codec已經是指針,而不是結構了,要把.換成->,而相應地獲得解碼器指針,不再需要&:

pCodecCtx=&pFormatCtx->streams[videoStream]->codec;

原教程提到一個視頻碼率的rate的Hack:

// Hack to correct wrong frame rates that seem to be generated by some codecs<br /> if(pCodecCtx->frame_rate>1000 && pCodecCtx->frame_rate_base==1)<br /> pCodecCtx->frame_rate_base=1000;

好吧現在frame_rate跟frame_rate_base壓根就沒了,去掉算了;

最麻煩的變化還是原代碼里面的img_convert,就是解碼出一個幀的數據后,需要轉換成RGB格式才能寫入文件,然而這個函數在0.5.0里面徹底沒了。嘗試把img_convert完全注釋掉,把原始幀img_convert寫入文件,還算可喜的是能夠看到圖形,只是被分成三個畫面的通道圖形罷了;

Google了一番,還是回到 Stephen Dranger的An FFmpeg and SDL Tutorial第八節,介紹了swscale的接口,雖然里面的例子是轉換成SDL所用的YUV,而不是RGB;注意到其使用的參數PIX_FMT_YUV420P,跟img_convert所用的PIX_FMT_RGB24有相同前序,就試試照樣花虎了;
給sws_getContext傳入源格式的H/W,格式,輸出格式的H/W,PIX_FMT_RGB24格式,其中有個參數flags的解釋是 specify which algorithm and options to use for rescaling,是選擇在縮放過程中是使用線性還是雙立方等算法(參數文檔沒說,要找看源碼去),這里照抄了例子里面的SWS_BICUBIC。獲得這個SwsContext,類似python的re.compile,再用這個轉換器去轉換每一個幀,所以后面每次解碼了幀后,調用sws_scale,跟原來的img_convert倒是挺像;

也就是說,以后如果需要對視頻進行4:3跟16:9的轉換,就是在sws_getContext的參數里面做設置了;

最后整個程序正常,會把視頻的前5幀抓成圖像了,只是會有個小警告:

[swscaler @ 0x1d8f670]No accelerated colorspace conversion found.

?

估計是轉換成RGB,swscale里面沒有特別優化的算法?

目前發現程序運行的時候CPU占用很高,是因為程序還沒有控制幀速的時鐘,只會用盡CPU的性能不斷的讀取解碼;

PT修改過可編譯通過(ffmpeg 5.0/gcc 4.4.2/ubuntu 9.10)的前三個Tutorial代碼可在Google Code查看下載。(編譯方法請看各個文件頭部的注釋說明)

tags: ffmpeg, img_convert, libavcodec, libavformat, libswscale
posted in Programming by BOYPT

總結

以上是生活随笔為你收集整理的ffmpeg API 笔记:使用libavcodec/libavformat/libswscale ffmpeg例子的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。