FFmpeg硬件编码视频加快处理速度

55 阅读3分钟

在使用 ffmpeg 处理视频时,只要没有使用 -c:v copy, 就涉及到视频的重新编码,默认将使用软解,在处理大视频时,非常耗时,而要启用硬解,涉及到4个硬件 3个操作系统 及各种不同视频编码格式,不同操作系统不同硬件平台,可用的编码解码器又各不相同,想想就头大,处理兼容性就够喝一壶的。

下方图表是ffmpeg官方提供的硬件兼容表格,各种刺眼的 "N"

trac.ffmpeg.org/wiki/HWAcce…

image.png

image.png

四大硬件:Intel AMD apple Nvidia

三大操作系统:Windows Linux MacOS

各种编码格式: H.264 / H.265 / VP8 / VP9 / MJPEG / MPEG-2

硬件解码|硬件编码

ffmpeg对这些平台和操作系统都有支持,其中AMD的支持较差,略过不提。

另外只讨论 H.264/H.265 这2种最常用的视频编码格式,忽略其他。

只谈硬件编码,暂时忽略硬件解码。

查看本机安装的ffmpeg支持的编码器

ffmpeg -encoders

image.png

Windows系统下可用的硬件编码

hevc_前缀代表适用于H.265编码的加速器

默认编码器:libx264 / libx265

转码举例: ffmpeg -i 1.mp4 -c:v libx264 out.mp4 ffmpeg -i 1.mp4 -c:v libx265 out.mp4


Intel 硬件编码加速器:h264_qsv / hevc_qsv

查看本机ffmpeg是否支持:ffmpeg -encoders|findstr h264_qsv

转码举例: ffmpeg -i 1.mp4 -c:v h264_qsv out.mp4


Nvidia 硬件编码加速器: h264_nvenc nvenc_h264 / hevc_nvenc nvenc_hevc

转码举例: ffmpeg -i 1.mp4 -c:v h264_nvenc out.mp4

查看本机ffmpeg是否支持:ffmpeg -encoders|findstr h264_nvenc


Linux系统下可用的硬件编码

hevc_前缀代表适用于H.265编码的加速器

默认编码器:libx264 / libx265

转码举例: ffmpeg -i 1.mp4 -c:v libx264 out.mp4


Intel 硬件编码加速器: h264_vaapi / hevc_vaapi

转码举例: ffmpeg -i 1.mp4 -c:v h264_vaapi out.mp4

查看本机ffmpeg是否支持:ffmpeg -encoders|grep h264_vaapi


Nvidia 硬件编码加速器:h264_nvenc nvenc_h264 / hevc_nvenc nvenc_hevc

转码举例: ffmpeg -i 1.mp4 -c:v h264_nvenc out.mp4

查看本机ffmpeg是否支持:ffmpeg -encoders|grep h264_nvenc

MacOS系统可用的硬件编码

hevc_前缀代表适用于H.265编码的加速器

默认编码器:libx264 / libx265

转码举例: ffmpeg -i 1.mp4 -c:v libx264 out.mp4


Intel 硬件编码加速器:h264_videotoolbox / hevc_videotoolbox

转码举例: ffmpeg -i 1.mp4 -c:v h264_videotoolbox out.mp4

查看本机ffmpeg是否支持:ffmpeg -encoders|grep h264_videotoolbox


Apple Silicon硬件加速:h264_videotoolbox / hevc_videotoolbox

转码举例: ffmpeg -i 1.mp4 -c:v h264_videotoolbox out.mp4

查看本机ffmpeg是否支持:ffmpeg -encoders|grep h264_videotoolbox

判断当前系统可用硬件加速器



def get_video_codec():
    import platform,subprocess
    from pathlib import Path
    
    plat=platform.system()
    mp4_test="test.mp4"
    mp4_target="target.mp4"
    codec='libx264'
    if plat in ['Windows','Linux']:
        import torch    
        if torch.cuda.is_available():
            codec='h264_nvenc'
        elif plat=='Windows':
            codec='h264_qsv'
        elif plat=='Linux':
            codec='h264_vaapi'
    elif plat=='Darwin':
        codec='h264_videotoolbox'


    s=time.time()
    try:
        subprocess.run([
            "ffmpeg",
            "-y",
            "-hide_banner",
            "-ignore_unknown",
            "-i",
            mp4_test,
            "-c:v",
            codec,
            mp4_target
        ],
        check=True,
        creationflags=0 if sys.platform != 'win32' else subprocess.CREATE_NO_WINDOW)
    # except subprocess.CalledProcessError as e:
    except Exception as e:
        print('error='+str(e))
        return 'libx264'
    finally:
        print(f'time={time.time()-s}')
    return codec

参考

en.wikipedia.org/wiki/Intel_…

trac.ffmpeg.org/wiki/HWAcce…