Author: dongdong
Email: ldyldy828@126.com
This article includes:
- Installing FFmpeg on Linux
- Video format recognition and transcoding via command line
- Video transcoding acceleration using GPU on Linux with Nvidia graphics card
FFmpeg Compile Installation
On the FFmpeg website, https://ffmpeg.org/download.html can be downloaded to the ubunto/debian distribution package. Other Linux distributions need to be compiled on their own.Also, if you want to use GPU for hardware acceleration, you must compile FFmpeg yourself, so this section describes how to install FFmpeg from source code (based on RHEL/Centos)
Install Dependent Tools
yum install autoconf automake bzip2 cmake freetype-devel gcc gcc-c++ git libtool make mercurial pkgconfig zlib-devel
Dead work
Create ffmpeg_sources directory under $HOME
HOME=/home/local/
Compile and install dependent Libraries
Dependent libraries in this section are essentially required, and it is recommended that they all be installed
nasm
Assemble compilers required to compile certain dependent Libraries
cd /home/local/ffmpeg_sources curl -O -L http://www.nasm.us/pub/nasm/releasebuilds/2.13.02/nasm-2.13.02.tar.bz2 tar xjvf nasm-2.13.02.tar.bz2 cd nasm-2.13.02 ./autogen.sh ./configure --prefix="/home/local/ffmpeg_build" --bindir="/home/local/bin" make make install
yasm
Assemble compilers required to compile certain dependent Libraries
cd /home/local/ffmpeg_sources curl -O -L http://www.tortall.net/projects/yasm/releases/yasm-1.3.0.tar.gz tar xzvf yasm-1.3.0.tar.gz cd yasm-1.3.0 ./configure --prefix="/home/local/ffmpeg_build" --bindir="/home/local/bin" make make install
libx264
H.264 video encoder, this library is required if you need to output H.264 encoded video, so it is necessary
cd /home/local/ffmpeg_sources git clone --depth 1 http://git.videolan.org/git/x264 cd x264 PKG_CONFIG_PATH="/home/local/ffmpeg_build/lib/pkgconfig" ./configure --prefix="/home/local/ffmpeg_build" --bindir="/home/local/bin" --enable-static make make install
libx265
H.265/HEVC video encoder.
If you don't need this encoder, you can skip and remove--enable-libx265 from ffmpeg's configure command
cd /home/local/ffmpeg_sources hg clone https://bitbucket.org/multicoreware/x265 cd ~/ffmpeg_sources/x265/build/linux cmake -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX="/home/local/ffmpeg_build" -DENABLE_SHARED:bool=off ../../source make make install
libfdk_acc
AAC Audio Encoder, Essential
cd /home/local/ffmpeg_sources git clone --depth 1 --branch v0.1.6 https://github.com/mstorsjo/fdk-aac.git cd fdk-aac autoreconf -fiv ./configure --prefix="/home/local/ffmpeg_build" --disable-shared make make install
libmp3lame
MP3 audio encoder, essential
cd /home/local/ffmpeg_sources curl -O -L http://downloads.sourceforge.net/project/lame/lame/3.100/lame-3.100.tar.gz tar xzvf lame-3.100.tar.gz cd lame-3.100 ./configure --prefix="/home/local/ffmpeg_build" --bindir="/home/local/bin" --disable-shared --enable-nasm make make install
libops
OPUS Audio Encoder
If you don't need this encoder, you can skip and remove--enable-libopus from ffmpeg's configure command
cd /home/local/ffmpeg_sources curl -O -L https://archive.mozilla.org/pub/opus/opus-1.2.1.tar.gz tar xzvf opus-1.2.1.tar.gz cd opus-1.2.1 ./configure --prefix="/home/local/ffmpeg_build" --disable-shared make make install
libogg
Dependent on libvorbis
cd /home/local/ffmpeg_sources curl -O -L http://downloads.xiph.org/releases/ogg/libogg-1.3.3.tar.gz tar xzvf libogg-1.3.3.tar.gz cd libogg-1.3.3 ./configure --prefix="/home/local/ffmpeg_build" --disable-shared make make install
libvorbis
Vorbis Audio Encoder
If you don't need this encoder, you can skip and remove--enable-libvorbis from ffmpeg's configure command
cd /home/local/ffmpeg_sources curl -O -L http://downloads.xiph.org/releases/vorbis/libvorbis-1.3.5.tar.gz tar xzvf libvorbis-1.3.5.tar.gz cd libvorbis-1.3.5 ./configure --prefix="/home/local/ffmpeg_build" --with-ogg="/home/local/ffmpeg_build" --disable-shared make make install
libvpx
VP8/VP9 Video Codec/Decoder
If you don't need this codec, you can skip and remove--enable-libvpx from ffmpeg's configure command
cd /home/local/ffmpeg_sources git clone --depth 1 https://github.com/webmproject/libvpx.git cd libvpx ./configure --prefix="/home/local/ffmpeg_build" --disable-examples --disable-unit-tests --enable-vp9-highbitdepth --as=yasm make make install
Compile and install ffmpeg 3.3.8
cd /home/local/ffmpeg_sources curl -O -L https://ffmpeg.org/releases/ffmpeg-3.3.8.tar.bz2 tar xjvf ffmpeg-3.3.8.tar.bz2 cd ffmpeg-3.3.8 PATH="/home/local/ffmpeg_sources/bin:$PATH" PKG_CONFIG_PATH="/home/local/ffmpeg_sources/ffmpeg_build/lib/pkgconfig" ./configure --prefix="/home/local/ffmpeg_sources/ffmpeg_build" --pkg-config-flags="--static" --extra-cflags="-I /home/local/ffmpeg_sources/ffmpeg_build/include" --extra-ldflags="-L /home/local/ffmpeg_sources/ffmpeg_build/lib" --extra-libs=-lpthread --extra-libs=-lm --bindir="$HOME/bin" --enable-gpl --enable-libfdk_aac --enable-libfreetype --enable-libmp3lame --enable-libopus --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libx265 --enable-nonfree --enable-libfreetype make make install hash -r
Verify Installation
ffmpeg -h
Use FFmpeg
Identify video information
Identify and output video information through ffprobe command
ffprobe -v error -show_streams -print_format json <input>
To facilitate program parsing, output video information in json format, such as the following:
{ "streams": [ { "index": 0, "codec_name": "h264", "codec_long_name": "H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10", "profile": "High", "codec_type": "video", "codec_time_base": "61127/3668400", "codec_tag_string": "avc1", "codec_tag": "0x31637661", "width": 1920, "height": 1080, "coded_width": 1920, "coded_height": 1080, "has_b_frames": 0, "sample_aspect_ratio": "0:1", "display_aspect_ratio": "0:1", "pix_fmt": "yuv420p", "level": 40, "color_range": "tv", "color_space": "bt709", "color_transfer": "bt709", "color_primaries": "bt709", "chroma_location": "left", "refs": 1, "is_avc": "true", "nal_length_size": "4", "r_frame_rate": "30/1", "avg_frame_rate": "1834200/61127", "time_base": "1/600", "start_pts": 0, "start_time": "0.000000", "duration_ts": 61127, "duration": "101.878333", "bit_rate": "16279946", "bits_per_raw_sample": "8", "nb_frames": "3057", "disposition": { "default": 1, "dub": 0, "original": 0, "comment": 0, "lyrics": 0, "karaoke": 0, "forced": 0, "hearing_impaired": 0, "visual_impaired": 0, "clean_effects": 0, "attached_pic": 0, "timed_thumbnails": 0 }, "tags": { "rotate": "90", "creation_time": "2018-08-09T09:13:33.000000Z", "language": "und", "handler_name": "Core Media Data Handler", "encoder": "H.264" }, "side_data_list": [ { "side_data_type": "Display Matrix", "displaymatrix": "\n00000000: 0 65536 0\n00000001: -65536 0 0\n00000002: 70778880 0 1073741824\n", "rotation": -90 } ] }, { "index": 1, "codec_name": "aac", "codec_long_name": "AAC (Advanced Audio Coding)", "profile": "LC", "codec_type": "audio", "codec_time_base": "1/44100", "codec_tag_string": "mp4a", "codec_tag": "0x6134706d", "sample_fmt": "fltp", "sample_rate": "44100", "channels": 1, "channel_layout": "mono", "bits_per_sample": 0, "r_frame_rate": "0/0", "avg_frame_rate": "0/0", "time_base": "1/44100", "start_pts": 0, "start_time": "0.000000", "duration_ts": 4492835, "duration": "101.878345", "bit_rate": "91595", "max_bit_rate": "96000", "nb_frames": "4390", "disposition": { "default": 1, "dub": 0, "original": 0, "comment": 0, "lyrics": 0, "karaoke": 0, "forced": 0, "hearing_impaired": 0, "visual_impaired": 0, "clean_effects": 0, "attached_pic": 0, "timed_thumbnails": 0 }, "tags": { "creation_time": "2018-08-09T09:13:33.000000Z", "language": "und", "handler_name": "Core Media Data Handler" } }, { "index": 2, "codec_type": "data", "codec_tag_string": "mebx", "codec_tag": "0x7862656d", "r_frame_rate": "0/0", "avg_frame_rate": "0/0", "time_base": "1/600", "start_pts": 0, "start_time": "0.000000", "duration_ts": 61127, "duration": "101.878333", "bit_rate": "119", "nb_frames": "17", "disposition": { "default": 1, "dub": 0, "original": 0, "comment": 0, "lyrics": 0, "karaoke": 0, "forced": 0, "hearing_impaired": 0, "visual_impaired": 0, "clean_effects": 0, "attached_pic": 0, "timed_thumbnails": 0 }, "tags": { "creation_time": "2018-08-09T09:13:33.000000Z", "language": "und", "handler_name": "Core Media Data Handler" } }, { "index": 3, "codec_type": "data", "codec_tag_string": "mebx", "codec_tag": "0x7862656d", "r_frame_rate": "0/0", "avg_frame_rate": "0/0", "time_base": "1/600", "start_pts": 0, "start_time": "0.000000", "duration_ts": 61127, "duration": "101.878333", "nb_frames": "1", "disposition": { "default": 1, "dub": 0, "original": 0, "comment": 0, "lyrics": 0, "karaoke": 0, "forced": 0, "hearing_impaired": 0, "visual_impaired": 0, "clean_effects": 0, "attached_pic": 0, "timed_thumbnails": 0 }, "tags": { "creation_time": "2018-08-09T09:13:33.000000Z", "language": "und", "handler_name": "Core Media Data Handler" } } ] }
You can see that a total of four streams have been returned, of which the 0th is a video stream, the 1st is an audio stream, the 2nd and 3S are additional data, which is not useful
If you want to specify an analysis video or audio stream, you can add the parameter -show_streams -v or -show_streams-a, which will output only the analysis results of the video/audio stream
Transcoding
ffmpeg -i <input> -c:v libx264 -b:v 2048k -vf scale=1280:-1 -y <output>
The above command transcodes the input video to h264 encoded video
- -c:v: Specify the encoder, the list of encoders can be viewed using ffmpeg-codecs
- -vf scale: Specifies the width and height of the output video, with a height of -1 representing proportional auto-fit
- -b:v: Specifies the bit rate of the output video, that is, the number of bits per second of the output video
- Other parameters supported by libx264 can be queried using the ffmpeg-h encoder=libx264 command, such as transcoding to other codes, or similar commands to query available parameters
Transcoding using the Nvidia graphics card GPU
It's a big hit. There's not much information on this, and I've worked hard to get it done.
CUDA
CUDA is a GPU computing library developed by Nvidia that allows programmers to drive the GPU of Nvidia graphics cards for various tasks, including video codec
Install CUDA
First verify that the graphics card driver is installed
nvidia-smi
If the driver is working properly, this command outputs information about the model, driver version, existing/GPU usage of the graphics card.How to install a graphics card driver is not described in this article, please refer to other information.
Download the distribution packages for the corresponding platforms on the CUDA website at https://developer.nvidia.com/cuda-downloads, where I choose
wget http://developer.download.nvidia.com/compute/cuda/10.2/Prod/local_installers/cuda-repo-rhel7-10-2-local-10.2.89-440.33.01-1.0-1.x86_64.rpm sudo rpm -i cuda-repo-rhel7-10-2-local-10.2.89-440.33.01-1.0-1.x86_64.rpm sudo yum clean all sudo yum -y install nvidia-driver-latest-dkms cuda sudo yum -y install cuda-drivers
There are probably more than 90 dependent libraries to install. Note the post-installation report. When I first installed a library, I didn't know why it failed, and Yum installed the library only once to succeed
Verify Installation
/usr/local/cuda-9.2/bin/nvcc -V
If the installation is successful, similar text will be output:
nvcc: NVIDIA (R) Cuda compiler driver Copyright (c) 2005-2018 NVIDIA Corporation Built on Tue_Jun_12_23:07:04_CDT_2018 Cuda compilation tools, release 9.2, V9.2.148
Recompile ffmpeg
To enable ffmpeg to use the GPU codec provided by CUDA, ffmpeg must be recompiled to enable it to invoke CUDA through dynamic links
First compile and install the nv-codec-headers Library
git clone https://git.videolan.org/git/ffmpeg/nv-codec-headers.git make PREFIX="/home/local/ffmpeg_build" BINDDIR="/home/local/bin" make install PREFIX="/home/local/ffmpeg_build" BINDDIR="/home/local/bin"
Enter the / home/local/ffmepg_sources/ffmpeg-3.3.8/directory to re-execute ffmpeg compilation and installation
Note the difference between the configure command parameter and the previous configure command parameter
PATH="/home/local/ffmpeg_sources/bin:$PATH" PKG_CONFIG_PATH="/home/local/ffmpeg_sources/ffmpeg_build/lib/pkgconfig" ./configure --prefix="/home/local/ffmpeg_sources/ffmpeg_build" --pkg-config-flags="--static" --extra-cflags="-I /home/local/ffmpeg_sources/ffmpeg_build/include -I/usr/local/cuda/include" --extra-ldflags="-L /home/local/ffmpeg_sources/ffmpeg_build/lib -L/usr/local/cuda/lib64" --extra-libs=-lpthread --extra-libs=-lm --bindir="$HOME/bin" --enable-gpl --enable-libfdk_aac --enable-libfreetype --enable-libmp3lame --enable-libopus --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libx265 --enable-nonfree --enable-libfreetype --enable-cuda --enable-cuvid --enable-nvenc --enable-libnpp
Verify Installation
After reinstalling ffmpeg, use the ffmpeg-hwaccels command to see the supported hardware acceleration options
Hardware acceleration methods: cuvid
You can see one more hardware acceleration option called cuvid, which is the GPU video codec acceleration option provided by CUDA
Then look at the GPU codec ffmpeg-codecs | grep cuvid provided by cuvid
DEV.LS h264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 (decoders: h264 h264_cuvid ) (encoders: libx264 libx264rgb h264_nvenc nvenc nvenc_h264 ) DEV.L. hevc H.265 / HEVC (High Efficiency Video Coding) (decoders: hevc hevc_cuvid ) (encoders: libx265 nvenc_hevc hevc_nvenc ) DEVIL. mjpeg Motion JPEG (decoders: mjpeg mjpeg_cuvid ) DEV.L. mpeg1video MPEG-1 video (decoders: mpeg1video mpeg1_cuvid ) DEV.L. mpeg2video MPEG-2 video (decoders: mpeg2video mpegvideo mpeg2_cuvid ) DEV.L. mpeg4 MPEG-4 part 2 (decoders: mpeg4 mpeg4_cuvid ) D.V.L. vc1 SMPTE VC-1 (decoders: vc1 vc1_cuvid ) DEV.L. vp8 On2 VP8 (decoders: vp8 libvpx vp8_cuvid ) (encoders: libvpx ) DEV.L. vp9 Google VP9 (decoders: vp9 libvpx-vp9 vp9_cuvid ) (encoders: libvpx-vp9 )
All with "cuvid" or "nvenc" are GPU codecs provided by CUDA
As you can see, we can now do GPU decoding in h264/hevc/mjpeg/mpeg1/mpeg2/mpeg4/vc1/vp8/vp9 format and GPU encoding in h264/hevc format
Video transcoding using GPU
The command to transcode with GPU is different from the soft transcode command. When the CPU transcodes, we can rely on ffmpeg to identify the encoding format of the input video and select the corresponding decoder, but ffmpeg will only select the CPU decoder automatically. In order for ffmpeg to use the GPU decoder, the encoding format of the input video must be identified with ffprobe first, and then the corresponding GPU decoder can be specified on the command line..
For example, the source video encoded by h264 is converted to a h264 encoded video of a specified size and bit rate:
ffmpeg -hwaccel cuvid -c:v h264_cuvid -i <input> -c:v h264_nvenc -b:v 2048k -vf scale_npp=1280:-1 -y <output>
- -hwaccel cuvid: Specify using cuvid hardware acceleration
- -c:v h264_cuvid: use h264_cuvid for video decoding
- -c:v h264_nvenc: use h264_nvenc for video encoding
- -vf scale_npp=1280:-1: Specify the width and height of the output video, note that this is not the same as -vf scale=x:x used in soft decoding
During transcoding, use nvidia-smi to check the status of the graphics card, and you can see that ffmpeg is actually transcoding using GPU:
+-----------------------------------------------------------------------------+ | Processes: GPU Memory | | GPU PID Type Process name Usage | |=============================================================================| | 0 62543 C ffmpeg 193MiB | +-----------------------------------------------------------------------------+
GPU Transcoding Efficiency Test
On servers equipped with two Intel-E5-2630v3 CPU s and two Nvidia Tesla M4 graphics cards, h264 video transcoding test was performed with the following results:
- Average GPU transcoding time: 8s
- Average CPU transcoding time: 25s
When parallel transcoding, the efficiency of CPU soft transferring is improved. When three transcoding tasks are parallel, 32 cores are full. At this time, the performance is improved.
- Average GPU transcoding time: 8s
- Average CPU transcoding time: 18s
It is not difficult to see that the GPU transcoding speed does not increase in parallel, so a GPU can only perform one transcoding task at the same time.So, if there are multiple graphics cards plugged into the server, will ffmpeg use multiple GPUs for parallel transcoding?
Unfortunately, the answer is No.
ffmpeg does not have the ability to automatically assign transcoding tasks to different GPUs, but after some investigation, it is found that the GPU used for transcoding tasks can be specified through the -hwaccel_device parameter!
Submit Transcoding Tasks to Different GPU s
ffmpeg -hwaccel cuvid -hwaccel_device 0 -c:v h264_cuvid -i <input> -c:v h264_nvenc -b:v 2048k -vf scale_npp=1280:-1 -y <output> ffmpeg -hwaccel cuvid -hwaccel_device 1 -c:v h264_cuvid -i <input> -c:v h264_nvenc -b:v 2048k -vf scale_npp=1280:-1 -y <output>
- -hwaccel_device N: Specifies a GPU to perform transcoding tasks, N is a number
At this point nvidia-smi shows:
+-----------------------------------------------------------------------------+ | Processes: GPU Memory | | GPU PID Type Process name Usage | |=============================================================================| | 0 96931 C ffmpeg 193MiB | | 1 96930 C ffmpeg 193MiB | +-----------------------------------------------------------------------------+
Parallel GPU transcoding is possible!
Then when the server resources are full, the efficiency of GPU and CPU transcoding is as follows:
- Average GPU transcoding time: 4s
- Average CPU transcoding time: 18s
GPU efficiency is 4.5 times that of CPU
Pit drainage
1. Error:. /autogen.sh: 4:. /autogen.sh: autoreconf: not found
Solution: yum-y install Autoconf automake libtool Then execute
Error: ERROR: freetype2 not found using pkg-config
yum install -y bzip2 wget http://download.savannah.gnu.org/releases/freetype/freetype-2.10.0.tar.bz2 tar -jxvf freetype-2.10.0.tar.bz2 cd freetype-2.10.0 ./configure --prefix= /home/local/ffmpeg_sources/ffmpeg_build make make install
3. Error: configure: error: C compiler cannot create executables See `config.log'for more details make: *** [setup] Error 77
Solution: Uninstall old c++ GCC gcc++ first Then reinstall
4. Error: make: *** [libavcodec/libfdk-aacenc.o] Error 1
4.1 with BUG Official Download Address
(This step can also use git clone to download the source package, which is essentially the same)
Then recompile it.
Reference link: https://www.jianshu.com/p/59da3d350488