Hi!
I’ve been working with GStreamer to integrate it into my app, but I haven’t been able to resolve the issue with the (exit code: 0xc0000005, STATUS_ACCESS_VIOLATION)
error when trying to push buffers to GStreamer and then save them as a video file.
My code is in Rust, but it’s quite small, so I think you’ll be able to understand it. I’ve included a link to similar code in C for reference: StackOverflow
Here’s my code:
use gstreamer as gst;
use gstreamer::prelude::*;
use gstreamer::{Buffer, BufferRef, Caps, FlowReturn, Format};
use std::error::Error;
fn main() -> Result<(), Box<dyn Error>> {
// Initialize GStreamer
gst::init()?;
// Create GStreamer elements
let pipeline = gst::Pipeline::new();
let appsrc = gst::ElementFactory::make_with_name("appsrc", Some("mysource"))
.expect("Couldn't create appsrc element.");
let videoconvert = gst::ElementFactory::make_with_name("videoconvert", Some("myconvert"))
.expect("Couldn't create videoconvert element.");
let x264enc = gst::ElementFactory::make_with_name("x264enc", Some("myencoder"))
.expect("Couldn't create x264enc element.");
let mp4mux = gst::ElementFactory::make_with_name("mp4mux", Some("mymux"))
.expect("Couldn't create mp4mux element.");
let filesink = gst::ElementFactory::make_with_name("filesink", Some("myfileoutput"))
.expect("Couldn't create filesink element.");
// Set the properties for filesink
filesink.set_property_from_str("location", &"output.mp4");
// Add elements to the pipeline
pipeline.add_many(&[&appsrc, &videoconvert, &x264enc, &mp4mux, &filesink])?;
// Link the elements
appsrc.link(&videoconvert)?;
videoconvert.link(&x264enc)?;
x264enc.link(&mp4mux)?;
mp4mux.link(&filesink)?;
// Set the caps for appsrc
let caps = Caps::builder("video/x-raw")
.field("format", &"BGR")
.field("width", &800)
.field("height", &600)
.field("framerate", &gstreamer::Fraction::new(30, 1))
.build();
appsrc.set_property("caps", &caps);
appsrc.set_property("format", &Format::Time);
// Set the pipeline to the playing state
pipeline.set_state(gstreamer::State::Playing)?;
// Push buffers into the appsrc
for i in 0..10 {
let mut buffer = Buffer::with_size(800 * 600 * 3).expect("Failed to allocate buffer");
{
let mut map = buffer.get_mut().unwrap().map_writable().expect("Failed to map buffer writable");
assert_eq!(map.size(), 800 * 600 * 3);
for byte in map.as_mut_slice().iter_mut() {
*byte = (i % 255) as u8; // Filling with dummy data
}
}
{
let buffer_ref: &mut BufferRef = buffer.get_mut().unwrap();
buffer_ref.set_pts(gstreamer::ClockTime::from_mseconds(30 * i));
buffer_ref.set_dts(Some(gstreamer::ClockTime::from_mseconds(30 * i)));
buffer_ref.set_duration(gstreamer::ClockTime::from_mseconds(33));
}
// appsrc.dynamic_cast::<gst::Element>().unwrap();
let _ = appsrc.emit_by_name::<FlowReturn>("push-buffer", &[&buffer]);
}
// Signal the end of stream
// let appsrc = appsrc.dynamic_cast::<gst::Element>().unwrap();
let _ = appsrc.emit_by_name::<FlowReturn>("end-of-stream", &[&""]);
// Wait for EOS or error
let bus = pipeline.bus().unwrap();
for msg in bus.iter_timed(gst::ClockTime::NONE) {
use gstreamer::MessageView;
match msg.view() {
MessageView::Eos(..) => break,
MessageView::Error(err) => {
eprintln!(
"Error received from element {:?}: {}",
err.src().map(|s| s.path_string()),
err.error()
);
break;
}
_ => (),
}
}
// Cleanup
pipeline.set_state(gstreamer::State::Null)?;
Ok(())
}
Logs looks like:
cargo run --bin frames
Compiling GStreamer v0.1.0 (C:\Langs\Rust\GStreamer)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 1.26s
Running `target\debug\frames.exe`
error: process didn't exit successfully: `target\debug\frames.exe` (exit code: 0xc0000005, STATUS_ACCESS_VIOLATION)
I’m not sure if the issue lies in the Rust bindings or elsewhere. Any ideas on how to resolve this?
Thank you!