1、FFmpeg 播放視頻的基本流程整理
播放流程: video.avi(Container) -> 打開獲得 Video_Stream -> 讀取Packet -> 解析到 Frame -> 顯示Frame。html
- Container:在音視頻中的容器,通常指的是一種特定的文件格式(如 AVI/QT ),裏面指明瞭所包含的音視頻,字幕等相關信息。
- Stream:媒體流,指時間軸上的一段連續數據,如一段聲音、視頻或字幕數據。
- Packet:Stream中的Raw數據,包含了能夠被解碼成方便咱們最後在應用程序中操做的幀的原始數據。
- Frame:Stream中的一個數據單元。
- Codec:編解碼器(Code 和 Decode),如 Divx和 MP3,以幀爲單位實現壓縮數據和原始數據之間的相互轉換。
2、FFmpeg 各個結構體及相關方法流程整理
1. AVCodec
AVCodec -- 編解碼器,採用鏈表維護,每個都有其對應的名字、類型、CodecID和對數據進行處理的編解碼函數指針。數組
- avcodec_find_decoder/avcodec_find_encoder :根據給定的codec id或解碼器名稱從系統中搜尋並返回一個AVCodec結構的指針
- avcodec_alloc_context3:根據 AVCodec 分配合適的 AVCodecContext
- avcodec_open/avcodec_open2/avcodec_close :根據給定的 AVCodec 打開對應的Codec,並初始化 AVCodecContext/ 關閉Codec
- avcodec_alloc_frame:分配編解碼須要的 AVFrame 結構
- avcodec_decode_video/avcodec_decode_video2 :解碼一個視頻幀,輸入數據在AVPacket結構中,輸出數據在AVFrame結構中
- avcodec_decode_audio4:解碼一個音頻幀。輸入數據在AVPacket結構中,輸出數據在AVFrame結構中
- avcodec_encode_video/avcodec_encode_video2 :編碼一個視頻幀,輸入數據在AVFrame結構中,輸出數據在AVPacket結構中
2. AVCodecContext
AVCodecContext -- 和具體媒體數據相關的編解碼器上下文,保存AVCodec指針和與codec相關的數據,包含了流中所使用的關於編解碼器的全部信息ide
- codec_name[32]、codec_type(AVMediaType)、codec_id(CodecID)、codec_tag:編解碼器的名字、類型(音頻/視頻/字幕等)、ID(H264/MPEG4等)、FOURC等信息
- hight/width,coded_width/coded_height: Video的高寬
- sample_fmt:音頻的原始採樣格式, 是 SampleFormat 枚舉
- time_base:採用分數(den/num)保存了幀率的信息
3. AVFrame
- data/linesize:FFMpeg內部以平面的方式存儲原始圖像數據,即將圖像像素分爲多個平面(R/G/B或Y/U/V)數組
- data數組:其中的指針指向各個像素平面的起始位置,編碼時須要用戶設置數據
- linesize數組 :存放各個存貯各個平面的緩衝區的行寬,編碼時須要用戶設置數據
- key_frame:該圖像是不是關鍵幀,由 libavcodec 設置
- pict_type:該圖像的編碼類型:Intra(1)/Predicted(2)/Bi-dir(3) 等,默認值是 NONE(0),其值由libavcodec設置
- pts:呈現時間,編碼時由用戶設置
- quality:從1(最好)到FF_LAMBDA_MAX(256*128-1,最差),編碼時用戶設置,默認值是0
- nterlaced_frame:代表是不是隔行掃描的,編碼時用戶指定,默認0
4. AVFormatContext
AVFormatContext -- 格式轉換過程當中實現輸入和輸出功能、保存相關數據的主要結構,描述了一個媒體文件或媒體流的構成和基本信息函數
- nb_streams/streams :AVStream結構指針數組, 包含了全部內嵌媒體流的描述,其內部有 AVInputFormat + AVOutputFormat 結構體,來表示輸入輸出的文件格式
- avformat_open_input:建立並初始化部分值,但其餘一些值(如 mux_rate、key 等)須要手工設置初始值,不然可能出現異常
- avformat_alloc_output_context2:根據文件的輸出格式、擴展名或文件名等分配合適的 AVFormatContext 結構
5. AVPacket
AVPacket -- 暫存解碼以前的媒體數據(一個音/視頻幀、一個字幕包等)及附加信息(解碼時間戳、顯示時間戳、時長等),主要用於創建緩衝區並裝載數據。學習
- data/size/pos: 數據緩衝區指針、長度和媒體流中的字節偏移量
- flags:標誌域的組合,1(AV_PKT_FLAG_KEY)表示該數據是一個關鍵幀, 2(AV_PKT_FLAG_CORRUPT)表示該數據已經損壞
- destruct:釋放數據緩衝區的函數指針,其值可爲 [av_destruct_packet]/av_destruct_packet_nofree, 會被 av_free_packet 調用
6. AVStream
AVStream -- 描述一個媒體流,其大部分信息可經過 avformat_open_input 根據文件頭信息肯定,其餘信息可經過 avformat_find_stream_info 獲取,典型的有 視頻流、中英文音頻流、中英文字幕流(Subtitle),可經過 av_new_stream、avformat_new_stream 等建立。編碼
- index:在AVFormatContext中流的索引,其值自動生成(AVFormatContext::streams[index])
- nb_frames:流內的幀數目
- time_base:流的時間基準,是一個實數,該流中媒體數據的pts和dts都將以這個時間基準爲粒度。一般,使用av_rescale/av_rescale_q能夠實現不一樣時間基準的轉換
- avformat_find_stream_info:獲取必要的編解碼器參數(如 AVMediaType、CodecID ),設置到 AVFormatContext::streams[i]::codec 中
- av_read_frame:從多媒體文件或多媒體流中讀取媒體數據,獲取的數據由 AVPacket 來存放
- av_seek_frame:改變媒體文件的讀寫指針來實現對媒體文件的隨機訪問,一般支持基於時間、文件偏移、幀號(AVSEEK_FLAG_FRAME)的隨機訪問方式
3、FFmpeg 學習教程及資源整理
1. 英文的入門教材(有些過期)
地址:http://dranger.com/ffmpeg/ffmpeg.htmlspa
2. 使用FFMpeg進行H264編碼
地址:https://www.cnblogs.com/billcoco/archive/2012/06/18/2553948.html指針
3. FFMpeg寫MP4文件例子分析
地址:http://www.cnblogs.com/billcoco/archive/2012/06/18/2553939.htmlcode
4、後續計劃
目前針對FFmepg的最基本的知識已經瞭解,後續要結合相應的開發實戰來進行更深一步的學習。orm