gstreamer 0.6.2

Idiomatic bindings for GStreamer
Documentation
use buffer::Buffer;
use ffi::*;
use std::mem;
use std::slice::from_raw_parts;

pub struct VideoFrame{
    vf: GstVideoFrame,
    buffer: Buffer
}

pub struct VideoPlane<'a>{
	vf: &'a GstVideoFrame,
	p: usize
}

pub struct VideoComponent<'a>{
	vf: &'a GstVideoFrame,
	c: usize
}

macro_rules! GST_VIDEO_FRAME_COMP_WIDTH(
	($video_frame:expr,$c:expr) => ( -((-$video_frame.info.width) >> ((*$video_frame.info.finfo).w_sub[$c]) as usize) ) ;
);

macro_rules! GST_VIDEO_FRAME_COMP_HEIGHT(
	($video_frame:expr,$c:expr) => ( -((-$video_frame.info.height) >> ((*$video_frame.info.finfo).h_sub[$c]) as usize) );
);

macro_rules! GST_VIDEO_FRAME_COMP_OFFSET(
	($video_frame:expr,$c:expr) => ((($video_frame.info.offset)[(*$video_frame.info.finfo).plane[($c)] as usize]) + (*$video_frame.info.finfo).poffset[($c)] as u64)
);

macro_rules! GST_VIDEO_FRAME_COMP_STRIDE(
	($video_frame:expr,$c:expr) => (($video_frame.info.stride)[(*$video_frame.info.finfo).plane[($c)] as usize])
);

macro_rules! GST_VIDEO_FRAME_COMP_DATA(
	($video_frame:expr,$c:expr) => {
	    ($video_frame.data[(*$video_frame.info.finfo).plane[$c] as usize] as *mut u8).offset((*$video_frame.info.finfo).poffset[$c] as isize)
	}
);


impl<'a> VideoPlane<'a>{
    pub fn stride(&self) -> i32{
        self.info().stride[self.p]
    }

    pub fn offset(&self) -> u64{
        self.info().offset[self.p]
    }

    pub fn width(&self) -> i32{
        unsafe{ GST_VIDEO_FRAME_COMP_WIDTH!(self.vf,self.p) }
    }

    pub fn height(&self) -> i32{
        unsafe{ GST_VIDEO_FRAME_COMP_HEIGHT!(self.vf,self.p) }
    }

    pub fn size(&self) -> usize{
        (self.stride()*self.height()) as usize
    }

    pub fn len<T>(&self) -> usize{
        self.size()/mem::size_of::<T>()
    }

    pub fn depth(&self) -> u32{
        self.format_info().depth[self.p]
    }

    pub fn data<T:'a>(&self) -> &'a[T]{
        unsafe{
	        from_raw_parts( mem::transmute(self.vf.data[self.p]), self.len::<T>())
	    }
    }

    fn info(&self) -> &::VideoInfo{
        &self.vf.info
    }

    fn format_info(&self) -> &GstVideoFormatInfo{
        unsafe{ &(*self.vf.info.finfo) }
    }
}

impl<'a> VideoComponent<'a>{
    pub fn stride(&self) -> i32{
        unsafe{  GST_VIDEO_FRAME_COMP_STRIDE!(self.vf,self.c) }
    }

    pub fn offset(&self) -> u64{
        unsafe{ GST_VIDEO_FRAME_COMP_OFFSET!(self.vf,self.c) }
    }

    pub fn width(&self) -> i32{
        unsafe{ GST_VIDEO_FRAME_COMP_WIDTH!(self.vf,self.c) }
    }

    pub fn height(&self) -> i32{
        unsafe{ GST_VIDEO_FRAME_COMP_HEIGHT!(self.vf,self.c) }
    }

    pub fn size(&self) -> usize{
        (self.stride()*self.height()) as usize
    }

    pub fn len<T>(&self) -> usize{
        self.size()/mem::size_of::<T>()
    }

    pub fn depth(&self) -> u32{
        self.format_info().depth[self.c]
    }

    pub fn data<T:'a>(&self) -> &'a[T]{
        unsafe{
            let data = GST_VIDEO_FRAME_COMP_DATA!(self.vf,self.c);
	        from_raw_parts( mem::transmute(data), self.len::<T>())
	    }
    }

    fn format_info(&self) -> &GstVideoFormatInfo{
        unsafe{ &(*self.vf.info.finfo) }
    }
}

impl Drop for VideoFrame{
    fn drop(&mut self){
        unsafe{ gst_video_frame_unmap(&mut self.vf) };
    }
}

impl VideoFrame{
    pub unsafe fn new(mut vi: GstVideoInfo, mut buffer: Buffer) -> Option<VideoFrame>{
        let mut gstframe = mem::zeroed();
        if gst_video_frame_map(&mut gstframe, &mut vi, buffer.gst_buffer_mut(), GST_MAP_READ) != 0{
            Some(VideoFrame{ vf: gstframe, buffer: buffer })
        }else{
        	None
        }
    }

    #[inline]
    pub fn info(&self) -> &::VideoInfo{
        &self.vf.info
    }

    #[inline]
    pub fn flags(&self) -> &GstVideoFlags{
        &self.vf.flags
    }

    #[inline]
    pub fn buffer(&self) -> &Buffer{
        &self.buffer
    }

    #[inline]
    pub fn format_info(&self) -> &GstVideoFormatInfo{
        unsafe{ &(*self.vf.info.finfo) }
    }

    #[inline]
    pub fn format(&self) -> &GstVideoFormat{
        &self.format_info().format
    }

    #[inline]
    pub fn width(&self) -> i32{
        self.info().width
    }

    #[inline]
    pub fn height(&self) -> i32{
        self.info().height
    }

    #[inline]
    pub fn size(&self) -> u64{
        self.info().size
    }

	#[inline]
	pub fn len<T>(&self) -> usize{
		(self.size() / mem::size_of::<T>() as u64)  as usize
	}

    #[inline]
    pub fn is_interlaced(&self) -> bool{
        self.flags() & GST_VIDEO_FRAME_FLAG_INTERLACED == GST_VIDEO_FRAME_FLAG_INTERLACED
    }

    #[inline]
    pub fn is_tff(&self) -> bool{
        self.flags() & GST_VIDEO_FRAME_FLAG_TFF == GST_VIDEO_FRAME_FLAG_TFF
    }

    #[inline]
    pub fn is_rff(&self) -> bool{
        self.flags() & GST_VIDEO_FRAME_FLAG_RFF == GST_VIDEO_FRAME_FLAG_RFF
    }

    #[inline]
    pub fn is_onefield(&self) -> bool{
        self.flags() & GST_VIDEO_FRAME_FLAG_ONEFIELD == GST_VIDEO_FRAME_FLAG_ONEFIELD
    }

    #[inline]
    pub fn n_planes(&self) -> u32{
        self.format_info().n_planes
    }

    #[inline]
    pub fn plane<'a>(&'a self, p: u32) -> Option<VideoPlane<'a>>{
        if p < self.n_planes(){
	        Some(VideoPlane{
	            vf: &self.vf,
	            p: p as usize
	    	})
	    }else{
	        None
	    }
    }

	#[inline]
	pub fn n_components(&self) -> u32{
	    self.format_info().n_components
	}

    #[inline]
    pub fn component<'a>(&'a self, c: u32) -> Option<VideoComponent<'a>>{
        if c < self.n_components(){
	        Some(VideoComponent{
	            vf: &self.vf,
	            c: c as usize
	    	})
	    }else{
	        None
	    }
    }
}