6.AVCodecContext和AVCodec

AVCodecContext 
AVCodecContext 結構表示程序運行的當前 Codec 使用的上下文,着重於全部 Codec 共有的屬性(而且是在程序運行時才能肯定其值)和關聯其餘結構的字段。
  • extradata 和 extradata_size 兩個成員表述了相應 Codec 使用的私有數據;
  • codec成員關聯相應的編解碼器;
  • priv_data 成員關聯各個具體編解碼器獨有的屬性 context,與 AVCodec 結構中的 priv_data_size 配對使用。
typedef struct AVCodecContext
{
enum AVMediaType codec_type; /* see AVMEDIA_TYPE_xxx */
const struct AVCodec *codec; //指向相應的解碼器,如: ff_h264_decoder
enum AVCodecID codec_id; /* see AV_CODEC_ID_xxx */
void *priv_data;//指向具體相應的解碼器的 context,如 H264Context
 
int bit_rate;
int frame_number;
 
int thread_count; //編解碼時的線程數量,由用戶設置,與CPU核心數有關,最佳效果通常設置爲CPU核心數*2.
 
AVRational time_base; //時間的基準單位
 
unsigned char *extradata;//擴展數據,如 mov 格式-> audio trak ->aac -> esds 格式中的附加解碼信息、H.264解碼器的存儲SPS,PPS信息等.
 
int extradata_size;//擴展數據的 size
 
int width, height; //視頻的原始的寬度與高度,僅針對視頻
 
enum PixelFormat pix_fmt;//視頻一幀圖像的格式,如 YUV420
 
 
int sample_rate; //採樣率(僅音頻)。
int channels;
//聲道數(僅音頻)。
enum AVSampleFormat sample_fmt;
//音頻採樣格式,編碼:由用戶設置。解碼:由libavcodec設置。
int frame_size;
//音頻幀中每一個聲道的採樣數。編碼:由libavcodec在avcodec_open2()中設置。 解碼:能夠由一些解碼器設置以指示恆定的幀大小.
int frame_number;
//幀計數器,由libavcodec設置。解碼:從解碼器返回的幀的總數。編碼:到目前爲止傳遞給編碼器的幀的總數。
uint64_t channel_layout;
//音頻聲道佈局。編碼:由用戶設置。解碼:由用戶設置,可能被libavcodec覆蓋。
enum AVAudioServiceType audio_service_type;
//音頻流傳輸的服務類型。編碼:由用戶設置。解碼:由libavcodec設置。 int bits_per_sample; int block_align; //公共操做函數 int (*alloc_frame)(AVCodecContext *avctx, AVFrame *frame); int (*start_frame)(AVCodecContext *avctx, const uint8_t *buf, uint32_t buf_size); int (*decode_params)(AVCodecContext *avctx, int type, const uint8_t *buf, uint32_t buf_size); int (*decode_slice)(AVCodecContext *avctx, const uint8_t *buf, uint32_t buf_size); int (*end_frame)(AVCodecContext *avctx); }AVCodecContext;

其中codec成員結構體爲AVCodec.數據結構

AVCodec
AVCodec 是相似 COM 接口的數據結構,表示音視頻編解碼器,着重於功能函數.
  • next 成員用於把全部支持的編解碼器鏈接成鏈表,便於遍歷查找;
  • id 肯定惟 一編 解 碼器 ;
  • priv_data_size 表示具 體 的 Codec 對應的 Context 結構大 小 .
typedef struct AVCodec
{
 
const char *name;// 標示 Codec 的名字, 好比, "h264" "h263" 等。
const char *long_name; //表示Codec的長名字,好比h264的長名字爲"H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10"
enum AVMediaType type; // 標示 Codec 的類型,有 video , audio ,字幕等類型。
enum AVCodecID id; // 標示 Codec 的 ID,有 AV_CODEC_ID_H264等。
 
int priv_data_size; // 標示具體的 Codec 對應的 Context 的 size,好比h264的等於sizeof(H264Context)
 
struct AVCodec *next; //以鏈表的形式指向下一個Codec(ID+1)
 
// 如下標示 Codec 對外提供的操做,每一種解碼器都會實現這些操做。
int(*init)(AVCodecContext*);
int(*encode)(AVCodecContext *, uint8_t *buf, int buf_size, void *data);
int(*close)(AVCodecContext*);
int(*decode)(AVCodecContext *, void *outdata, int *outdata_size, uint8_t *buf, int buf_size);
 
}AVCodec;

H264 的主要結構的初始化以下:ide

AVCodec ff_h264_decoder = {
.name = "h264",
.long_name = NULL_IF_CONFIG_SMALL("H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10"),
.type = AVMEDIA_TYPE_VIDEO,
.id = AV_CODEC_ID_H264,
.priv_data_size = sizeof(H264Context),
.init = h264_decode_init,
.close = h264_decode_end,
.decode = h264_decode_frame,
.capabilities = /*AV_CODEC_CAP_DRAW_HORIZ_BAND |*/ AV_CODEC_CAP_DR1 |
AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SLICE_THREADS |
AV_CODEC_CAP_FRAME_THREADS,
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_EXPORTS_CROPPING |
FF_CODEC_CAP_ALLOCATE_PROGRESS | FF_CODEC_CAP_INIT_CLEANUP,
.flush = h264_decode_flush,
.update_thread_context = ONLY_IF_THREADS_ENABLED(ff_h264_update_thread_context),
.profiles = NULL_IF_CONFIG_SMALL(ff_h264_profiles),
.priv_class = &h264_class,
}

打開一個視頻解碼器示例函數

videoStream = av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0);//獲取視頻流
AVCodec *vcodec = avcodec_find_decoder(ic->streams[videoStream]->codecpar->codec_id);//獲取codec
AVCodecContext *vc = avcodec_alloc_context3(vcodec); //構造AVCodecContext ,並將vcodec填入AVCodecContext中
avcodec_parameters_to_context(vc, ic->streams[videoStream]->codecpar); //初始化AVCodecContext
int ret = avcodec_open2(vc, NULL,NULL); //打開解碼器,因爲以前調用avcodec_alloc_context3(vcodec)初始化了vc,那麼codec(第2個參數)能夠填NULL
相關文章
相關標籤/搜索