Support FFmpeg drawtext param #487

This commit is contained in:
Alexey Khit
2023-07-03 00:45:51 +03:00
parent c29dd8c4e3
commit c34f9ae2b7
4 changed files with 65 additions and 21 deletions

View File

@@ -41,7 +41,8 @@ FROM base
# Install ffmpeg, tini (for signal handling), # Install ffmpeg, tini (for signal handling),
# and other common tools for the echo source. # and other common tools for the echo source.
# alsa-plugins-pulse for ALSA support (+0MB) # alsa-plugins-pulse for ALSA support (+0MB)
RUN apk add --no-cache tini ffmpeg bash curl jq alsa-plugins-pulse # font-droid for FFmpeg drawtext filter (+2MB)
RUN apk add --no-cache tini ffmpeg bash curl jq alsa-plugins-pulse font-droid
# Hardware Acceleration for Intel CPU (+50MB) # Hardware Acceleration for Intel CPU (+50MB)
ARG TARGETARCH ARG TARGETARCH

View File

@@ -89,8 +89,8 @@ var defaults = map[string]string{
// hardware NVidia on Linux and Windows // hardware NVidia on Linux and Windows
// preset=p2 - faster, tune=ll - low latency // preset=p2 - faster, tune=ll - low latency
"h264/cuda": "-c:v h264_nvenc -g 50 -profile:v high -level:v auto -preset:v p2 -tune:v ll", "h264/cuda": "-c:v h264_nvenc -g 50 -bf 0 -profile:v high -level:v auto -preset:v p2 -tune:v ll",
"h265/cuda": "-c:v hevc_nvenc -g 50 -profile:v high -level:v auto", "h265/cuda": "-c:v hevc_nvenc -g 50 -bf 0 -profile:v high -level:v auto",
// hardware Intel on Windows // hardware Intel on Windows
"h264/dxva2": "-c:v h264_qsv -g 50 -bf 0 -profile:v high -level:v 4.1 -async_depth:v 1", "h264/dxva2": "-c:v h264_qsv -g 50 -bf 0 -profile:v high -level:v 4.1 -async_depth:v 1",
@@ -234,6 +234,18 @@ func parseArgs(s string) *ffmpeg.Args {
} }
} }
for _, drawtext := range query["drawtext"] {
// support templates https://github.com/AlexxIT/go2rtc/issues/487
drawtext = configTemplate(drawtext)
// support default timestamp format
if !strings.Contains(drawtext, "text=") {
drawtext += `:text='%{localtime\:%Y-%m-%d %X}'`
}
args.AddFilter("drawtext=" + drawtext)
}
// 3. Process video codecs // 3. Process video codecs
if args.Video > 0 { if args.Video > 0 {
for _, video := range query["video"] { for _, video := range query["video"] {

View File

@@ -55,33 +55,51 @@ func MakeHardware(args *ffmpeg.Args, engine string, defaults map[string]string)
switch engine { switch engine {
case EngineVAAPI: case EngineVAAPI:
args.Input = "-hwaccel vaapi -hwaccel_output_format vaapi " + args.Input
args.Codecs[i] = defaults[name+"/"+engine] args.Codecs[i] = defaults[name+"/"+engine]
for i, filter := range args.Filters { if !args.HasFilters("drawtext=") {
if strings.HasPrefix(filter, "scale=") { args.Input = "-hwaccel vaapi -hwaccel_output_format vaapi " + args.Input
args.Filters[i] = "scale_vaapi=" + filter[6:]
} for i, filter := range args.Filters {
if strings.HasPrefix(filter, "transpose=") { if strings.HasPrefix(filter, "scale=") {
if filter == "transpose=1,transpose=1" { // 180 degrees half-turn args.Filters[i] = "scale_vaapi=" + filter[6:]
args.Filters[i] = "transpose_vaapi=4" // reversal }
} else { if strings.HasPrefix(filter, "transpose=") {
args.Filters[i] = "transpose_vaapi=" + filter[10:] if filter == "transpose=1,transpose=1" { // 180 degrees half-turn
args.Filters[i] = "transpose_vaapi=4" // reversal
} else {
args.Filters[i] = "transpose_vaapi=" + filter[10:]
}
} }
} }
// fix if input doesn't support hwaccel, do nothing when support
// insert as first filter before hardware scale and transpose
args.InsertFilter("format=vaapi|nv12,hwupload")
} else {
// enable software pixel for drawtext, scale and transpose
args.Input = "-hwaccel vaapi -hwaccel_output_format nv12 " + args.Input
args.AddFilter("hwupload")
} }
// fix if input doesn't support hwaccel, do nothing when support
args.InsertFilter("format=vaapi|nv12,hwupload")
case EngineCUDA: case EngineCUDA:
args.Input = "-hwaccel cuda -hwaccel_output_format cuda -extra_hw_frames 2 " + args.Input
args.Codecs[i] = defaults[name+"/"+engine] args.Codecs[i] = defaults[name+"/"+engine]
for i, filter := range args.Filters { // CUDA doesn't support hardware transpose
if strings.HasPrefix(filter, "scale=") { // https://github.com/AlexxIT/go2rtc/issues/389
args.Filters[i] = "scale_cuda=" + filter[6:] if !args.HasFilters("drawtext=", "transpose=") {
args.Input = "-hwaccel cuda -hwaccel_output_format cuda " + args.Input
for i, filter := range args.Filters {
if strings.HasPrefix(filter, "scale=") {
args.Filters[i] = "scale_cuda=" + filter[6:]
}
} }
} else {
args.Input = "-hwaccel cuda -hwaccel_output_format nv12 " + args.Input
args.AddFilter("hwupload")
} }
case EngineDXVA2: case EngineDXVA2:

View File

@@ -29,6 +29,18 @@ func (a *Args) InsertFilter(filter string) {
a.Filters = append([]string{filter}, a.Filters...) a.Filters = append([]string{filter}, a.Filters...)
} }
func (a *Args) HasFilters(filters ...string) bool {
for _, f1 := range a.Filters {
for _, f2 := range filters {
if strings.HasPrefix(f1, f2) {
return true
}
}
}
return false
}
func (a *Args) String() string { func (a *Args) String() string {
b := bytes.NewBuffer(make([]byte, 0, 512)) b := bytes.NewBuffer(make([]byte, 0, 512))
@@ -65,12 +77,13 @@ func (a *Args) String() string {
if a.Filters != nil { if a.Filters != nil {
for i, filter := range a.Filters { for i, filter := range a.Filters {
if i == 0 { if i == 0 {
b.WriteString(" -vf ") b.WriteString(` -vf "`)
} else { } else {
b.WriteByte(',') b.WriteByte(',')
} }
b.WriteString(filter) b.WriteString(filter)
} }
b.WriteByte('"')
} }
b.WriteByte(' ') b.WriteByte(' ')