Add API to create a Buffer from a Vec<u8> with memory reuse and use it for the Speex headers

This commit is contained in:
Sebastian Dröge 2017-01-14 18:04:55 +01:00
parent 745a6a3c17
commit 3e17102166
2 changed files with 60 additions and 11 deletions

View file

@ -194,10 +194,8 @@ impl AudioFormat {
})
}
flavors::SoundFormat::SPEEX => {
let mut header = Buffer::new_with_size(80).unwrap();
{
let mut map = header.map_readwrite().unwrap();
let mut data = Cursor::new(map.as_mut_slice());
let header = {
let mut data = Cursor::new(Vec::with_capacity(80));
data.write(b"Speex 1.1.12").unwrap();
data.write(&[0; 14]).unwrap();
data.write_u32le(1).unwrap(); // version
@ -213,19 +211,28 @@ impl AudioFormat {
data.write_u32le(0).unwrap(); // extra headers
data.write_u32le(0).unwrap(); // reserved 1
data.write_u32le(0).unwrap(); // reserved 2
}
assert_eq!(data.position(), 80);
data.into_inner()
};
let header = Buffer::new_from_vec(header).unwrap();
let comment_size = 4 + 7 /* nothing */ + 4 + 1;
let mut comment = Buffer::new_with_size(comment_size).unwrap();
{
let mut map = comment.map_readwrite().unwrap();
let mut data = Cursor::new(map.as_mut_slice());
let comment = {
let mut data = Cursor::new(Vec::with_capacity(comment_size));
data.write_u32le(7).unwrap(); // length of "nothing"
data.write(b"nothing").unwrap(); // "vendor" string
data.write_u32le(0).unwrap(); // number of elements
data.write_u8(1);
}
data.write_u8(1).unwrap();
assert_eq!(data.position() as usize, comment_size);
data.into_inner()
};
let comment = Buffer::new_from_vec(comment).unwrap();
Some(Caps::new_simple("audio/x-speex",
&[("streamheader",
&vec![header.into(), comment.into()].into())]))

View file

@ -151,6 +151,48 @@ impl Buffer {
}
}
extern "C" fn vec_drop(vec: *mut c_void) {
let vec: Box<Vec<u8>> = unsafe { Box::from_raw(vec as *mut Vec<u8>) };
drop(vec);
}
pub fn new_from_vec(vec: Vec<u8>) -> Option<Buffer> {
extern "C" {
fn gst_buffer_new_wrapped_full(flags: u32,
data: *mut u8,
maxsize: usize,
offset: usize,
size: usize,
user_data: *mut c_void,
destroy_notify: extern "C" fn(*mut c_void))
-> *mut c_void;
}
let raw = unsafe {
let mut vec = Box::new(vec);
let maxsize = vec.capacity();
let size = vec.len();
let data = vec.as_mut_ptr();
let user_data = Box::into_raw(vec);
gst_buffer_new_wrapped_full(0,
data,
maxsize,
0,
size,
user_data as *mut c_void,
Buffer::vec_drop)
};
if raw.is_null() {
None
} else {
Some(Buffer {
raw: raw,
owned: true,
})
}
}
pub fn map_read(&self) -> Option<ReadBufferMap> {
extern "C" {
fn gst_buffer_map(buffer: *mut c_void,