Ffmpeg 編碼實戰!

一. 讀取 YUV 文件並編碼成 H264 的 DEMO 介紹:

本次的 DEMO 是通過讀取 YUV 文件,並利用 FFMPEG 編碼成 H264 格式並輸出到文件上面,保存的格式是 ·xxxx.h264 的文件。

二. 代碼模塊的講解:

要注意:這裏的講解忽略了文件創建部分,只講重點的讀取 YUV 數據和編碼過程。

2.1. 初始化 AVFrame 並進行賦值

AVFrame 是指未壓縮前的音視頻原始數據,首先要 av_frame_alloc 對 AVframe 進行初始化分配工作。分配完 AVFrame 之後,對每一個成員變量進行賦值。首先,先用 av_image_fill_arrays(av_image_fill_arrays 的主要功能是根據圖像參數初始化 avframe 的數據指針) 對 avframe 的 data 成員變量進行賦值,另外還要對 AVFrame 的 width、height、圖像格式 (format) 等進行賦值。

2.2. 初始化編碼器

上面的代碼主要是初始化編碼器的工作,這裏要用到兩個結構體成員。一個是 AVCodec(編碼器)、AVCodecContext(編碼器上下文),AVCodec 需要用 av_codec_find_encoder 找到對應的編碼器,並使用這個編碼器 (AVCodec) 去創建編碼器上下文(AVCodecContext),使用的 API 是 avcodec_alloc_context3

創建完 AVCodecContext 上下文之後,對其成員變量進行賦值。這些成員變量包括:bit_rate(碼率)、width(長度)、height(高度)、time_base(時間基)、framerate(幀率)、gop_size(GOP 關鍵幀間隔)、max_b_frames(B 幀的數量)、pix_fmt(原始數據格式)。設置完之後,使用 avcodec_open2 把編碼器上下文和編碼器相互關聯起來。

2.3. 讀取每一幀 YUV 原始數據

使用 fread 去讀取每一幀 YUV 數據,對於 YUV 視頻原始數據每一幀的大小是:width * height * 3 /2。讀取每一幀數據後, 就要把讀到的數據向 avframe 的 data 進行賦值,avrame 的 data 的數據拷貝需要向 Y,U,V 三個變量分別賦值。frame_in->data[0] 指的是 Y 變量frame_in->data[1] 指的是 U 變量frame_in->data[2] 指的是 V 變量。還有一點注意的是,對於 AVFrame 還需要對 pts 進行疊加,否則畫面質量將會非常模糊。

2.4. 將每一幀原始數據進行 H264 編碼並保存

使用 avcodec_encode_video2 的 API 對每一幀 AVFrame 進行 H264 編碼壓縮,並把對應的 H264 數據存儲到文件裏面。

三. 整體代碼顯示:

四. 演示效果:

上圖這個是編碼出來的 H264 的文件,並用 ffplay 播放出來

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/6JKIJq_RMH_Fo28qIrNKVg