[FFmpeg滤镜增强能力]在FFmpeg中使用OpenGL 自定义Shader渲染视频媒体素材

O 背景

相信很多人不满足于FFmpeg已有的Filters,对于现有FFmpeg支持Animation动画能力很不满足
确实,FFmpeg本身的Filter滤波器并非为动画而作,而是核心服务于编解码/转码的用户需求
同时我们也知道,OpenGL作为动画 2D/3D特效算法开发的首选能力,正好可以弥补FFmpeg对于特效渲染的短板。

今天要给的解决方案:如何在FFmpeg Cmd中使用 OpenGL 自定义 Shader 渲染视频媒体素材。

主要介绍 FFmpeg-Plus-OpenGL 滤镜对于这个困境的解决方案。


1 FFmpeg-Plus-OpenGL

滤镜:https://github.com/numberwolf/FFmpeg-Plus-OpenGL

FFmpeg-Plus-OpenGL 是一个 FFmpeg 下支持OpenGL的扩展滤波器,此项目为一个Patch,可以直接将滤镜编译到自己的FFmpeg4+(FFmpeg3的滤镜 Patch有所不同,略微更改即可)

source render
image.png
image.png


使用步骤如下

安装 编译

  • 相关依赖

    • Centos 7.x+ || Linux

      • 第一步 安装相关依赖

        yum install -y glew*
        yum install -y glfw*
        
        #
        # If can not compile , you need
        #
        yum install -y libGLEW*
        yum install -y mesa
        yum install -y mesa-libGLU mesa-libGLU-devel
        
      • 第二步(可选)

        如果你在无显卡环境下跑此滤镜(比如你的生产环境服务器),需要xvfb的支持

        yum install -y xorg-x11-server-Xvfb
        
    • Ubuntu || Linux

      • 第一步 安装相关依赖

        apt-get install libglfw3-dev libglfw3
        apt-get install libglew2.0 libglew-dev
        
      • 第二步(可选)

        如果你在无显卡环境下跑此滤镜(比如你的生产环境服务器),需要xvfb的支持

        apt-get install xvfb
        
    • MacOS下编译 (需要brew支持)

      brew install glew glfw
      


  • 编译构建

    • 下载源码

      git clone https://github.com/numberwolf/FFmpeg-Plus-OpenGL.git
      git clone https://github.com/FFmpeg/FFmpeg.git # for 4.x+
      
      cd FFmpeg
      
      #
      # Patch
      #
      cp ../FFmpeg-Plus-OpenGL/Plus-GL-Shader/vf_plusglshader.c libavfilter/
      git apply ../FFmpeg-Plus-OpenGL/Plus-GL-Shader/libavfilter.diff
      
    • 编译

      • 编译的必选项 - 和此滤镜相关

        --enable-opengl
        --extra-libs='-lGLEW -lglfw'
        --enable-filter=plusglshader

      • 编译示例 - 可以不参考此示例,但是必须加上必选项

        #!/bin/bash
        ./configure \
          --enable-cross-compile \
          --pkg-config-flags="--static" \
          --extra-ldflags="-lm -lz -llzma -lpthread" \
          --extra-libs=-lpthread \
          --extra-libs=-lm \
          --enable-gpl \
          --enable-libfdk_aac \
          --enable-libfreetype \
          --enable-libmp3lame \
          --enable-libopus \
          --enable-libvpx \
          --enable-libx264 \
          --enable-libx265 \
          --enable-libass \
          --enable-libfreetype       \
          --enable-libfontconfig     \
          --enable-libfribidi        \
          --enable-libwebp           \
          --enable-nonfree \
          --disable-shared \
          --enable-static \
          --enable-opengl \
          --extra-libs='-lGLEW -lglfw' \
          --enable-filter=plusglshader
        make clean
        make -j16
        make install
        


