use futures_util::StreamExt;
use rs2_stream::media::codec::{CodecFactory, EncodingConfig, MediaCodec, RawMediaData};
use rs2_stream::media::types::{MediaType, QualityLevel};
use rs2_stream::rs2::*;
use std::collections::HashMap;
use std::time::Duration;
struct RawVideoFrame {
width: u32,
height: u32,
data: Vec<u8>,
timestamp: Duration,
is_keyframe: bool,
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("Custom Codec Configuration Example");
let custom_config = EncodingConfig {
quality: QualityLevel::High,
target_bitrate: 4_000_000, keyframe_interval: 120, enable_compression: true,
preserve_metadata: true,
};
println!("Created custom codec configuration:");
println!(" Quality: {:?}", custom_config.quality);
println!(" Target bitrate: {} bps", custom_config.target_bitrate);
println!(
" Keyframe interval: {} frames",
custom_config.keyframe_interval
);
println!(
" Compression enabled: {}",
custom_config.enable_compression
);
println!(" Preserve metadata: {}", custom_config.preserve_metadata);
let custom_codec = MediaCodec::new(custom_config);
let standard_codec = CodecFactory::create_h264_codec(QualityLevel::High);
let test_frames = generate_test_frames(10);
println!("Generated {} test frames", test_frames.len());
println!("\nEncoding test frames with both codecs...");
let mut custom_encoded_size = 0;
let mut standard_encoded_size = 0;
for (i, frame) in test_frames.iter().enumerate() {
let raw_data = RawMediaData {
data: frame.data.clone(),
media_type: MediaType::Video,
timestamp: frame.timestamp,
metadata: {
let mut metadata = HashMap::new();
metadata.insert("width".to_string(), frame.width.to_string());
metadata.insert("height".to_string(), frame.height.to_string());
metadata.insert("is_keyframe".to_string(), frame.is_keyframe.to_string());
metadata
},
};
let raw_data_stream = from_iter(vec![raw_data.clone()]);
let mut custom_stream =
custom_codec.encode_stream(raw_data_stream, "test-stream".to_string());
if let Some(custom_result) = custom_stream.next().await {
match custom_result {
Ok(custom_chunk) => {
custom_encoded_size += custom_chunk.data.len();
println!(
"Frame {}: Custom codec: {} bytes",
i,
custom_chunk.data.len()
);
if i == 0 {
match custom_codec.decode_chunk(custom_chunk).await {
Ok(decoded) => {
println!(
"Successfully decoded frame: {} bytes",
decoded.data.len()
);
}
Err(e) => {
println!("Failed to decode: {:?}", e);
}
}
}
}
Err(e) => {
println!("Custom codec encoding error: {:?}", e);
}
}
}
let raw_data_stream = from_iter(vec![raw_data]);
let mut standard_stream =
standard_codec.encode_stream(raw_data_stream, "test-stream".to_string());
if let Some(standard_result) = standard_stream.next().await {
match standard_result {
Ok(standard_chunk) => {
standard_encoded_size += standard_chunk.data.len();
println!(
"Frame {}: Standard codec: {} bytes",
i,
standard_chunk.data.len()
);
}
Err(e) => {
println!("Standard codec encoding error: {:?}", e);
}
}
}
}
println!("\nEncoding Performance Comparison:");
println!(" Custom codec total size: {} bytes", custom_encoded_size);
println!(
" Standard codec total size: {} bytes",
standard_encoded_size
);
let size_diff_percent = if standard_encoded_size > 0 {
((custom_encoded_size as f64 - standard_encoded_size as f64) / standard_encoded_size as f64)
* 100.0
} else {
0.0
};
println!(
" Size difference: {:.1}% ({} is more efficient)",
size_diff_percent.abs(),
if size_diff_percent < 0.0 {
"Custom codec"
} else {
"Standard codec"
}
);
let custom_stats = custom_codec.get_stats().await;
println!("\nCustom Codec Statistics:");
println!(" Frames encoded: {}", custom_stats.frames_encoded);
println!(" Frames decoded: {}", custom_stats.frames_decoded);
println!(" Bytes processed: {}", custom_stats.bytes_processed);
println!(" Encoding time: {} ms", custom_stats.encoding_time_ms);
println!(
" Average compression ratio: {:.2}",
custom_stats.average_compression_ratio
);
println!(" Error count: {}", custom_stats.error_count);
Ok(())
}
fn generate_test_frames(count: usize) -> Vec<RawVideoFrame> {
let mut frames = Vec::with_capacity(count);
for i in 0..count {
let is_keyframe = i % 3 == 0;
let frame = RawVideoFrame {
width: 1920,
height: 1080,
data: vec![0u8; 1920 * 1080 * 3 / 8], timestamp: Duration::from_millis((i as u64) * 16), is_keyframe,
};
frames.push(frame);
}
frames
}