Compare commits
1 commit
main
...
overlay_va
Author | SHA1 | Date | |
---|---|---|---|
fc881cff08 |
3 changed files with 69 additions and 18 deletions
|
@ -1,6 +1,6 @@
|
||||||
use super::{cmd, filter::Filter};
|
use super::{cmd, filter::Filter};
|
||||||
use crate::{
|
use crate::{
|
||||||
render::filter::channel,
|
render::filter::{channel, next_tmp},
|
||||||
time::{format_time, Time},
|
time::{format_time, Time},
|
||||||
Resolution
|
Resolution
|
||||||
};
|
};
|
||||||
|
@ -107,9 +107,17 @@ enum FfmpegFilter {
|
||||||
Rescale(Resolution)
|
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 {
|
pub(crate) struct Ffmpeg {
|
||||||
inputs: Vec<FfmpegInput>,
|
inputs: Vec<FfmpegInput>,
|
||||||
filter: FfmpegFilter,
|
filter: FfmpegFilter,
|
||||||
|
overlay: Option<FfmpegOverlay>,
|
||||||
video_bitrate: Option<&'static str>,
|
video_bitrate: Option<&'static str>,
|
||||||
output: FfmpegOutput,
|
output: FfmpegOutput,
|
||||||
|
|
||||||
|
@ -121,6 +129,7 @@ impl Ffmpeg {
|
||||||
Self {
|
Self {
|
||||||
inputs: Vec::new(),
|
inputs: Vec::new(),
|
||||||
filter: FfmpegFilter::None,
|
filter: FfmpegFilter::None,
|
||||||
|
overlay: None,
|
||||||
video_bitrate: None,
|
video_bitrate: None,
|
||||||
output,
|
output,
|
||||||
|
|
||||||
|
@ -182,6 +191,11 @@ impl Ffmpeg {
|
||||||
self
|
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 {
|
pub fn set_video_bitrate(&mut self, bitrate: &'static str) -> &mut Self {
|
||||||
self.video_bitrate = Some(bitrate);
|
self.video_bitrate = Some(bitrate);
|
||||||
self
|
self
|
||||||
|
@ -229,10 +243,52 @@ impl Ffmpeg {
|
||||||
for filter in filters {
|
for filter in filters {
|
||||||
filter.append_to_complex_filter(&mut complex, &mut self.filter_idx);
|
filter.append_to_complex_filter(&mut complex, &mut self.filter_idx);
|
||||||
}
|
}
|
||||||
|
if let Some(FfmpegOverlay {
|
||||||
|
overlay_input,
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
alpha
|
||||||
|
}) = self.overlay
|
||||||
|
{
|
||||||
|
let tmp = next_tmp(&mut self.filter_idx);
|
||||||
if vaapi {
|
if vaapi {
|
||||||
write!(complex, "{}format=nv12,hwupload[v]", channel('v', &output));
|
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 {
|
} else {
|
||||||
write!(complex, "{}null[v]", channel('v', &output));
|
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 {
|
||||||
|
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("-filter_complex").arg(complex);
|
||||||
cmd.arg("-map").arg("[v]");
|
cmd.arg("-map").arg("[v]");
|
||||||
|
|
|
@ -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;
|
*filter_idx += 1;
|
||||||
format!("[tmp{filter_idx}]")
|
format!("[tmp{filter_idx}]")
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,10 @@
|
||||||
pub mod ffmpeg;
|
pub mod ffmpeg;
|
||||||
mod filter;
|
mod filter;
|
||||||
|
|
||||||
use self::{ffmpeg::FfmpegOutput, filter::Filter};
|
use self::{
|
||||||
|
ffmpeg::{FfmpegOutput, FfmpegOverlay},
|
||||||
|
filter::Filter
|
||||||
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
iotro::{intro, outro},
|
iotro::{intro, outro},
|
||||||
render::ffmpeg::{Ffmpeg, FfmpegInput},
|
render::ffmpeg::{Ffmpeg, FfmpegInput},
|
||||||
|
@ -426,23 +429,15 @@ impl<'a> Renderer<'a> {
|
||||||
});
|
});
|
||||||
|
|
||||||
// overlay the logo
|
// overlay the logo
|
||||||
let logoalpha = "logoalpha";
|
ffmpeg.enable_overlay(FfmpegOverlay {
|
||||||
ffmpeg.add_filter(Filter::Alpha {
|
overlay_input: logo.into(),
|
||||||
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(),
|
|
||||||
x: "main_w-overlay_w-130".into(),
|
x: "main_w-overlay_w-130".into(),
|
||||||
y: "main_h-overlay_h-65".into(),
|
y: "main_h-overlay_h-65".into(),
|
||||||
output: overlay.into()
|
alpha: Rational::new(1, 2)
|
||||||
});
|
});
|
||||||
|
|
||||||
// we're done :)
|
// we're done :)
|
||||||
ffmpeg.set_filter_output(overlay);
|
ffmpeg.set_filter_output(concat);
|
||||||
ffmpeg.run()?;
|
ffmpeg.run()?;
|
||||||
|
|
||||||
Ok(output)
|
Ok(output)
|
||||||
|
|
Loading…
Reference in a new issue