运行

  • 检查 Plus-GL-Shader:plusglshader 滤镜是否安装成功

    • 检查命令

      ffmpeg -help filter=plusglshader
      
    • 正确输出

      ffmpeg version a0d68e65 Copyright (c) 2000-2020 the FFmpeg developers
        built with Apple LLVM version 10.0.0 (clang-1000.10.44.4)
        configuration: --enable-cross-compile --pkg-config-flags=--static --extra-ldflags='-lm -lz -llzma -lpthread' --extra-libs=-lpthread --extra-libs=-lm --enable-gpl --enable-libfdk_aac --enable-libfreetype --enable-libmp3lame --enable-libopus --enable-libvpx --enable-libx264 --enable-libx265 --enable-libass --enable-libfreetype --enable-libfontconfig --enable-libfribidi --enable-libwebp --enable-nonfree --disable-shared --enable-static --enable-opengl --extra-libs='-lGLEW -lglfw' --enable-filter=plusglshader
        libavutil      56. 51.100 / 56. 51.100
        libavcodec     58. 91.100 / 58. 91.100
        libavformat    58. 45.100 / 58. 45.100
        libavdevice    58. 10.100 / 58. 10.100
        libavfilter     7. 85.100 /  7. 85.100
        libswscale      5.  7.100 /  5.  7.100
        libswresample   3.  7.100 /  3.  7.100
        libpostproc    55.  7.100 / 55.  7.100
      Filter plusglshader
        Generic OpenGL shader filter
          Inputs:
             #0: default (video)
          Outputs:
             #0: default (video)
      plusglshader AVOptions:
        sdsource          <string>     ..FV...... gl fragment shader source path (default is render gray color)
        vxsource          <string>     ..FV...... gl vertex shader source path (default is render gray color)
      
      This filter has support for timeline through the 'enable' option.
      
  • 使用plusglfilter转码渲染 (Transcoding)

    plusglshader=sdsource='./test_shader.gl':vxsource='./test_vertex.gl'

    • 参数项

      • sdsource : Fragment shader file path (Default is gray)
      • vxsource : Vertex shader file path (Default is gray)
    • 滤镜使用规则

      • plusglshader
      • plusglshader=sdsource='./test_shader.gl':vxsource='./test_vertex.gl'
    • 用你自己的Shader渲染

        1. Fragment shader

        Notice: playTime is timestamp, from 0 -> end

        uniform sampler2D tex;
        uniform float playTime;
        varying vec2 texCoord;
        void main() {
            gl_FragColor = texture2D(tex, texCoord * 0.5 + 0.5);
            float usePts = max(playTime, 0.4);
            float gray = (gl_FragColor.r + gl_FragColor.g + gl_FragColor.b) / (usePts * usePts);
            gl_FragColor.r = gray;
            gl_FragColor.g = gray;
            gl_FragColor.b = gray;
        }
        
        1. Vertex shader
        attribute vec2 position;
        varying vec2 texCoord;
        void main(void) {
            gl_Position = vec4(position, 0, 1);
            texCoord = position;
        }
        
    • 如果在无头(无显示器显卡环境下)环境下使用

      你需要xvfb server支持,使用如下命令

      xvfb-run -a --server-args="-screen 0 1280x720x24 -ac -nolisten tcp -dpi 96 +extension RANDR" \
      ffmpeg -v debug \
      -i 1000p10s_9k.mp4 \
      -filter_complex "[0:v]plusglshader=sdsource='./test_shader.gl':vxsource='./test_vertex.gl'[1outgl];[1outgl]scale=1280:-2" \
      -vcodec libx264 \
      -an \
      -pix_fmt yuv420p \
      -y test.mp4
      
    • 在有头(显卡 显示器)环境下运行

      ffmpeg -v debug \
      -i 1000p10s_9k.mp4 \
      -filter_complex "[0:v]plusglshader=sdsource='./test_shader.gl':vxsource='./test_vertex.gl'[1outgl];[1outgl]scale=1280:-2" \
      -vcodec libx264 \
      -an \
      -pix_fmt yuv420p \
      -y test.mp4
      
    • 输出示例

      Tag Src Dst
      Frame
      原图
      渲染


2 相关帮助

FFmpeg编译相关帮助


推荐阅读更多精彩内容