Videos: Improve FFmpeg parameters for Intel QSV #2222

This commit also removes PHOTOPRISM_FFMPEG_BUFFERS as it is only
used/required by Video4Linux. 64 seems to be a good value, so we pass
it statically as for the other encoders. Examples have been updated.
This commit is contained in:
Michael Mayer 2022-04-05 16:48:53 +02:00
parent a57c21febd
commit b32d9bf30c
9 changed files with 31 additions and 45 deletions

View file

@ -109,8 +109,8 @@ services:
## Run/install on first startup (options: update, gpu, tensorflow, davfs, clitools, clean):
# PHOTOPRISM_INIT: "gpu tensorflow"
## Hardware Video Transcoding (optional):
# PHOTOPRISM_FFMPEG_ENCODER: "nvidia" # FFmpeg encoder ("software", "intel", "nvidia", "apple", "v4l2", "vaapi")
# PHOTOPRISM_FFMPEG_BUFFERS: "64" # FFmpeg capture buffers (default: 32)
# PHOTOPRISM_FFMPEG_ENCODER: "nvidia" # FFmpeg encoder ("software", "intel", "nvidia", "apple", "raspberry")
# PHOTOPRISM_FFMPEG_ENCODER: "intel" # FFmpeg encoder ("software", "intel", "nvidia", "apple", "raspberry")
# PHOTOPRISM_FFMPEG_BITRATE: "32" # FFmpeg encoding bitrate limit in Mbit/s (default: 50)
## Share hardware devices with FFmpeg and TensorFlow (optional):
# devices:

View file

@ -92,8 +92,8 @@ services:
## Run/install on first startup (options: update, gpu, tensorflow, davfs, clean):
# PHOTOPRISM_INIT: "update clean"
## Hardware Video Transcoding (optional):
# PHOTOPRISM_FFMPEG_ENCODER: "v4l2" # FFmpeg encoder ("software", "intel", "nvidia", "apple", "v4l2", "vaapi")
# PHOTOPRISM_FFMPEG_BUFFERS: "64" # FFmpeg capture buffers (default: 32)
# PHOTOPRISM_FFMPEG_ENCODER: "raspberry" # FFmpeg encoder ("software", "intel", "nvidia", "apple", "raspberry")
# PHOTOPRISM_FFMPEG_BITRATE: "32" # FFmpeg encoding bitrate limit in Mbit/s (default: 50)
## Run as a specific user, group, or with a custom umask (does not work together with "user:")
# PHOTOPRISM_UID: 1000
# PHOTOPRISM_GID: 1000

View file

@ -83,8 +83,7 @@ services:
## Run/install on first startup (options: update, gpu, tensorflow, davfs, clitools, clean):
# PHOTOPRISM_INIT: "gpu tensorflow"
## Hardware Video Transcoding (optional):
# PHOTOPRISM_FFMPEG_ENCODER: "software" # FFmpeg encoder ("software", "intel", "nvidia", "apple", "v4l2", "vaapi")
# PHOTOPRISM_FFMPEG_BUFFERS: "64" # FFmpeg capture buffers (default: 32)
# PHOTOPRISM_FFMPEG_ENCODER: "software" # FFmpeg encoder ("software", "intel", "nvidia", "apple", "raspberry")
# PHOTOPRISM_FFMPEG_BITRATE: "32" # FFmpeg encoding bitrate limit in Mbit/s (default: 50)
## Run as a specific user, group, or with a custom umask (does not work together with "user:")
# PHOTOPRISM_UID: 1000

View file

