inicio de la lectura de la documentación ffmpeg: https://trac.ffmpeg.org/wiki/HWAccelIntro y mejor respuesta How to use hardware acceleration with ffmpeg (y para Linux página de comprobación https://wiki.archlinux.org/index.php/Hardware_video_acceleration)
Cuando se utiliza FFmpeg la herramienta, la decodificación HW-asistida se habilita el uso a través de la opción de -hwaccel
, lo que permite una decodificador específico. Cada decodificador puede tener limitaciones específicas (por ejemplo, un decodificador H.264 solo puede admitir el perfil de referencia). La codificación asistida por HW se habilita mediante el uso de un codificador específico (por ejemplo h264_nvenc). El filtrado del proceso asistido por HW solo se admite en algunos filtros. Existen varias API de aceleración de hardware API, , algunas de las cuales son compatibles con hasta cierto punto por FFmpeg.
activación hwaccel fue controlado por código como (bit reformateado después de 2013 https://github.com/FFmpeg/FFmpeg/commit/08303d774132775d49d4ba767092de5d426f089d)
avctx->hwaccel = ff_find_hwaccel(avctx->codec->id, avctx->pix_fmt);
Por ejemplo, en libavcodec/mpeg12dec.c https://github.com/FFmpeg/FFmpeg/blob/6c7254722ad43712db5686feee8bf75c74d8635b/libavcodec/mpeg12dec.c
avctx->pix_fmt = mpeg_get_pixelformat(avctx);
avctx->hwaccel = ff_find_hwaccel(avctx->codec->id, avctx->pix_fmt);
El códec ff_find_hwaccel
cheques y PixelFormat par de imágenes y de todos los hwaccelerators disponibles.
AVHWAccel *ff_find_hwaccel(enum CodecID codec_id, enum PixelFormat pix_fmt)
{
AVHWAccel *hwaccel=NULL;
while((hwaccel= av_hwaccel_next(hwaccel))){
if ( hwaccel->id == codec_id
&& hwaccel->pix_fmt == pix_fmt)
return hwaccel;
}
return NULL;
}
Por ejemplo, dxva2 (https://en.wikipedia.org/wiki/DirectX_Video_Acceleration) tiene:
AVHWAccel mpeg2_dxva2_hwaccel = {
.name = "mpeg2_dxva2",
.type = AVMEDIA_TYPE_VIDEO,
.id = CODEC_ID_MPEG2VIDEO,
.pix_fmt = PIX_FMT_DXVA2_VLD,
.capabilities = 0,
.start_frame = start_frame,
.decode_slice = decode_slice,
.end_frame = end_frame,
.priv_data_size = sizeof(struct dxva2_picture_context),
};
Y libavutil/pixfmt.h
listas de todos los hw decodificadores/aceleradores apoyados por sus formatos de píxeles https://ffmpeg.org/doxygen/3.2/pixfmt_8h.html
AV_PIX_FMT_XVMC_MPEG2_MC - XVideo Motion Acceleration via common packet passing.
AV_PIX_FMT_XVMC_MPEG2_IDCT - undocumented
AV_PIX_FMT_XVMC - undocumented
AV_PIX_FMT_VDPAU_H264 - H.264 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers.
AV_PIX_FMT_VDPAU_MPEG1 - MPEG-1 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers.
AV_PIX_FMT_VDPAU_MPEG2 - MPEG-2 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers.
AV_PIX_FMT_VDPAU_WMV3 - WMV3 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers.
AV_PIX_FMT_VDPAU_VC1 - VC-1 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers.
AV_PIX_FMT_VAAPI_MOCO - HW acceleration through VA API at motion compensation entry-point, Picture.data[3] contains a vaapi_render_state struct which contains macroblocks as well as various fields extracted from headers.
AV_PIX_FMT_VAAPI_IDCT - HW acceleration through VA API at IDCT entry-point, Picture.data[3] contains a vaapi_render_state struct which contains fields extracted from headers.
AV_PIX_FMT_VAAPI_VLD - HW decoding through VA API, Picture.data[3] contains a VASurfaceID.
AV_PIX_FMT_VDPAU_MPEG4 - MPEG-4 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers.
AV_PIX_FMT_DXVA2_VLD - HW decoding through DXVA2, Picture.data[3] contains a LPDIRECT3DSURFACE9 pointer.
AV_PIX_FMT_VDPAU - HW acceleration through VDPAU, Picture.data[3] contains a VdpVideoSurface.
AV_PIX_FMT_VDA - HW acceleration through VDA, data[3] contains a CVPixelBufferRef.
AV_PIX_FMT_QSV - HW acceleration through QSV, data[3] contains a pointer to the mfxFrameSurface1 structure.
AV_PIX_FMT_MMAL - HW acceleration though MMAL, data[3] contains a pointer to the MMAL_BUFFER_HEADER_T structure.
AV_PIX_FMT_D3D11VA_VLD - HW decoding through Direct3D11, Picture.data[3] contains a ID3D11VideoDecoderOutputView pointer.
AV_PIX_FMT_CUDA - HW acceleration through CUDA. data[i] contain CUdeviceptr pointers exactly as for system memory frames.
La selección real de formatos de píxeles es en la función llamada antes de ff_find_hwaccel
, static enum PixelFormat mpeg_get_pixelformat(AVCodecContext *avctx)
de libavcodec/mpeg12dec.c
para mpeg1/2. En versiones anteriores de ffmpeg/libavcodec comprueba avctx->xvmc_acceleration
y/o avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU
o llama al avctx->get_format(avctx,ff_hwaccel_pixfmt_list_420);
para habilitar la decodificación hw en algunos casos.
En la versión más reciente (2017) y en varias funciones cercanas, haga la selección de hw coder https://github.com/FFmpeg/FFmpeg/blob/aff8cf18cb0b1fa4f2e3d163c3da2f25aa6d1906/libavcodec/mpeg12dec.c#L1189.
Básicamente: decodificador de hardware y su API (obsoleta XVMC, VDPAU, VA API, MS DXVA o MS Direct3D11 o videotoolbox) deben estar habilitadas en su acumulación de ffmpeg y supported by your hardware y su conductor/bibliotecas (muchos de ellos son de propiedad y debe haber descargado por separado). A veces, la opción -hwaccel
se debe dar a ffmpeg, o al plugin cargado. En Linux, puede usar los comandos vainfo
y vdpauinfo
para probar la disponibilidad y los perfiles compatibles con la mayoría de las API de decodificación de video hw estándar más populares.
archivo de entrada (para MPEG1/2) no debe ser en escala de grises, debe tener s->chroma_format
menos de 2 (4: 2: 0 Chroma subsampling, que es habitual para la norma ISO/IEC MPEG e ITU-T VCEG H.26x, pero no para MPEG-4 Parte 2 y no para alta 4: 4: 4 variantes de H.264/MPEG-4 AVC).
static const enum AVPixelFormat mpeg2_hwaccel_pixfmt_list_420[] = {
#if CONFIG_MPEG2_XVMC_HWACCEL
AV_PIX_FMT_XVMC,
#endif
#if CONFIG_MPEG_VDPAU_DECODER && FF_API_VDPAU
AV_PIX_FMT_VDPAU_MPEG2,
#endif
#if CONFIG_MPEG2_VDPAU_HWACCEL
AV_PIX_FMT_VDPAU,
#endif
#if CONFIG_MPEG2_DXVA2_HWACCEL
AV_PIX_FMT_DXVA2_VLD,
#endif
#if CONFIG_MPEG2_D3D11VA_HWACCEL
AV_PIX_FMT_D3D11VA_VLD,
#endif
#if CONFIG_MPEG2_VAAPI_HWACCEL
AV_PIX_FMT_VAAPI,
#endif
#if CONFIG_MPEG2_VIDEOTOOLBOX_HWACCEL
AV_PIX_FMT_VIDEOTOOLBOX,
#endif
AV_PIX_FMT_YUV420P,
AV_PIX_FMT_NONE
};
static const enum AVPixelFormat mpeg12_pixfmt_list_422[] = {
AV_PIX_FMT_YUV422P,
AV_PIX_FMT_NONE
};
static const enum AVPixelFormat mpeg12_pixfmt_list_444[] = {
AV_PIX_FMT_YUV444P,
AV_PIX_FMT_NONE
};
#if FF_API_VDPAU
static inline int uses_vdpau(AVCodecContext *avctx) {
return avctx->pix_fmt == AV_PIX_FMT_VDPAU_MPEG1 || avctx->pix_fmt == AV_PIX_FMT_VDPAU_MPEG2;
}
#endif
static enum AVPixelFormat mpeg_get_pixelformat(AVCodecContext *avctx)
{
Mpeg1Context *s1 = avctx->priv_data;
MpegEncContext *s = &s1->mpeg_enc_ctx;
const enum AVPixelFormat *pix_fmts;
if (CONFIG_GRAY && (avctx->flags & AV_CODEC_FLAG_GRAY))
return AV_PIX_FMT_GRAY8;
if (s->chroma_format < 2)
pix_fmts = avctx->codec_id == AV_CODEC_ID_MPEG1VIDEO ?
mpeg1_hwaccel_pixfmt_list_420 :
mpeg2_hwaccel_pixfmt_list_420;
else if (s->chroma_format == 2)
pix_fmts = mpeg12_pixfmt_list_422;
else
pix_fmts = mpeg12_pixfmt_list_444;
return ff_thread_get_format(avctx, pix_fmts);
}
static void setup_hwaccel_for_pixfmt(AVCodecContext *avctx)
{
// until then pix_fmt may be changed right after codec init
if (avctx->hwaccel
#if FF_API_VDPAU
|| uses_vdpau(avctx)
#endif
)
if (avctx->idct_algo == FF_IDCT_AUTO)
avctx->idct_algo = FF_IDCT_SIMPLE;
if (avctx->hwaccel && avctx->pix_fmt == AV_PIX_FMT_XVMC) {
Mpeg1Context *s1 = avctx->priv_data;
MpegEncContext *s = &s1->mpeg_enc_ctx;
s->pack_pblocks = 1;
#if FF_API_XVMC
FF_DISABLE_DEPRECATION_WARNINGS
avctx->xvmc_acceleration = 2;
FF_ENABLE_DEPRECATION_WARNINGS
#endif /* FF_API_XVMC */
}
}
¿Debo reemplazar el pix_fmt de avctx manualmente por PIX_FMT_DXVA2_VLD? Cuando miro el código de ffmpeg, solo veo leer este valor, nunca establecerlo. – ronag
Ningún archivo será formato PIX_FMT_DXVA2_VLD. Parece que no existe documentación en FFmpeg hwaccel ... – Maypeur
@Maypeur, la documentación es oficial ahora: https://trac.ffmpeg.org/wiki/HWAccelIntro, también consulte https://wiki.archlinux.org/index.php/Hardware_video_acceleration. Su pregunta no tiene detalles necesarios (versión de ffmpeg, sistema operativo Linux/Windows/Otro; ¿cuál es su decodificador hw y está instalado, cuál es su API, cuál es su archivo, cómo comenzó ffmpeg, funciona hw decode al iniciar 'ffmpeg' desde la línea de comandos) y no se puede responder. Pero mi respuesta original no era muy correcta (["no resuelve nada"] (http://stackoverflow.com/questions/23289157/#comment35652265_23289157)), así que actualicé un poco. – osgx