Cómo aumentar la velocidad de decodificación de una transmisión de video en FFmpeg


Con la llegada de formatos de video pesados ​​como 4K (Ultra HD), el problema de la eficiencia de decodificación de transmisión de video se ha vuelto bastante relevante. En una computadora promedio, se deben tomar medidas especiales para poder procesar dicha transmisión de video en tiempo real. El artículo describe las posibles formas de aumentar la velocidad de decodificación de transmisiones de video en soluciones basadas en FFmpeg, y presenta los resultados de experimentos para medir la velocidad de decodificación para transmisiones de video 4K codificadas en H264 y HEVC (H265).




Tabla de contenido


  1. Tres formas de aumentar la velocidad de decodificación de la transmisión de video
    1.1. Conexión de flujos de trabajo adicionales en decodificadores estándar
    1.2. Conexión de la aceleración de hardware en decodificadores estándar
    1.3. Uso de decodificadores especiales que implementan decodificación en GPU
  2. Medición de la velocidad de decodificación
  3. Notas sobre decodificadores QSV
  Recursos




1. Tres formas de aumentar la velocidad de decodificación de una transmisión de video


Consideraremos tres formas de aumentar la velocidad de decodificación de una transmisión de video.


  1. Conexión de hilos de trabajo adicionales (hilos) en decodificadores estándar.
  2. Conexión de aceleración de hardware (HW Acceleration) en decodificadores estándar.
  3. Uso de decodificadores especiales que implementan la decodificación en GPU.

CPU, .


, FFmpeg. - : — Windows 10, — Intel i5 8400 2.80 (6 hyper-threading), — Intel UHD Graphics 630, — 16 , FFmpeg 4.2.1, zeranoe.


FFmpeg , .



1.1.


(, , ) , . avcodec_open2() thread_count AVCodecContext . — threads , avcodec_open2().


, , (h264, hevc, vp9) , theora .


-threads.



1.2.


FFmpeg . FFmpeg API libavutil/hwcontext.h. enum AVHWDeviceType, . FFmpeg :


void print_hwtypes_all()
{
    AVHWDeviceType hwtype = AV_HWDEVICE_TYPE_NONE;
    while ((hwtype = av_hwdevice_iterate_types(hwtype)) !=
                            AV_HWDEVICE_TYPE_NONE)
    {
        printf("%s\n", av_hwdevice_get_type_name(hwtype));
    }
}

- :


    cuda
    dxva2
    qsv
    d3d11va

, cuda Nvidia , qsv Intel Quick Sync Video (QSV), Intel (. [1]), dxva2 d3d11va DirectX Video Acceleration (. [2]), Windows, (Intel, Nvidia, AMD).


( ). , , :


void print_hwtypes(const char* dec_name)
{
    const AVCodec* decoder = avcodec_find_decoder_by_name(dec_name);
    for (int i = 0; ; ++i) { 
        const AVCodecHWConfig *config =
               avcodec_get_hw_config(decoder, i);
        if (config) {
            if (config->methods &
                    AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX) {
                printf("%s\n", 
                  av_hwdevice_get_type_name(config->device_type));
            }
        }
        else {
            break;
        }
    }
}

- h264, hevc, vp9, vc1 :


    dxva2
    d3d11va
    cuda

theora .


, hw_decode.c. [3], 2expres.


void init_hwdevice(AVHWDeviceType hwtype, AVCodecContext *codec_ctx)
{
    AVBufferRef *dev_ctx = NULL;
    int ret = av_hwdevice_ctx_create(&dev_ctx, hwtype, NULL, NULL, 0);
    if (ret >= 0) {
        codec_ctx->get_format = get_hw_format; // . hw_decode.c
        codec_ctx->hw_device_ctx = av_buffer_ref(dev_ctx);
//   dev_ctx,    
//   av_buffer_unref()
    }
}

, , av_hwframe_transfer_data(). dxva2 d3d11va NV12.


-hwaccel.


1.3. ,


FFmpeg , .



Intel Quick Sync Video (QSV), , Intel i3, i5, i7, i9. . [1]. _qsv. FFmpeg : h264_qsv, hevc_qsv, vp8_qsv, mpeg2_qsv, vc1_qsv.


NVDEC, NVENC Nvidia. _cuvid. FFmpeg : h264_cuvid, hevc_cuvid, mpeg2_cuvid, vc1_cuvid, vp8_cuvid, vp9_cuvid, mjpeg_cuvid, mpeg4_cuvid.


:


AVStream *strm;
// ...
AVCodecID cid = strm->codecpar->codec_id;
const AVCodec *decoder = avcodec_find_decoder(cid);

. :


const AVCodec *decoder = (cid == AV_CODEC_ID_H264)
    ? avcodec_find_decoder_by_name("h264_qsv")
    : avcodec_find_decoder(cid);

-c:v -i


ffmpeg -c:v h264_qsv -i INPUT ...


2.


, H264, HEVC(H265). — 38402160 (Ultra HD), — 30 /. — h264, hevc QSV — h264_qsv, hevc_qsv. 4 : , , , dxva2. dxva2 , d3d11va, . , . : , 32- BGRA libswscale. ( 12- YUV420P NV12.) , , ( ). , 100%, , , . . 64- FFmpeg.


.
h264hevc
Config#CPUGPUCPUGPU
default175260125250
2132280180270
threads=214742074420
279480104460
threads=413560046640
26054071700
dxva21451472342870
21072835993036
xxxx_qsv1253480253472
2703954704050


, , . — BGRA. , , .


32- FFmpeg. , : hevc 2-3 . .


. -benchmark . :


ffmpeg -benchmark -i INPUT -an -f null -
ffmpeg -benchmark -threads N -i INPUT -an -f null -
ffmpeg -benchmark -c:v h264_qsv -i INPUT -an -f null -
ffmpeg -benchmark -hwaccel dxva2 -i INPUT -an -f null -
ffmpeg -benchmark -i INPUT -an -pix_fmt bgra -f null -

fps, speed . -threads N auto, , 100%.



3. QSV


FFmpeg QSV : h264_qsv, hevc_qsv, vp8_qsv, mpeg2_qsv, vc1_qsv. . mpeg2_qsv , vc1_qsv . , , , -, , .


. , — avcodec_flush_buffers(). , .




[1] Intel Quick Sync Video.
[2] DirectX Video Acceleration.
[3] FFmpeg DXVA2.




Source: https://habr.com/ru/post/undefined/


All Articles