@ -145,7 +145,6 @@ func configAction(ctx *cli.Context) error {
fmt.Printf("%-25s %s\n", "ffmpeg-bin", conf.FFmpegBin())
fmt.Printf("%-25s %s\n", "ffmpeg-encoder", conf.FFmpegEncoder())
fmt.Printf("%-25s %d\n", "ffmpeg-bitrate", conf.FFmpegBitrate())
fmt.Printf("%-25s %d\n", "ffmpeg-buffers", conf.FFmpegBuffers())
fmt.Printf("%-25s %s\n", "exiftool-bin", conf.ExifToolBin())
// Thumbnails.

View file

@ -19,19 +19,6 @@ func (c *Config) FFmpegEncoder() string {
return c.options.FFmpegEncoder
}
// FFmpegBuffers returns the number of ffmpeg capture buffers.
func (c *Config) FFmpegBuffers() int {
if c.options.FFmpegBuffers <= 8 {
return 8
}
if c.options.FFmpegBuffers >= 2048 {
return 2048
}
return c.options.FFmpegBuffers
}
// FFmpegBitrate returns the ffmpeg bitrate limit in MBit/s.
func (c *Config) FFmpegBitrate() int {
switch {

View file

@ -22,17 +22,6 @@ func TestConfig_FFmpegEnabled(t *testing.T) {
assert.Equal(t, false, c.FFmpegEnabled())
}
func TestConfig_FFmpegBuffers(t *testing.T) {
c := NewConfig(CliTestContext())
assert.Equal(t, 8, c.FFmpegBuffers())
c.options.FFmpegBuffers = 3300
assert.Equal(t, 2048, c.FFmpegBuffers())
c.options.FFmpegBuffers = 589
assert.Equal(t, 589, c.FFmpegBuffers())
}
func TestConfig_FFmpegBitrate(t *testing.T) {
c := NewConfig(CliTestContext())
assert.Equal(t, 50, c.FFmpegBitrate())

View file

@ -439,12 +439,6 @@ var GlobalFlags = []cli.Flag{
Value: 50,
EnvVar: "PHOTOPRISM_FFMPEG_BITRATE",
},
cli.IntFlag{
Name: "ffmpeg-buffers",
Usage: "`NUMBER` of FFmpeg capture buffers",
Value: 32,
EnvVar: "PHOTOPRISM_FFMPEG_BUFFERS",
},
cli.StringFlag{
Name: "exiftool-bin",
Usage: "ExifTool `COMMAND` for extracting metadata",

View file

@ -119,7 +119,6 @@ type Options struct {
FFmpegBin string `yaml:"FFmpegBin" json:"-" flag:"ffmpeg-bin"`
FFmpegEncoder string `yaml:"FFmpegEncoder" json:"FFmpegEncoder" flag:"ffmpeg-encoder"`
FFmpegBitrate int `yaml:"FFmpegBitrate" json:"FFmpegBitrate" flag:"ffmpeg-bitrate"`
FFmpegBuffers int `yaml:"FFmpegBuffers" json:"FFmpegBuffers" flag:"ffmpeg-buffers"`
ExifToolBin string `yaml:"ExifToolBin" json:"-" flag:"exiftool-bin"`
DetachServer bool `yaml:"DetachServer" json:"-" flag:"detach-server"`
DownloadToken string `yaml:"DownloadToken" json:"-" flag:"download-token"`

View file

@ -7,7 +7,6 @@ import (
"os"
"os/exec"
"path/filepath"
"strconv"
"time"
"github.com/photoprism/photoprism/internal/event"
@ -46,6 +45,7 @@ var FFmpegAvcEncoders = map[string]string{
"osx": FFmpegAppleEncoder,
"mac": FFmpegAppleEncoder,
"macos": FFmpegAppleEncoder,
"darwin": FFmpegAppleEncoder,
FFmpegAppleEncoder: FFmpegAppleEncoder,
"vaapi": FFmpegVAAPIEncoder,
"libva": FFmpegVAAPIEncoder,
@ -55,6 +55,7 @@ var FFmpegAvcEncoders = map[string]string{
"cuda": FFmpegNvidiaEncoder,
FFmpegNvidiaEncoder: FFmpegNvidiaEncoder,
"v4l2": FFmpegV4L2Encoder,
"v4l": FFmpegV4L2Encoder,
"video4linux": FFmpegV4L2Encoder,
"rp4": FFmpegV4L2Encoder,
"raspberry": FFmpegV4L2Encoder,
@ -76,11 +77,10 @@ func (c *Convert) AvcConvertCommand(f *MediaFile, avcName, encoderName string) (
if encoderName == FFmpegIntelEncoder {
format := "format=rgb32"
// Options: ffmpeg -hide_banner -h encoder=h264_qsv
result = exec.Command(
c.conf.FFmpegBin(),
"-qsv_device", "/dev/dri/renderD128",
"-init_hw_device", "qsv=hw",
"-filter_hw_device", "hw",
"-i", f.FileName(),
"-c:a", "aac",
"-vf", format,
@ -96,6 +96,7 @@ func (c *Convert) AvcConvertCommand(f *MediaFile, avcName, encoderName string) (
} else if encoderName == FFmpegAppleEncoder {
format := "format=yuv420p"
// Options: ffmpeg -hide_banner -h encoder=h264_videotoolbox
result = exec.Command(
c.conf.FFmpegBin(),
"-i", f.FileName(),
@ -112,8 +113,7 @@ func (c *Convert) AvcConvertCommand(f *MediaFile, avcName, encoderName string) (
avcName,
)
} else if encoderName == FFmpegNvidiaEncoder {
// to show options: ffmpeg -hide_banner -h encoder=h264_nvenc
// Options: ffmpeg -hide_banner -h encoder=h264_nvenc
result = exec.Command(
c.conf.FFmpegBin(),
"-r", "30",
@ -136,6 +136,27 @@ func (c *Convert) AvcConvertCommand(f *MediaFile, avcName, encoderName string) (
"-y",
avcName,
)
} else if encoderName == FFmpegV4L2Encoder {
format := "format=yuv420p"
// Options: ffmpeg -hide_banner -h encoder=h264_v4l2m2m
result = exec.Command(
c.conf.FFmpegBin(),
"-i", f.FileName(),
"-c:v", encoderName,
"-c:a", "aac",
"-vf", format,
"-num_output_buffers", "72",
"-num_capture_buffers", "64",
"-max_muxing_queue_size", "1024",
"-crf", "23",
"-vsync", "vfr",
"-r", "30",
"-b:v", c.AvcBitrate(f),
"-f", "mp4",
"-y",
avcName,
)
} else {
format := "format=yuv420p"
@ -145,8 +166,6 @@ func (c *Convert) AvcConvertCommand(f *MediaFile, avcName, encoderName string) (
"-c:v", encoderName,
"-c:a", "aac",
"-vf", format,
"-num_output_buffers", strconv.Itoa(c.conf.FFmpegBuffers()+8),
"-num_capture_buffers", strconv.Itoa(c.conf.FFmpegBuffers()),
"-max_muxing_queue_size", "1024",
"-crf", "23",
"-vsync", "vfr",