ffmpeg mediacodec
硬解初探
1
編譯:
ffmpeg
自3.1
版本加入了android mediacodec
硬解支持,解碼器如圖

硬件加速器如圖(還不清楚硬件加速器的功能)

編譯帶h264_mediacodec版本的庫需要開啟以下選項
--enable-jni
--enable-mediacodec
--enable-decoder=h264_mediacodec
--enable-hwaccel=h264_mediacodec
(不知道有什么用,還是開了)
2
使用:
首先在JNI_OnLoad
函數,或者使用解碼器之前調用
av_jni_set_java_vm(vm, NULL);
(位於libavcodec/jni.h
)
來設置java
虛擬機(反調mediacodec
時會用到)
其次,由於h264_mediacodec
解碼器和h264
解碼器
id
相同
所以,軟解時,通過
avcodec_find_decoder
(id
)來尋找解碼器
而想使用mediacodec
硬解時,使用
avcodec_find_decoder_by_name("h264_mediacodec");
尋找指定解碼器
之后所有步驟和軟解完全相同,不需要更改任何內容
3
暫時的現象和問題:
現象:
不知道是否和播放器本身架構設計和實現有關,對比h264
軟解和硬解,cpu
使用率並沒有明顯下降,多數下相差不大,有一部分視頻能出現5%-10%
的下降
但較為明顯提升的是
解碼速度
,解碼640X360
分辨率時,已有明顯區別(左圖軟解,右圖硬解,數字為每一幀解碼耗費時間,單位毫秒,左右兩圖時間並非一一對應,僅比較量級)
視頻為http://ips.ifeng.com/video19.ifeng.com/video09/2015/02/28/3019136-102-008-1929.mp4


解碼1920X1080
分辨率時,區別很大(左圖軟解,右圖硬解,數字為每一幀解碼耗費時間,單位毫秒,左右兩圖時間並非一一對應,僅比較量級)


問題:
軟解出來的數據格式為
YUV420P
,直接使用
libyuv
轉換即可;在我這台手機上硬解出來的數據格式為
NV
12
據網上博客所說,不同機器解碼出來的數據格式不盡相同,這就導致解碼出來后的數據,需要根據其類型來做轉化,使用
ffmpeg
自帶的轉換函數非常簡單通用,但是效率有待考察。
libyuv
中包含
neon
加速,但是不包含通用轉換函數,需要自行判斷類型,而且還不包含
ToRGBA
的函數,主要包含
ToARGB
的函數,
native window
顯示時,只支持
RGBA8888
,
RGBX8888
和
RGB656
,這樣會在轉換上增加了一些復雜度
這篇博客講述了android
在api21
之后,硬解指定格式的方法
附:
在libavcodec中的 mediacodec_common.c里面我找到了這個

注意ffmpeg里面也有jni.h,需要引入avcodec時加上路徑,然后mk文件里面不引入到avcodec這一級目錄。