《音视频应用开发系列文章目录》
enum AVHWDeviceType {
AV_HWDEVICE_TYPE_NONE,
AV_HWDEVICE_TYPE_VDPAU,
AV_HWDEVICE_TYPE_CUDA,
AV_HWDEVICE_TYPE_VAAPI,
AV_HWDEVICE_TYPE_DXVA2,
AV_HWDEVICE_TYPE_QSV,
AV_HWDEVICE_TYPE_VIDEOTOOLBOX,
AV_HWDEVICE_TYPE_D3D11VA,
AV_HWDEVICE_TYPE_DRM,
AV_HWDEVICE_TYPE_OPENCL,
AV_HWDEVICE_TYPE_MEDIACODEC,
};
std::vector get_vdec_support_hwdevices() {
std::vector hwdevs;
hwdevs.clear();
enum AVHWDeviceType type = AV_HWDEVICE_TYPE_NONE;
while ((type = av_hwdevice_iterate_types(type)) != AV_HWDEVICE_TYPE_NONE) {
hwdevs.push_back(av_hwdevice_get_type_name(type));
}
return hwdevs;
}
avformat_open_input ->
avformat_find_stream_info ->
avcodec_open2 ->
LOOP:
av_read_frame ->
avcodec_send_packet ->
avcodec_receive_frame
相比于CPU解码同样都是使用AVCodec为解码器结构体。GPU解码需要多填充AVCodec两个成员get_format和hw_device_ctx。
get_format 用于获取硬件像素格式的回调函数
hw_device_ctx 硬件解码器设备上下文
avformat_open_input ->
avformat_find_stream_info ->
avcodec_get_hw_config -> (从AVCodec获取对应硬件编码器的配置以取得hw_pix_fmt)
av_hwdevice_ctx_create -> (创建解码器设备上下文,用于填充AVCodec的hw_device_ctx)
register AVCodecContext's callback function:get_format -> (注册回调函数,在解码的时候会调用)
avcodec_open2 ->
LOOP:
av_read_frame ->
avcodec_send_packet ->
avcodec_receive_frame ->
av_hwframe_transfer_data (从GPU拷贝数据到CPU或则从CPU拷贝数据到GPU)
static enum AVPixelFormat get_hw_format(AVCodecContext *ctx, const enum AVPixelFormat *pix_fmts) {
const enum AVPixelFormat *p;
for (p = pix_fmts; *p != -1; p++) {
if (*p == g_hw_pix_fmt)
return *p;
}
return AV_PIX_FMT_NONE;
}
参考《FFmpeg拉流器》