Skip to content

Commit

Permalink
Adding tests to compare generated image data
Browse files Browse the repository at this point in the history
  • Loading branch information
sandeepbansal authored and ralfbiedert committed Oct 16, 2022
1 parent 320e985 commit 0b302b5
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 14 deletions.
4 changes: 4 additions & 0 deletions openh264/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,7 @@ openh264-sys2 = { path = "../openh264-sys2", version = "0.2.5", default-features
[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]

[dev-dependencies]
image = "0.24.4"
image-compare = "0.2.3"
18 changes: 11 additions & 7 deletions openh264/src/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ use crate::formats::YUVSource;
use crate::Error;
use openh264_sys2::{
videoFormatI420, ISVCDecoder, ISVCDecoderVtbl, SBufferInfo, SDecodingParam, SParserBsInfo, SSysMEMBuffer, WelsCreateDecoder,
WelsDestroyDecoder, DECODER_OPTION, DECODER_OPTION_ERROR_CON_IDC, DECODER_OPTION_NUM_OF_THREADS, DECODER_OPTION_TRACE_LEVEL,
DECODING_STATE, WELS_LOG_DETAIL, WELS_LOG_QUIET, DECODER_OPTION_NUM_OF_FRAMES_REMAINING_IN_BUFFER,
WelsDestroyDecoder, DECODER_OPTION, DECODER_OPTION_ERROR_CON_IDC, DECODER_OPTION_NUM_OF_FRAMES_REMAINING_IN_BUFFER,
DECODER_OPTION_NUM_OF_THREADS, DECODER_OPTION_TRACE_LEVEL, DECODING_STATE, WELS_LOG_DETAIL, WELS_LOG_QUIET,
};
use std::os::raw::{c_int, c_long, c_uchar, c_void};
use std::ptr::{addr_of_mut, null, null_mut};
Expand Down Expand Up @@ -188,15 +188,19 @@ impl Decoder {

if buffer_info.iBufferStatus != 1 {
let mut num_frames: DECODER_OPTION = 0;
self.raw_api().get_option(DECODER_OPTION_NUM_OF_FRAMES_REMAINING_IN_BUFFER,
addr_of_mut!(num_frames).cast()).ok()?;
if num_frames > 0 {
self.raw_api()
.get_option(
DECODER_OPTION_NUM_OF_FRAMES_REMAINING_IN_BUFFER,
addr_of_mut!(num_frames).cast(),
)
.ok()?;
if num_frames > 0 {
self.raw_api().flush_frame(&mut dst as *mut _, &mut buffer_info).ok()?;

if buffer_info.iBufferStatus != 1 {
return Err(Error::msg("Buffer status not valid"));
}
}
}
}

let info = buffer_info.UsrData.sSystemBuffer;
Expand Down
4 changes: 3 additions & 1 deletion openh264/src/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ use crate::error::NativeErrorExt;
use crate::formats::YUVSource;
use crate::Error;
use openh264_sys2::{
videoFormatI420, EVideoFormatType, ISVCEncoder, ISVCEncoderVtbl, SEncParamBase, SEncParamExt, SFrameBSInfo, SLayerBSInfo, SSourcePicture, WelsCreateSVCEncoder, WelsDestroySVCEncoder, ENCODER_OPTION, ENCODER_OPTION_DATAFORMAT, ENCODER_OPTION_TRACE_LEVEL, RC_MODES, VIDEO_CODING_LAYER, WELS_LOG_DETAIL, WELS_LOG_QUIET
videoFormatI420, EVideoFormatType, ISVCEncoder, ISVCEncoderVtbl, SEncParamBase, SEncParamExt, SFrameBSInfo, SLayerBSInfo,
SSourcePicture, WelsCreateSVCEncoder, WelsDestroySVCEncoder, ENCODER_OPTION, ENCODER_OPTION_DATAFORMAT,
ENCODER_OPTION_TRACE_LEVEL, RC_MODES, VIDEO_CODING_LAYER, WELS_LOG_DETAIL, WELS_LOG_QUIET,
};
use std::os::raw::{c_int, c_uchar, c_void};
use std::ptr::{addr_of_mut, null, null_mut};
Expand Down
Binary file added openh264/tests/data/multi_1024x768.bmp
Binary file not shown.
33 changes: 27 additions & 6 deletions openh264/tests/decode.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
#![cfg(feature = "decoder")]

use std::io::Read;
use std::io::{Cursor, Read};

use image::RgbImage;
use openh264::decoder::{Decoder, DecoderConfig};
use openh264::{nal_units, Error};

Expand Down Expand Up @@ -83,14 +84,34 @@ fn can_decode_multi_by_step() -> Result<(), Error> {
#[test]
fn decodes_file_requiring_flush_frame() -> Result<(), Error> {
let src = &include_bytes!("data/multi_1024x768.raw")[..];
let compare_data = &include_bytes!("data/multi_1024x768.bmp")[..];

let config = DecoderConfig::default();
let mut decoder = Decoder::with_config(config)?;

let mut decoded = None;

for packet in read_frame(src) {
decoder.decode(packet.as_slice())?;
decoded = Some(decoder.decode(packet.as_slice())?);
}

// Generate image from decoded frame
let decoded_frame = decoded.expect("No decoded data");
let dimensions = decoded_frame.dimension_rgb();
let mut frame_data = vec![0u8; dimensions.0 * dimensions.1 * 3];
decoded_frame.write_rgb8(frame_data.as_mut_slice())?;
let decoded_frame = RgbImage::from_vec(1024, 768, frame_data).expect("Failed to convert into image buffer");

// Get compare image
let compare_data = Cursor::new(compare_data);
let compare_data = image::load(compare_data, image::ImageFormat::Bmp)
.expect("Image load failed")
.into_rgb8();

let result = image_compare::rgb_hybrid_compare(&decoded_frame, &compare_data).expect("Image dimensitons are different");
// Images should be 99% similar
assert!(result.score > 0.99, "Image similarity score: {}", result.score);

Ok(())
}

Expand Down Expand Up @@ -133,7 +154,7 @@ fn what_goes_around_comes_around() -> Result<(), Error> {
// The packets in the file are written frame by frame
// the first 4 bytes are frame length in little endian
// followed by actual frame data
pub fn read_frame<T>(mut stream: T) -> impl Iterator<Item = Vec<u8>>
pub fn read_frame<T>(mut stream: T) -> impl Iterator<Item = Vec<u8>>
where
T: Read,
{
Expand All @@ -143,15 +164,15 @@ where
if result.is_err() {
return None;
}

let len = u32::from_le_bytes(data) as usize;
let mut data = vec![0u8; len];

let result = stream.read_exact(data.as_mut_slice());
if result.is_err() {
return None
None
} else {
Some(data)
}
})
}
}

0 comments on commit 0b302b5

Please sign in to comment.