Both sides previous revisionPrevious revisionNext revision | Previous revision |
ffmpeg:encoding:gpu_encoding [2024/05/18 16:28] – peter | ffmpeg:encoding:gpu_encoding [2025/02/17 15:23] (current) – peter |
---|
====== ffmpeg - Encoding - GPU Encoding ====== | ====== ffmpeg - Encoding - GPU Encoding ====== |
| |
| [[ffmpeg:Encoding:GPU Encoding:Convert videos to 10-bit h265, AAC 5.1|Convert videos to 10-bit h265, AAC 5.1]] |
| |
| ---- |
| |
| <code bash> |
| ffmpeg -i "input.mkv" -vaapi_device /dev/dri/renderD128 -vf 'format=p010,hwupload' -map 0:v -metadata:s:v:0 language=eng -map 0:a:m:language:eng -metadata:s:a:0 language=eng -map 0:s\? -c:v hevc_vaapi -b:v 3000k -bufsize 3000k -c:a aac -ac 6 -ar 48000 -b:a 640k -c:s srt -profile:v main10 -rc_mode CBR -v verbose "output.mkv" |
| </code> |
| |
| ---- |
| |
| |
===== Convert videos to H.265 / HEVC using ffmpeg and GPU hardware encoding ===== | ===== Convert videos to H.265 / HEVC using ffmpeg and GPU hardware encoding ===== |
<code bash> | <code bash> |
ffmpeg -i "input.mkv" -vaapi_device /dev/dri/renderD128 -vf 'format=nv12,hwupload,scale_vaapi=w=1920:h=1080' -map 0:v -metadata:s:v:0 language=eng -map 0:a -metadata:s:a:0 language=eng -map 0:s? -metadata:s:s:0 language=eng -profile:v main -c:v hevc_vaapi -c:a copy -c:s copy -rc_mode CQP -global_quality 25 -v verbose "output.mkv" | ffmpeg -i "input.mkv" -vaapi_device /dev/dri/renderD128 -vf 'format=nv12,hwupload,scale_vaapi=w=1920:h=1080' -map 0:v -metadata:s:v:0 language=eng -map 0:a -metadata:s:a:0 language=eng -map 0:s? -metadata:s:s:0 language=eng -profile:v main -c:v hevc_vaapi -c:a copy -c:s copy -rc_mode CQP -global_quality 25 -v verbose "output.mkv" |
| |
| ffmpeg -i "input.mkv" -vaapi_device /dev/dri/renderD128 -vf 'format=nv12,hwupload,scale_vaapi=w=1920:h=1080' -map 0:v -metadata:s:v:0 language=eng -map 0:a:m:language:eng? -metadata:s:a:0 language=eng -map 0:s? -metadata:s:s:0 language=eng -profile:v main -c:v hevc_vaapi -c:a copy -c:s copy -rc_mode CQP -global_quality 25 -v verbose "output.mkv" |
| |
| |
| # This is hardware decoding and software encoding. |
| ffmpeg -hwaccel vaapi -hwaccel_device /dev/dri/renderD128 -hwaccel_output_format vaapi -i "input.mkv" -vf 'deinterlace_vaapi=rate=field:auto=1,scale_vaapi=w=1920:h=1080,hwdownload,format=nv12' -map 0:v -metadata:s:v:0 language=eng -map 0:a -metadata:s:a:0 language=eng -map 0:s? -profile:v main -c:v libx265 -c:a copy -c:s copy -rc_mode CQP -global_quality 25 -v verbose output.mkv |
</code> | </code> |
| |
* **-i "input.mkv"** is the source file. | * **-i "input.mkv"** is the source file. |
* **-vaapi_device /dev/dri/renderD128** is a shortcut to **-init_hw_device vaapi=vaapi0:/dev/dri/renderD128 -filter_hw_device vaapi0**, and initializes a new hardware device of type **vaapi**. | * **-vaapi_device /dev/dri/renderD128** is a shortcut to **-init_hw_device vaapi=vaapi0:/dev/dri/renderD128 -filter_hw_device vaapi0**, and initializes a new hardware device of type **vaapi**. |
* **-vf 'format=nv12,hwupload,scale_vaapi=w=1920:h=1080'** creates the filtergraph and use it to filter the stream. | * **-vf 'format=nv12,hwupload,scale_vaapi=w=1920:h=1080'** creates the filtergraph and uses it to filter the stream. |
* The encoders only accept input as VAAPI surfaces. If the input is in normal memory, it will need to be uploaded before giving the frames to the encoder - in the ffmpeg utility, the hwupload filter can be used for this. | * The encoders only accept input as VAAPI surfaces. If the input is in normal memory, it will need to be uploaded before giving the frames to the encoder - in the ffmpeg utility, the hwupload filter can be used for this. |
* It will upload to a surface with the same layout as the software frame, so it may be necessary to add a format filter immediately before to get the input into the right format (hardware generally wants the nv12 layout). | * It will upload to a surface with the same layout as the software frame, so it may be necessary to add a format filter immediately before to get the input into the right format (hardware generally wants the nv12 layout). |
* The **hwupload** filter also requires a device to upload to, which needs to be defined before the filter graph is created which is done with **-vaapi_device**. | * The **hwupload** filter also requires a device to upload to, which needs to be defined before the filter graph is created which is done with **-vaapi_device**. |
* The **scale_vaapi=w=1920:h=1080** scales the video to 1080p. | * The **scale_vaapi=w=1920:h=1080** scales the video to 1080p. |
* Use **-vf 'format=nv12,hwupload'** to not do any scaling. | * Use **-vf 'format=nv12,hwupload'** to not do any scaling, and to use NV12 (8-bit encoding). |
| * Use **-vf 'format=p010,hwupload'** for 10-bit encoding; and also change the profile to **Main10**. |
| * See further below for other pixel formats.. |
* **-map 0:v** selects the Video streams from the inputs which will go into the output. | * **-map 0:v** selects the Video streams from the inputs which will go into the output. |
* **-metadata:s:v:0 language=eng** has the output Video stream to show English as the language. | * **-metadata:s:v:0 language=eng** has the output Video stream to show English as the language. |
* **-c:a copy** copies the Audio streams without modification to the output. | * **-c:a copy** copies the Audio streams without modification to the output. |
* **-c:s copy** copies the Subtitle streams without modification to the output. | * **-c:s copy** copies the Subtitle streams without modification to the output. |
* **-rc_mode CQP** sets the rate control mode to COP. | * **-rc_mode CQP** sets the rate control mode to CQP. |
* COP works well. | * CQP works well. |
* <WRAP> | * <WRAP> |
Run the following to see all possible modes: <code bash>ffmpeg -h encoder=hevc_vaapi</code> | Run the following to see all possible modes: <code bash>ffmpeg -h encoder=hevc_vaapi</code> |
</WRAP> | </WRAP> |
| |
| |
| ---- |
| |
| ===== Using other pixel formats ===== |
| |
| Check which pixel formats are supported: |
| |
| <code bash> |
| ffmpeg -pix_fmts |
| </code> |
| |
| returns |
| |
| <code> |
| Pixel formats: |
| I.... = Supported Input format for conversion |
| .O... = Supported Output format for conversion |
| ..H.. = Hardware accelerated format |
| ...P. = Paletted format |
| ....B = Bitstream format |
| FLAGS NAME NB_COMPONENTS BITS_PER_PIXEL BIT_DEPTHS |
| ----- |
| IO... yuv420p 3 12 8-8-8 |
| IO... yuyv422 3 16 8-8-8 |
| ... |
| ... |
| IO... nv12 3 12 8-8-8 |
| IO... p010le 3 15 10-10-10 |
| </code> |
| |
| ---- |
| |
| <WRAP info> |
| **NOTE:** When using a different pixel format, usually the following options will need to be set: |
| |
| * -vf 'format=nv12' and -profile:v main |
| * -vf 'format=p010' and -profile:v main10 |
| * -vf 'format=p016' and -profile:v rext |
| |
| </WRAP> |
| |
| ---- |
| |
| ==== Encode with 8-bit ==== |
| |
| ^Format^Chroma sampling^Packed or planar^Bits per channel^ |
| |NV12|4:2:0|Planar|8| |
| |
| <code bash> |
| ffmpeg -i "input.mkv" -vaapi_device /dev/dri/renderD128 -vf 'format=nv12,hwupload,scale_vaapi=w=1920:h=1080' -map 0:v -metadata:s:v:0 language=eng -map 0:a -metadata:s:a:0 language=eng -map 0:s? -metadata:s:s:0 language=eng -profile:v main -c:v hevc_vaapi -c:a copy -c:s copy -rc_mode CQP -global_quality 25 -v verbose "output.mkv" |
| |
| ffmpeg -i "input.mkv" -vaapi_device /dev/dri/renderD128 -vf 'format=nv12,hwupload,scale_vaapi=w=1920:h=1080' -map 0:v -metadata:s:v:0 language=eng -map 0:a:m:language:eng? -metadata:s:a:0 language=eng -map 0:s? -metadata:s:s:0 language=eng -profile:v main -c:v hevc_vaapi -c:a copy -c:s copy -rc_mode CQP -global_quality 25 -v verbose "output.mkv" |
| </code> |
| |
| ==== Encode with 10-bit ==== |
| |
| ^Format^Chroma sampling^Packed or planar^Bits per channel^ |
| |P010|4:2:0|Planar|10| |
| |
| <code bash> |
| ffmpeg -i "input.mkv" -vaapi_device /dev/dri/renderD128 -vf 'format=p010,hwupload,scale_vaapi=w=1920:h=1080' -map 0:v -metadata:s:v:0 language=eng -map 0:a -metadata:s:a:0 language=eng -map 0:s? -metadata:s:s:0 language=eng -profile:v main10 -c:v hevc_vaapi -c:a copy -c:s copy -rc_mode CQP -global_quality 25 -v verbose "output.mkv" |
| |
| ffmpeg -i "input.mkv" -vaapi_device /dev/dri/renderD128 -vf 'format=p010,hwupload,scale_vaapi=w=1920:h=1080' -map 0:v -metadata:s:v:0 language=eng -map 0:a:m:language:eng? -metadata:s:a:0 language=eng -map 0:s? -metadata:s:s:0 language=eng -profile:v main10 -c:v hevc_vaapi -c:a copy -c:s copy -rc_mode CQP -global_quality 25 -v verbose "output.mkv" |
| </code> |
| |
| ==== Encode with 16-bit ==== |
| |
| ^Format^Chroma sampling^Packed or planar^Bits per channel^ |
| |P010|4:2:0|Planar|16| |
| |
| <code bash> |
| ffmpeg -i "input.mkv" -vaapi_device /dev/dri/renderD128 -vf 'format=p016,hwupload,scale_vaapi=w=1920:h=1080' -map 0:v -metadata:s:v:0 language=eng -map 0:a -metadata:s:a:0 language=eng -map 0:s? -metadata:s:s:0 language=eng -profile:v rext -c:v hevc_vaapi -c:a copy -c:s copy -rc_mode CQP -global_quality 25 -v verbose "output.mkv" |
| |
| ffmpeg -i "input.mkv" -vaapi_device /dev/dri/renderD128 -vf 'format=p016,hwupload,scale_vaapi=w=1920:h=1080' -map 0:v -metadata:s:v:0 language=eng -map 0:a:m:language:eng? -metadata:s:a:0 language=eng -map 0:s? -metadata:s:s:0 language=eng -profile:v rext -c:v hevc_vaapi -c:a copy -c:s copy -rc_mode CQP -global_quality 25 -v verbose "output.mkv" |
| </code> |
| |
| |