Skip to content

Commit

Permalink
Auto merge of #261 - pch07/ffmpeg_non_io_tests, r=TroyKomodo
Browse files Browse the repository at this point in the history
Pch07/ffmpeg non io tests
Added tests to the non io files in the ffmpeg crate.

So far I have only run into one issue:
In the `logs.rs` file, I updated some log levels to their respective names in `log_callback_tracing()`, let me know if this change is appropriate. Additionally, `test_log_callback_tracing()` excludes the `tracing::warn!` case because it doesn't work for some reason; I couldn't figure this out.

In the `frame.rs` file, the last test is incorrect due to `is_audio()` returning `false` instead of `true`. I left it commented for now.

In the `encoder.rs` file, I didn't include tests for the `Encoder::send_frame()`, `Encoder::receive_packet()`, `MuxerEncoder::send_eof()`, `MuxerEncoder::send_frame()`, or `MuxerEncoder::handle_packets()` functions.

In the `decoder.rs` file, I didn't include tests for `GenericDecoder::send_packet()`, `GenericDecoder::send_eof()`, or `GenericDecoder::receive_frame()` functions.

The untested functions are due to them being kinda complex (also they seem to be related to the untested functions in the ffmpeg/io folder. It would probably be better to work on all of those in one go since it seems pretty technical.

Requested-by: TroyKomodo <[email protected]>
Reviewed-by: TroyKomodo <[email protected]>
  • Loading branch information
scuffle-brawl[bot] authored Jan 28, 2025
2 parents 6457685 + 34c6271 commit 1776e79
Show file tree
Hide file tree
Showing 18 changed files with 3,409 additions and 249 deletions.
87 changes: 82 additions & 5 deletions Cargo.lock

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

3 changes: 3 additions & 0 deletions crates/ffmpeg/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,13 @@ arc-swap = { version = "1.7" }
ffmpeg-sys-next = { version = "7.1.0" }
scuffle-workspace-hack.workspace = true
rand = "0.8"
bon = "3.3.2"

[dev-dependencies]
insta = {version = "1.42", features = ["filters"]}
tempfile = "3.15"
tracing-test = "0.2"
tracing-subscriber = "0.3"

[features]
channel = ["dep:bytes"]
Expand Down
180 changes: 180 additions & 0 deletions crates/ffmpeg/src/codec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,3 +128,183 @@ impl From<DecoderCodec> for *const AVCodec {
codec.0
}
}

