Improve gif handling.

- Allow a fast-path exif cleaning if we'd re-encode a gif to a gif
- Use single-frame palettes to better map transparency from frame to frame

Unrelated:
- decrease ffmpeg logging when creating thumbnails
This commit is contained in:
asonix 2023-06-19 14:25:22 -05:00
parent 0833271281
commit a3a986638d
2 changed files with 31 additions and 7 deletions

View file

@ -50,6 +50,13 @@ impl TranscodeOptions {
}
}
pub(crate) const fn needs_reencode(&self) -> bool {
!matches!(
(self.input_format, &self.output),
(VideoFormat::Gif, TranscodeOutputOptions::Gif)
)
}
const fn input_file_extension(&self) -> &'static str {
self.input_format.to_file_extension()
}
@ -92,10 +99,12 @@ impl TranscodeOptions {
match self.output {
TranscodeOutputOptions::Gif => Process::run("ffmpeg", &[
"-hide_banner",
"-v",
"warning",
"-i",
input_path,
"-filter_complex",
"[0:v] split [a][b]; [a] palettegen=reserve_transparent=on:transparency_color=ffffff [p]; [b][p] paletteuse",
"[0:v] split [a][b]; [a] palettegen=stats_mode=single [p]; [b][p] paletteuse=new=1",
"-an",
"-f",
self.output_ffmpeg_format(),
@ -108,6 +117,8 @@ impl TranscodeOptions {
"ffmpeg",
&[
"-hide_banner",
"-v",
"warning",
"-i",
input_path,
"-pix_fmt",
@ -129,6 +140,8 @@ impl TranscodeOptions {
"ffmpeg",
&[
"-hide_banner",
"-v",
"warning",
"-i",
input_path,
"-pix_fmt",
@ -576,6 +589,8 @@ pub(crate) async fn thumbnail<S: Store>(
"ffmpeg",
&[
"-hide_banner",
"-v",
"warning",
"-i",
input_file_str,
"-frames:v",

View file

@ -59,12 +59,21 @@ pub(crate) async fn validate_bytes(
}
let transcode_options = TranscodeOptions::new(media, &details, video_format);
Ok((
transcode_options.output_type(),
Either::right(Either::left(Either::left(
crate::ffmpeg::transcode_bytes(bytes, transcode_options).await?,
))),
))
if transcode_options.needs_reencode() {
Ok((
transcode_options.output_type(),
Either::right(Either::left(Either::left(
crate::ffmpeg::transcode_bytes(bytes, transcode_options).await?,
))),
))
} else {
Ok((
transcode_options.output_type(),
Either::right(Either::right(crate::exiftool::clear_metadata_bytes_read(
bytes,
)?)),
))
}
}
(FileFormat::Image(image_format), Some(format)) if image_format != format => Ok((
ValidInputType::from_format(format),