最簡單的基於FFMPEG的轉碼程式__ffmpeg

來源:互聯網
上載者:User

本文介紹一個簡單的基於FFmpeg的轉碼器。它可以將一種視頻格式(包括封轉格式和編碼格式)轉換為另一種視頻格式。轉碼器在視音頻編解碼處理的程式中,屬於一個比較複雜的東西。因為它結合了視頻的解碼和編碼。一個視頻播放器,一般只包含解碼功能;一個視頻編碼工具,一般只包含編碼功能;而一個視頻轉碼器,則需要先對視頻進行解碼,然後再對視頻進行編碼,因而相當於解碼器和編碼器的結合。下圖例舉了一個視頻的轉碼流程。輸入視頻的封裝格式是FLV,視頻編碼通訊協定是H.264,音頻編碼通訊協定是AAC;輸出視頻的封裝格式是AVI,視頻編碼通訊協定是MPEG2,音頻編碼通訊協定是MP3。從流程中可以看出,首先從輸入視頻中分離出視頻碼流和音頻壓縮碼流,然後分別將視頻碼流和音頻碼流進行解碼,擷取到非壓縮的像素資料/音頻採樣資料,接著將非壓縮的像素資料/音頻採樣資料重新進行編碼,獲得重新編碼後的視頻碼流和音頻碼流,最後將視頻碼流和音頻碼流重新封裝成一個檔案。

 

本文介紹的視頻轉碼器正是使用FFMPEG類庫從編程的角度實現了上述流程。該例子是從FFmpeg的例子改編的,平台是VC2010,類庫版本是2014.5.6。 流程圖(2014.9.29更新)

下面附兩張使用FFmpeg轉碼視頻的流程圖。圖中使用淺綠色標出了視頻的編碼、解碼函數。從代碼中可以看出,使用了AVFilter的不少東西,因此建議先學習AVFilter的內容後再看這個轉碼器的原始碼。

PS:實際上,轉碼器不是一定依賴AVFilter的。因此打算有時間對這個轉碼器進行進一步的簡化,使學習的人無需AVFilter的基礎也可以理解轉碼器。


簡單介紹一下流程中各個函數的意義:
open_input_file():開啟輸入檔案,並初始化相關的結構體。
open_output_file():開啟輸出檔案,並初始化相關的結構體。
init_filters():初始化AVFilter相關的結構體。
av_read_frame():從輸入檔案中讀取一個AVPacket。
avcodec_decode_video2():解碼一個視頻AVPacket(儲存H.264等壓縮碼流資料)為AVFrame(儲存YUV等非壓縮的像素資料)。
avcodec_decode_video4():解碼一個音頻AVPacket(儲存MP3等壓縮碼流資料)為AVFrame(儲存PCM採樣資料)。
filter_encode_write_frame():編碼一個AVFrame。
flush_encoder():輸入檔案讀取完畢後,輸出編碼器中剩餘的AVPacket。

以上函數中open_input_file(),open_output_file(),init_filters()中的函數在其他文章中都有所敘述,在這裡不再重複:

open_input_file()可參考:100行代碼實現最簡單的基於FFMPEG+SDL的視頻播放器(SDL1.x)

open_output_file()可參考:最簡單的基於FFMPEG的視頻編碼器(YUV編碼為H.264)

init_filters()可參考:最簡單的基於FFmpeg的AVfilter例子(浮水印疊加)

在這裡介紹一下其中編碼的函數filter_encode_write_frame()。filter_encode_write_frame()函數的流程如下圖所示,它完成了視頻/音訊編碼功能。

PS:視頻和音訊編碼流程中除了編碼函數avcodec_encode_video2()和avcodec_encode_audio2()不一樣之外,其他部分幾乎完全一樣。


簡單介紹一下filter_encode_write_frame()中各個函數的意義:

av_buffersrc_add_frame():將解碼後的AVFrame加入Filtergraph。

av_buffersink_get_buffer_ref():從Filtergraph中取一個AVFrame。

avcodec_encode_video2():編碼一個視頻AVFrame為AVPacket。

avcodec_encode_audio2():編碼一個音頻AVFrame為AVPacket。

av_interleaved_write_frame():將編碼後的AVPacket寫入檔案。


代碼

貼上代碼

  [cpp]  view plain copy /*   *最簡單的基於FFmpeg的轉碼器   *Simplest FFmpeg Transcoder   *   *雷霄驊 Lei Xiaohua   *leixiaohua1020@126.com   *中國傳媒大學/數字電視技術   *Communication University of China / DigitalTV Technology   *http://blog.csdn.net/leixiaohua1020   *   *本程式實現了視頻格式之間的轉換。是一個最簡單的視頻轉碼程式。   *   */       #include "stdafx.h"   extern "C"   {   #include "libavcodec/avcodec.h"   #include "libavformat/avformat.h"   #include "libavfilter/avfiltergraph.h"   #include "libavfilter/avcodec.h"   #include "libavfilter/buffersink.h"   #include "libavfilter/buffersrc.h"   #include "libavutil/avutil.h"   #include "libavutil/opt.h"   #include "libavutil/pixdesc.h"   };               static AVFormatContext *ifmt_ctx;   static AVFormatContext *ofmt_ctx;   typedef struct FilteringContext{       AVFilterContext*buffersink_ctx;       AVFilterContext*buffersrc_ctx;       AVFilterGraph*filter_graph;   } FilteringContext;   static FilteringContext *filter_ctx;   static int open_input_file(const char *filename)   {     

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.