1. 程式人生 > >視訊編解碼的理論和實踐2:Ffmpeg視訊編解碼

視訊編解碼的理論和實踐2:Ffmpeg視訊編解碼

近幾年,視訊編解碼技術在理論及應用方面都取得了重大的進展,越來越多的人想要了解編解碼技術。因此,網易雲信研發工程師為大家進行了歸納梳理,從理論及實踐兩個方面簡單介紹視訊編解碼技術。

 

相關閱讀推薦

視訊直播關鍵技術:流暢、擁塞和延時追趕

視訊直播技術詳解:直播的推流排程

音視訊通話:小議音訊處理與壓縮技術

視訊編解碼的理論和實踐1:基礎知識介紹

 

1、Ffmpeg介紹

視訊編解碼的理論和實踐1:基礎知識介紹介紹了視訊編碼的基礎知識,本篇文章,我們一起看看實際應用中的視訊編碼是如何操作的。

在實際工程專案中,ffmpeg是應用最多的多媒體處理框架,它提供了音視訊採集、編解碼、影象處理,格式轉換等功能,並且擁有很強的擴充套件能力,通過ffmpeg可以很容易整合第三方庫(例如:x264、openh264等),通過這種能力,它可以實現更強大的功能。Ffmpeg由下面幾個部分構成:

Libavformat:音視訊格式處理

Libavcodec:音視訊編解碼

Libavfilter:音視訊濾鏡

Libavdevice:音視訊裝置採集

Libswscale:影象縮放、轉換

Libswresample:音訊重取樣

Ffmpeg:一個命令列的轉碼工具

Ffplay:一個命令列播放器

Ffprobe:簡單的媒體格式分析工具

 

2、Ffmpeg視訊編碼

視訊編碼是ffmpeg提供的基本功能之一,通過ffmpeg可以很容易實現視訊編碼操作。使用ffmpeg進行視訊編碼之前需要把x264、openh264等第三方編解碼庫整合到ffmpeg中才能使用。編碼步驟如下:

  1. 註冊編碼器
  2. 根據名字或者ID查詢你想使用的編碼器(例如x264、x265、openh264等)
  3. 建立一個編碼器上下文物件
  4. 在編碼器上下文物件中設定編碼器引數
  5. 開啟編碼器
  6. 讀取一幀影象進行編碼,一直重複該過程,直到處理結束
  7. 關閉編碼器

示例程式碼如下:

avcodec_register_all(); // 註冊所有可用的編碼器

codec = avcodec_find_encoder_by_name(“libx264”); // 查詢編碼器

ctx = avcodec_alloc_context3(codec); // 建立編碼器上下文

ctx->width = 1280; // 設定編碼器引數

ctx->height = 720;

// ….其他的引數設定

avcodec_open2(ctx, codec, NULL); // 開啟編碼器

while(read_frame(frame)){

      AVPacket pkt; // 存放編碼之後的資料

      int got_output = 0; // 是否成功編碼得到一個影象

      avcodec_encode_video2(ctx, &pkt, frame, &got_output); // 編碼

      if(got_output){

           // 得到編碼後的資料,進行後續操作

}

}

avcodec_free_context(&ctx); // 關閉編碼器

      可以看到,ffmpeg隱藏了大部分的編碼細節,呼叫者不需要了解預測、變換、量化、熵編碼等細節,這些細節都已經被ffmpeg封裝好了,開發者只要把編碼引數設定好,然後呼叫相關的介面函式,即可實現視訊編碼功能。當然,這知識最基本的編碼功能,要想在畫面質量和壓縮率之間取得平衡,必須瞭解視訊編碼的細節,然後設定相應的引數

 

3、Ffmpeg視訊解碼

Ffmpeg自帶了H264的視訊解碼器,開發者可選擇直接使用ffmpeg自帶的H264解碼器或者第三方的解碼庫進行視訊解碼。和視訊編碼一樣,解碼操作的大部分細節都已經被ffmpeg隱藏起來了,開發者只需要設定好相關的解碼引數,然後呼叫介面函式就可以實現解碼功了。解碼流程如下:

  1. 註冊解碼器
  2. 查詢解碼器
  3. 建立解碼器上下文物件
  4. 設定解碼引數
  5. 開啟解碼器 
  6. 讀取資料進行解碼,直到結束
  7. 關閉解碼器

程式碼示例如下:

avcodec_register_all(); //註冊解碼器

codec = avcodec_find_decoder_by_name(“h264”); // 查詢解碼器

ctx = avcodec_alloc_context3(codec); // 建立解碼器上下文物件

//…設定解碼引數

avcodec_open2(ctx, codec, NULL); // 開啟解碼器

while(read_packet(pkt)){

      AVFrame frame; // 存放解碼之後的影象資料

      int got_frame = 0;

      avcodec_decode_video2(ctx, frame, &got_frame, pkt); // 解碼

      if(got_frame){

           // 解碼得到一幀影象,進行後續操作…

      }

}

avcodec_free_context(&ctx); // 關閉解碼器

 

可以看到ffmpeg是個非常強大的多媒體處理框架,通過ffmpeg我們可以很容易進行音視訊方面的處理。上面介紹的只是ffmpeg的冰山一角,要想熟練使用ffmpeg,必須花很多時間去熟練使用它。

 

更多即時通訊、音視訊技術的乾貨文章,請關注網易雲信部落格