From fc881cff08422f9150717fdf53954ac6bd2697bf Mon Sep 17 00:00:00 2001
From: Dominic <git@msrd0.de>
Date: Thu, 16 Nov 2023 09:56:34 +0100
Subject: [PATCH] try using overlay_vaapi filter

---
 src/render/ffmpeg.rs | 64 +++++++++++++++++++++++++++++++++++++++++---
 src/render/filter.rs |  2 +-
 src/render/mod.rs    | 21 ++++++---------
 3 files changed, 69 insertions(+), 18 deletions(-)

diff --git a/src/render/ffmpeg.rs b/src/render/ffmpeg.rs
index 614ad19..8cc8a09 100644
--- a/src/render/ffmpeg.rs
+++ b/src/render/ffmpeg.rs
@@ -1,6 +1,6 @@
 use super::{cmd, filter::Filter};
 use crate::{
-	render::filter::channel,
+	render::filter::{channel, next_tmp},
 	time::{format_time, Time},
 	Resolution
 };
@@ -107,9 +107,17 @@ enum FfmpegFilter {
 	Rescale(Resolution)
 }
 
+pub(crate) struct FfmpegOverlay {
+	pub(crate) overlay_input: Cow<'static, str>,
+	pub(crate) x: Cow<'static, str>,
+	pub(crate) y: Cow<'static, str>,
+	pub(crate) alpha: Rational
+}
+
 pub(crate) struct Ffmpeg {
 	inputs: Vec<FfmpegInput>,
 	filter: FfmpegFilter,
+	overlay: Option<FfmpegOverlay>,
 	video_bitrate: Option<&'static str>,
 	output: FfmpegOutput,
 
@@ -121,6 +129,7 @@ impl Ffmpeg {
 		Self {
 			inputs: Vec::new(),
 			filter: FfmpegFilter::None,
+			overlay: None,
 			video_bitrate: None,
 			output,
 
@@ -182,6 +191,11 @@ impl Ffmpeg {
 		self
 	}
 
+	pub fn enable_overlay(&mut self, overlay: FfmpegOverlay) -> &mut Self {
+		self.overlay = Some(overlay);
+		self
+	}
+
 	pub fn set_video_bitrate(&mut self, bitrate: &'static str) -> &mut Self {
 		self.video_bitrate = Some(bitrate);
 		self
@@ -229,10 +243,52 @@ impl Ffmpeg {
 				for filter in filters {
 					filter.append_to_complex_filter(&mut complex, &mut self.filter_idx);
 				}
-				if vaapi {
-					write!(complex, "{}format=nv12,hwupload[v]", channel('v', &output));
+				if let Some(FfmpegOverlay {
+					overlay_input,
+					x,
+					y,
+					alpha
+				}) = self.overlay
+				{
+					let tmp = next_tmp(&mut self.filter_idx);
+					if vaapi {
+						writeln!(
+							complex,
+							"{}format=nv12,hwupload{tmp};",
+							channel('v', &output)
+						);
+						let tmp2 = next_tmp(&mut self.filter_idx);
+						writeln!(
+							complex,
+							"{}format=nv12,hwupload{tmp2};",
+							channel('v', &overlay_input)
+						);
+						writeln!(
+							complex,
+							"{tmp}{tmp2}overlay_vaapi=x={x}:y={y}:alpha={alpha}[v]"
+						);
+					} else {
+						writeln!(
+							complex,
+							"{}format=yuva444p,colorchannelmixer=aa={alpha}{tmp};",
+							channel('v', &output)
+						);
+						writeln!(
+							complex,
+							"{tmp}{}overlay=x={x}:y={y}[v]",
+							channel('v', &overlay_input)
+						);
+					}
 				} else {
-					write!(complex, "{}null[v]", channel('v', &output));
+					if vaapi {
+						writeln!(
+							complex,
+							"{}format=nv12,hwupload[v]",
+							channel('v', &output)
+						);
+					} else {
+						writeln!(complex, "{}null[v]", channel('v', &output));
+					}
 				}
 				cmd.arg("-filter_complex").arg(complex);
 				cmd.arg("-map").arg("[v]");
diff --git a/src/render/filter.rs b/src/render/filter.rs
index 6a76ccc..fc0c720 100644
--- a/src/render/filter.rs
+++ b/src/render/filter.rs
@@ -234,7 +234,7 @@ pub(super) fn channel(channel: char, id: &str) -> String {
 	}
 }
 
-fn next_tmp(filter_idx: &mut usize) -> String {
+pub(super) fn next_tmp(filter_idx: &mut usize) -> String {
 	*filter_idx += 1;
 	format!("[tmp{filter_idx}]")
 }
diff --git a/src/render/mod.rs b/src/render/mod.rs
index 3b9257c..75d440c 100644
--- a/src/render/mod.rs
+++ b/src/render/mod.rs
@@ -3,7 +3,10 @@
 pub mod ffmpeg;
 mod filter;
 
-use self::{ffmpeg::FfmpegOutput, filter::Filter};
+use self::{
+	ffmpeg::{FfmpegOutput, FfmpegOverlay},
+	filter::Filter
+};
 use crate::{
 	iotro::{intro, outro},
 	render::ffmpeg::{Ffmpeg, FfmpegInput},
@@ -426,23 +429,15 @@ impl<'a> Renderer<'a> {
 		});
 
 		// overlay the logo
-		let logoalpha = "logoalpha";
-		ffmpeg.add_filter(Filter::Alpha {
-			input: logo.into(),
-			alpha: 0.5,
-			output: logoalpha.into()
-		});
-		let overlay = "overlay";
-		ffmpeg.add_filter(Filter::Overlay {
-			video_input: concat.into(),
-			overlay_input: logoalpha.into(),
+		ffmpeg.enable_overlay(FfmpegOverlay {
+			overlay_input: logo.into(),
 			x: "main_w-overlay_w-130".into(),
 			y: "main_h-overlay_h-65".into(),
-			output: overlay.into()
+			alpha: Rational::new(1, 2)
 		});
 
 		// we're done :)
-		ffmpeg.set_filter_output(overlay);
+		ffmpeg.set_filter_output(concat);
 		ffmpeg.run()?;
 
 		Ok(output)
-- 
GitLab