如何利用日益強大的硬件來實現高效的編解碼有則非比尋常的意義,對於開發者來講,面對日益增長的不一樣硬件,帶來的不一樣的接口,如何快速的使用和對接,自己就是一個問題,還好ffmpeg爲了咱們提供很是好的解決方案,徹底不用去關心底層的實現,一切面向接口的良好體現。linux
static const char *const hw_type_names[] = { [AV_HWDEVICE_TYPE_CUDA] = "cuda", //CUDA是Nvidia出的一個GPU計算庫 [AV_HWDEVICE_TYPE_DRM] = "drm", //DRM 是linux 下的圖形渲染架構(Direct Render Manager) [AV_HWDEVICE_TYPE_DXVA2] = "dxva2",//微軟dx套件,使用D3D9 [AV_HWDEVICE_TYPE_D3D11VA] = "d3d11va",//微軟dx套件,使用D3D11 [AV_HWDEVICE_TYPE_OPENCL] = "opencl",//第一個面向異構系統(此係統中可由CPU,GPU或其它類型的處理器架構組成)的並行編程的開放式標準。面向GPU編程 [AV_HWDEVICE_TYPE_QSV] = "qsv",//英特爾Quick Sync Video,號稱地球最強 [AV_HWDEVICE_TYPE_VAAPI] = "vaapi", //Video Acceleration Api,UNINX下的編碼接口,intel提供 [AV_HWDEVICE_TYPE_VDPAU] = "vdpau", //Video Decode and Presentation API for Unix ,NVIDIA提供的 [AV_HWDEVICE_TYPE_VIDEOTOOLBOX] = "videotoolbox", // mac iOS [AV_HWDEVICE_TYPE_MEDIACODEC] = "mediacodec", // Android };
ffmpeg -hwaccels編程
描述硬件frame的一個pool,包括大小,格式,AVHWDeviceContext,長/寬等內容api
void av_register_all(void) { ff_thread_once(&av_format_next_init, av_format_init_next); //保證多線程下只執行一次,屏蔽不一樣平臺的多線程代碼差別,不一樣的平臺下映射到不一樣線程庫中的pthread_once函數 } #define PTHREAD_ONCE_INIT {0, _FMUTEX_INITIALIZER} #define AV_ONCE_INIT PTHREAD_ONCE_INIT static AVOnce av_format_next_init = AV_ONCE_INIT; //實際上av_format_next_init就是{0} static void av_format_init_next(void) { //輸入輸出結構封裝成鏈表,加鎖處理 AVOutputFormat *prevout = NULL, *out; AVInputFormat *previn = NULL, *in; ff_mutex_lock(&avpriv_register_devices_mutex); for (int i = 0; (out = (AVOutputFormat*)muxer_list[i]); i++) { if (prevout) prevout->next = out; prevout = out; } if (outdev_list) { for (int i = 0; (out = (AVOutputFormat*)outdev_list[i]); i++) { if (prevout) prevout->next = out; prevout = out; } } for (int i = 0; (in = (AVInputFormat*)demuxer_list[i]); i++) { if (previn) previn->next = in; previn = in; } if (indev_list) { for (int i = 0; (in = (AVInputFormat*)indev_list[i]); i++) { if (previn) previn->next = in; previn = in; } } ff_mutex_unlock(&avpriv_register_devices_mutex); } //h264的AVOutputFormat結構 AVOutputFormat ff_h264_muxer = { .name = "h264", .long_name = NULL_IF_CONFIG_SMALL("raw H.264 video"), .extensions = "h264,264", .audio_codec = AV_CODEC_ID_NONE, .video_codec = AV_CODEC_ID_H264, .write_header = force_one_stream, .write_packet = ff_raw_write_packet, .check_bitstream = h264_check_bitstream, .flags = AVFMT_NOTIMESTAMPS, };
經過hw_device_setup_for_encode/hw_device_setup_for_decode進行設置,和4.x以前差別較大。多線程
查找hw_devices裏面的解碼器。架構