一.avcodec_find_decoder
獲取解碼器。在使用之前必須保證所用到的解碼器已經注冊,最簡單的就是調用avcodec_register_all() 函數,就像之前注冊解封裝器的時候,也要注冊一下。。
AVCodec *avcodec_find_decoder(enum AVCodecID id);
// 查找解碼器,第一種方法就是直接通過ID號查找,這個ID號從哪里獲取呢?就像剛才我們解封裝之后,你可以發現我們的AVStream里面其實是有一個codecID, 那個ID號就是我們要用到的解碼器的ID號。當然如果本身知道格式的ID號,也可以直接傳進去(一般我們用h264,那這個codecID就是28)。找到這個解碼器,然后返回到AVCodec當中去。AVCodec當中存放的是解碼器格式的配置信息,並不代表最終要處理的解碼器。
AVCodec *avcodec_find_decoder_by_name(const char name);
// 除了通過解碼器的ID號來查找解碼器,還可能通過名字打開解碼器。例:avcodec_find_decoder_by_name(“h264_mediacodec”); // 用Android里面自帶的解碼模塊)
二.AVCodecContext 解碼器上下文
AVCodecContext *avcode_alloc_context3(const AVCodec *codec); // 申請AVCodecContext空間。需要傳遞一個編碼器,也可以不傳,但不會包含編碼器。
void avcodec_free_context(AVCodecContext **avctx); // 清理並AVCodecContext空間。
int avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options);
// 打開視頻解碼器。如果在 avcode_alloc_context3 的時候沒有傳解碼器,則在此需要進行傳遞,后面的options是可選參數。參見:libavcodec/options_table.h。
AVCodecContext 的常用參數:
int thread_count; // 用於配置解碼線程數
time_base // 時間基數。
三.avcodec_parameters_to_context
avcodec_parameters_to_context(codec, p)。該函數用於將流里面的參數,也就是AVStream里面的參數直接復制到AVCodecContext的上下文當中。
四. 打開音視頻解碼器示例
// 注冊解碼器 avcodec_register_all(); AVCodec *vc = avcodec_find_decoder(ic->streams[videoStream]->codecpar->codec_id); // 軟解 // vc = avcodec_find_decoder_by_name("h264_mediacodec"); // 硬解 if (!vc) { LOGE("avcodec_find_decoder[videoStream] failure"); return env->NewStringUTF(hello.c_str()); } // 配置解碼器 AVCodecContext *vct = avcodec_alloc_context3(vc); avcodec_parameters_to_context(vct, ic->streams[videoStream]->codecpar); vct->thread_count = 1; // 打開解碼器 int re = avcodec_open2(vct, vc, 0); if (re != 0) { LOGE("avcodec_open2 failure"); return env->NewStringUTF(hello.c_str()); }