Skip to content

Commit

Permalink
Bump ffmpeg version to 7.0 (#74)
Browse files Browse the repository at this point in the history
  • Loading branch information
Polochon-street authored May 12, 2024
1 parent c212659 commit c47fd6d
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 13 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Changelog

## bliss 0.7.0
* Bump ffmpeg-next version to 7.0
* Bump aubio-rs custom crate to disable compiling it with -std=c99
* Add the possibility to make playlists based on multiple songs using extended
isolation forest (Thanks @SimonTeixidor!)
Expand Down
34 changes: 27 additions & 7 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ serde = ["dep:serde", "extended-isolation-forest/serde"]
# Until https://github.com/aubio/aubio/issues/336 is somehow solved
# Hopefully we'll be able to use the official aubio-rs at some point.
bliss-audio-aubio-rs = "0.2.2"
ffmpeg-next = "6.1.1"
ffmpeg-sys-next = { version = "6.1.0", default-features = false }
ffmpeg-next = "7.0.1"
ffmpeg-sys-next = { version = "7.0.0", default-features = false }
log = "0.4.17"
# `rayon` is used only by `par_mapv_inplace` in chroma.rs.
# TODO: is the speed gain that substantial?
Expand Down
27 changes: 23 additions & 4 deletions src/song.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,10 @@ impl Analysis {
}
}

// Safe because the other thread just reads the channel layout
struct SendChannelLayout(ChannelLayout);
unsafe impl Send for SendChannelLayout {}

impl Song {
/// Returns a decoded [Song] given a file path, or an error if the song
/// could not be analyzed for some reason.
Expand Down Expand Up @@ -445,23 +449,31 @@ impl Song {
t => Some(t.to_string()),
};
};

#[cfg(not(feature = "ffmpeg_7_0"))]
let is_channel_layout_empty = decoder.channel_layout() == ChannelLayout::empty();
#[cfg(feature = "ffmpeg_7_0")]
let is_channel_layout_empty = decoder.channel_layout().is_empty();

let (empty_in_channel_layout, in_channel_layout) = {
if decoder.channel_layout() == ChannelLayout::empty() {
if is_channel_layout_empty {
(true, ChannelLayout::default(decoder.channels().into()))
} else {
(false, decoder.channel_layout())
}
};
decoder.set_channel_layout(in_channel_layout);

let in_channel_layout_to_send = SendChannelLayout(in_channel_layout);

let (tx, rx) = mpsc::channel();
let in_codec_format = decoder.format();
let in_codec_rate = decoder.rate();
let child = thread::spawn(move || {
resample_frame(
rx,
in_codec_format,
in_channel_layout,
in_channel_layout_to_send,
in_codec_rate,
sample_array,
empty_in_channel_layout,
Expand Down Expand Up @@ -547,6 +559,7 @@ impl Song {
}

drop(tx);
// Waiting here ensures that ChannelLayout doesn't get dropped in the middle
song.sample_array = child.join().unwrap()?;
let duration_seconds = song.sample_array.len() as f32 / SAMPLE_RATE as f32;
song.duration = Duration::from_nanos((duration_seconds * 1e9_f32).round() as u64);
Expand All @@ -570,11 +583,12 @@ pub(crate) struct InternalSong {
fn resample_frame(
rx: Receiver<Audio>,
in_codec_format: Sample,
in_channel_layout: ChannelLayout,
sent_in_channel_layout: SendChannelLayout,
in_rate: u32,
mut sample_array: Vec<f32>,
empty_in_channel_layout: bool,
) -> BlissResult<Vec<f32>> {
let in_channel_layout = sent_in_channel_layout.0;
let mut resample_context = ffmpeg::software::resampling::context::Context::get(
in_codec_format,
in_channel_layout,
Expand All @@ -592,10 +606,15 @@ fn resample_frame(
let mut resampled = ffmpeg::frame::Audio::empty();
let mut something_happened = false;
for mut decoded in rx.iter() {
#[cfg(not(feature = "ffmpeg_7_0"))]
let is_channel_layout_empty = decoded.channel_layout() == ChannelLayout::empty();
#[cfg(feature = "ffmpeg_7_0")]
let is_channel_layout_empty = decoded.channel_layout().is_empty();

// If the decoded layout is empty, it means we forced the
// "in_channel_layout" to something default, not that
// the format is wrong.
if empty_in_channel_layout && decoded.channel_layout() == ChannelLayout::empty() {
if empty_in_channel_layout && is_channel_layout_empty {
decoded.set_channel_layout(in_channel_layout);
} else if in_codec_format != decoded.format()
|| (in_channel_layout != decoded.channel_layout())
Expand Down

0 comments on commit c47fd6d

Please sign in to comment.