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:
parent
a57c21febd
commit
b32d9bf30c
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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"`
|
||||
|
|
|
@ -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",
|
||||
|
|
Loading…
Reference in a new issue