Código de almacén: https://gitee.com/liudegui/ffmpeg_decode_video
ffmpeg_decode_video
- Use ffmpeg para decodificar el módulo de video, admita 3 tipos de decodificación: decodificación de cpu, decodificación de cuda en la plataforma amd64 y decodificación de Nvmpi en la plataforma NX
- La biblioteca de paquetes solo depende de ffmpeg, y OpenCV se usa en el programa de prueba, que se puede usar para enviar marcos al programa de detección de opencv
árbitro:
- https://github.com/FFmpeg/FFmpeg/blob/master/doc/examples/hw_decode.c
- referencia: https://github.com/chinahbcq/ffmpeg_hw_decode
descripción general
La biblioteca espera admitir el cambio entre los modos CUDA GPU y CPU en un solo código, y también puede elegir si solo decodificar fotogramas clave. Las principales ideas de diseño son las siguientes:
Determinar si se admite la decodificación GPU CUDA
bool support_hwdevice()
{
AVHWDeviceType type;
type = av_hwdevice_find_type_by_name(s_hwdevice_name);
if (type == AV_HWDEVICE_TYPE_NONE)
{
fprintf(stderr, "Device type %s is not supported.\n", s_hwdevice_name);
fprintf(stderr, "Available device types:");
while ((type = av_hwdevice_iterate_types(type)) != AV_HWDEVICE_TYPE_NONE)
fprintf(stderr, " %s", av_hwdevice_get_type_name(type));
fprintf(stderr, "\n");
return false;
}
return true;
}
Este método no se aplica a las máquinas que tienen una tarjeta gráfica pero que no admiten la aceleración de la solución de hardware, como algunas computadoras portátiles.
En este momento, la función también regresará , pero dicho error true
se informará al decodificar . Hardware is lacking required capabilities
inicialización
La función de inicialización init_ctx principalmente inicializa input_ctx y decoder_ctx para la decodificación.
Inicialización de decodificación GPU
ilustrar:
-
La caja oscura es la diferencia entre la decodificación por hardware y la decodificación por software.
-
La función de av_hwdevice_find_type_by_name() es encontrar el AVHWDeviceType correspondiente según el nombre.
-
AVHWDeviceType indica el tipo de API de aceleración de hardware, como AV_HWDEVICE_TYPE_CUDA es la API de aceleración proporcionada por nvidia.
-
Los nombres compatibles con av_hwdevice_find_type_by_name son los siguientes.
static const char *const hw_type_names[] = {
[AV_HWDEVICE_TYPE_CUDA] = "cuda",
[AV_HWDEVICE_TYPE_DRM] = "drm",
[AV_HWDEVICE_TYPE_DXVA2] = "dxva2",
[AV_HWDEVICE_TYPE_D3D11VA] = "d3d11va",
[AV_HWDEVICE_TYPE_OPENCL] = "opencl",
[AV_HWDEVICE_TYPE_QSV] = "qsv",
[AV_HWDEVICE_TYPE_VAAPI] = "vaapi",
[AV_HWDEVICE_TYPE_VDPAU] = "vdpau",
[AV_HWDEVICE_TYPE_VIDEOTOOLBOX] = "videotoolbox",
[AV_HWDEVICE_TYPE_MEDIACODEC] = "mediacodec",
};
- avcodec_get_hw_config: se utiliza para obtener la configuración de hardware AVCodecHWConfig compatible con el códec. Esto se utiliza para obtener el formato de píxel compatible con el hardware.
- av_hwdevice_ctx_create: av_hwdevice_ctx_create crea información de contexto relacionada con el dispositivo de hardware AVHWDeviceContext e inicializa el dispositivo de hardware.
decoder_ctx->get_format = get_hw_format
, get_hw_format es una función registrada con AVCodecContext para negociar el formato de píxel admitido.
Inicialización de decodificación de CPU
- La diferencia entre la inicialización de la decodificación de la CPU y la GPU es que se llama avcodec_find_decoder para encontrar un decodificador adecuado, y el tipo, la altura y el ancho se establecen para el contexto del decodificador.
descodificación
- Una diferencia entre la decodificación de GPU y la decodificación de CPU es que la GPU debe llamar av_hwframe_transfer_data, que copia la GPU en la CPU.
- av_hwframe_transfer_data: copia datos a una superficie de hardware, o copia datos de una superficie de hardware, es decir, copia datos entre GPU y CPU. Esto se usa para copiar de GPU a CPU.
Formato
- El tipo predeterminado de formato de datos después de leer la decodificación GPU desde el hardware, CUDA puede ser AV_PIX_FMT_NV12; y los datos decodificados por la CPU generalmente son datos YUV, como AV_PIX_FMT_YUV420P.
referencia
// ref:https://github.com/FFmpeg/FFmpeg/blob/master/doc/examples/hw_decode.c
// ref: https://github.com/chinahbcq/ffmpeg_hw_decode
// ref: https://www.jianshu.com/p/3ea9ef713211