#[cfg(test)]
#[cfg_attr(all(test, coverage_nightly), coverage(off))]
mod tests {
use ffmpeg_sys_next::AVCodecID::{self, AV_CODEC_ID_AAC, AV_CODEC_ID_H264};
use ffmpeg_sys_next::{avcodec_find_decoder, avcodec_find_encoder, AVCodec};

use crate::codec::{DecoderCodec, EncoderCodec};

#[test]
fn test_decoder_codec_debug_null() {
let decoder_codec = DecoderCodec::empty();
let debug_output = format!("{:?}", decoder_codec);

insta::assert_snapshot!(debug_output, @r#"DecoderCodec { name: "null", id: AV_CODEC_ID_NONE }"#);
}

#[test]
fn test_decoder_codec_debug_non_null() {
let decoder_codec = DecoderCodec::new(AV_CODEC_ID_H264).expect("H264 codec should be available");
let debug_output = format!("{:?}", decoder_codec);

insta::assert_snapshot!(debug_output, @r#"DecoderCodec { name: "h264", id: AV_CODEC_ID_H264 }"#);
}

#[test]
fn test_decoder_codec_new_invalid_codec_id() {
let invalid_codec_id = AVCodecID::AV_CODEC_ID_NONE;
let result = DecoderCodec::new(invalid_codec_id);

assert!(
result.is_none(),
"Expected `DecoderCodec::new` to return None for an invalid codec ID"
);
}

#[test]
fn test_decoder_codec_by_name_valid() {
let result = DecoderCodec::by_name("h264");

assert!(
result.is_some(),
"Expected `DecoderCodec::by_name` to return Some for a valid codec name"
);

let codec = result.unwrap();
assert!(!codec.as_ptr().is_null(), "Expected a non-null codec pointer");
}

#[test]
fn test_decoder_codec_by_name_invalid() {
let invalid_codec_name = "nonexistent_codec";
let result = DecoderCodec::by_name(invalid_codec_name);

assert!(
result.is_none(),
"Expected `DecoderCodec::by_name` to return None for an invalid codec name"
);
}

#[test]
fn test_decoder_codec_from_ptr_valid() {
let codec_ptr = unsafe { avcodec_find_decoder(AVCodecID::AV_CODEC_ID_H264) };
assert!(!codec_ptr.is_null(), "Expected a valid codec pointer for H264");

let decoder_codec = DecoderCodec::from_ptr(codec_ptr);
assert_eq!(
decoder_codec.as_ptr(),
codec_ptr,
"Expected the codec pointer in DecoderCodec to match the original pointer"
);
}

#[test]
fn test_encoder_codec_debug_valid() {
let codec_ptr = unsafe { avcodec_find_encoder(AVCodecID::AV_CODEC_ID_MPEG4) };
assert!(!codec_ptr.is_null(), "Expected a valid codec pointer for MPEG4");

let encoder_codec = EncoderCodec(codec_ptr);
insta::assert_debug_snapshot!(encoder_codec, @r#"
EncoderCodec {
name: "mpeg4",
id: AV_CODEC_ID_MPEG4,
}
"#);
}

#[test]
fn test_encoder_codec_debug_null() {
let encoder_codec = EncoderCodec(std::ptr::null());
insta::assert_debug_snapshot!(encoder_codec, @r#"
EncoderCodec {
name: "null",
id: AV_CODEC_ID_NONE,
}
"#);
}

#[test]
fn test_encoder_codec_empty() {
let encoder_codec = EncoderCodec::empty();
assert!(
encoder_codec.as_ptr().is_null(),
"Expected the encoder codec pointer to be null"
);

insta::assert_debug_snapshot!(encoder_codec, @r#"
EncoderCodec {
name: "null",
id: AV_CODEC_ID_NONE,
}
"#);
}

#[test]
fn test_encoder_codec_new_invalid_codec() {
let invalid_codec_id = AVCodecID::AV_CODEC_ID_NONE;
let result = EncoderCodec::new(invalid_codec_id);

assert!(result.is_none(), "Expected None for an invalid codec ID");
}

#[test]
fn test_encoder_codec_by_name_valid() {
let result = EncoderCodec::by_name("mpeg4");
assert!(result.is_some(), "Expected a valid encoder codec for the name {}", "mpeg4");

let encoder_codec = result.unwrap();
assert!(!encoder_codec.as_ptr().is_null(), "Expected a non-null encoder codec pointer");
}

#[test]
fn test_encoder_codec_by_name_invalid() {
let invalid_encoder_name = "invalid_encoder_name";
let result = EncoderCodec::by_name(invalid_encoder_name);

assert!(
result.is_none(),
"Expected None for an invalid encoder name {}",
invalid_encoder_name
);
}

#[test]
fn test_encoder_codec_into_raw_ptr() {
let valid_codec_id = AV_CODEC_ID_AAC;
let encoder_codec = EncoderCodec::new(valid_codec_id).expect("Expected a valid encoder codec for AAC");
let raw_ptr: *const AVCodec = encoder_codec.into();

assert_eq!(
raw_ptr,
encoder_codec.as_ptr(),
"The raw pointer should match the encoder codec's internal pointer"
);
}

#[test]
fn test_decoder_codec_into_raw_ptr() {
let valid_codec_id = AV_CODEC_ID_AAC;
let decoder_codec = DecoderCodec::new(valid_codec_id).expect("Expected a valid decoder codec for AAC");
let raw_ptr: *const AVCodec = decoder_codec.into();

assert_eq!(
raw_ptr,
decoder_codec.as_ptr(),
"The raw pointer should match the decoder codec's internal pointer"
);
}

#[test]
fn test_codec_into_raw_ptr_empty() {
let empty_encoder_codec = EncoderCodec::empty();
let raw_ptr: *const AVCodec = empty_encoder_codec.into();
assert!(raw_ptr.is_null(), "The raw pointer should be null for an empty EncoderCodec");

let empty_decoder_codec = DecoderCodec::empty();
let raw_ptr: *const AVCodec = empty_decoder_codec.into();
assert!(raw_ptr.is_null(), "The raw pointer should be null for an empty DecoderCodec");
}
}
23 changes: 23 additions & 0 deletions crates/ffmpeg/src/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,26 @@ impl<T> std::ops::DerefMut for Mut<'_, T> {
&mut self.0
}
}

#[cfg(test)]
#[cfg_attr(all(test, coverage_nightly), coverage(off))]
mod tests {
use crate::consts::Mut;

#[test]
fn test_mut_fmt_vec() {
let value = vec![1, 2, 3];
let mut_value = Mut::new(value);

assert_eq!(format!("{:?}", mut_value), "[1, 2, 3]");
}

#[test]
fn test_deref_for_mut_with_complex_type() {
let value = vec![1, 2, 3];
let mut_value = Mut::new(value);
let deref_value: &Vec<i32> = &mut_value;

assert_eq!(deref_value, &vec![1, 2, 3], "Dereferencing Mut should return the inner value");
}
}
Loading

0 comments on commit 1776e79

Please sign in to comment.