rsmpeg
rsmpeg copied to clipboard
Can the AVformatContextInput::from_io_context interface add an optional AVdictionary parameter?
pub fn open_memory_file(data: Arc<Vec<u8>>) -> Result<AVFormatContextInput> {
let mut current = 0;
let io_context = AVIOContextCustom::alloc_context(
AVMem::new(1048576),
false,
vec![],
Some(Box::new(move |_, buf| {
let right = data.len().min(current + buf.len());
if right <= current {
return ffi::AVERROR_EOF;
}
let read_len = right - current;
buf[0..read_len].copy_from_slice(&data[current..right]);
current = right;
read_len as i32
})),
None,
None,
);
let input_format_context = match AVFormatContextInput::from_io_context(
rsmpeg::avformat::AVIOContextContainer::Custom(io_context),
) {
Ok(x) => x,
Err(e) => {
bail!("open file default:{}", e);
}
};
Ok(input_format_context)
}
The above code will have the following output for some files
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7ffff0000f40] stream 0, offset 0x30: partial file
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7ffff0000f40] Could not find codec parameters for stream 0 (Video: h264 (avc1 / 0x31637661), none(tv, bt709), 720x1280, 11185 kb/s): unspecified pixel format
Consider increasing the value for the 'analyzeduration' (0) and 'probesize' (5000000) options
But if I use AVformatContextInput::open() to open a file that exists on disk it works fine.
Hi, just wondering if there's been any progress on this, since I've got a similar use case?
Just a sharing ! Thank you! Please test as follows;
#[test]
fn test1() -> Result<()> {
unsafe {
ffi::avdevice_register_all();
// ffi::av_log_set_level(ffi::AV_LOG_TRACE as i32);
}
let name = cstr!("lavfi");
let filter_ref = AVInputFormat::find(name).unwrap();
println!("long_name: {:?}", unsafe {
CStr::from_ptr(filter_ref.long_name)
});
assert_eq!(
unsafe { CStr::from_ptr(filter_ref.long_name) },
cstr!("Libavfilter virtual input device")
);
let mut dict: Option<_> =
Some(AVDictionary::new(cstr!("probesize"), cstr!("1000000"), 0).into());
let mut lavfi_ic = AVFormatContextInput::open(
cstr!("color=c=black:s=640x480:r=1:duration=10"),
Some(&filter_ref),
&mut dict,
)?;
let (stream_index, dec) = lavfi_ic.find_best_stream(ffi::AVMEDIA_TYPE_VIDEO)?.unwrap();
println!("lavfi_ic:{:#?}", lavfi_ic.clone());
println!("stream_index:{}", stream_index);
println!("dec:{:?}", dec.name());
println!("duration:{}", lavfi_ic.duration);
println!("bit_rate:{}", lavfi_ic.bit_rate);
println!("nb_streams:{}", lavfi_ic.nb_streams);
println!("fps_probe_size:{}", lavfi_ic.fps_probe_size);
let mut v_dec_ctx = AVCodecContext::new(&dec);
v_dec_ctx.apply_codecpar(&lavfi_ic.streams()[stream_index as usize].codecpar())?;
v_dec_ctx.open(None)?;
while let Ok(Some(packet)) = lavfi_ic.read_packet() {
if packet.stream_index == stream_index as i32 {
v_dec_ctx.send_packet(Some(&packet))?;
while let Ok(virtual_frame) = v_dec_ctx.receive_frame() {
println!("frame {:?}", virtual_frame);
}
}
}
Ok(())
}
-WENPIN