ffmpeg_rs/codec/
picture.rs

1use std::marker::PhantomData;
2use std::mem;
3use std::slice;
4
5use ffi::*;
6use format;
7use libc::{c_int, size_t};
8use Error;
9
10pub struct Picture<'a> {
11    ptr: *mut AVPicture,
12
13    format: format::Pixel,
14    width: u32,
15    height: u32,
16
17    _own: bool,
18    _marker: PhantomData<&'a ()>,
19}
20
21impl<'a> Picture<'a> {
22    pub unsafe fn wrap(
23        ptr: *mut AVPicture,
24        format: format::Pixel,
25        width: u32,
26        height: u32,
27    ) -> Self {
28        Picture {
29            ptr,
30
31            format,
32            width,
33            height,
34
35            _own: false,
36            _marker: PhantomData,
37        }
38    }
39
40    pub unsafe fn as_ptr(&self) -> *const AVPicture {
41        self.ptr as *const _
42    }
43
44    pub unsafe fn as_mut_ptr(&mut self) -> *mut AVPicture {
45        self.ptr
46    }
47}
48
49impl<'a> Picture<'a> {
50    pub fn size(format: format::Pixel, width: u32, height: u32) -> Result<usize, Error> {
51        unsafe {
52            match avpicture_get_size(format.into(), width as c_int, height as c_int) {
53                v if v >= 0 => Ok(v as usize),
54                e => Err(Error::from(e)),
55            }
56        }
57    }
58
59    pub fn new(format: format::Pixel, width: u32, height: u32) -> Result<Self, Error> {
60        unsafe {
61            let ptr = av_malloc(mem::size_of::<AVPicture>() as size_t) as *mut AVPicture;
62
63            match avpicture_alloc(ptr, format.into(), width as c_int, height as c_int) {
64                0 => Ok(Picture {
65                    ptr,
66
67                    format,
68                    width,
69                    height,
70
71                    _own: true,
72                    _marker: PhantomData,
73                }),
74
75                e => Err(Error::from(e)),
76            }
77        }
78    }
79
80    pub fn format(&self) -> format::Pixel {
81        self.format
82    }
83
84    pub fn width(&self) -> u32 {
85        self.width
86    }
87
88    pub fn height(&self) -> u32 {
89        self.height
90    }
91
92    pub fn layout(&self, out: &mut [u8]) -> Result<usize, Error> {
93        unsafe {
94            match avpicture_layout(
95                self.ptr,
96                self.format.into(),
97                self.width as c_int,
98                self.height as c_int,
99                out.as_mut_ptr(),
100                out.len() as c_int,
101            ) {
102                s if s >= 0 => Ok(s as usize),
103                e => Err(Error::from(e)),
104            }
105        }
106    }
107
108    pub fn layout_as(
109        &self,
110        format: format::Pixel,
111        width: u32,
112        height: u32,
113        out: &mut [u8],
114    ) -> Result<usize, Error> {
115        unsafe {
116            match avpicture_layout(
117                self.as_ptr(),
118                format.into(),
119                width as c_int,
120                height as c_int,
121                out.as_mut_ptr(),
122                out.len() as c_int,
123            ) {
124                s if s >= 0 => Ok(s as usize),
125                e => Err(Error::from(e)),
126            }
127        }
128    }
129
130    pub fn crop(&self, source: &mut Picture, top: u32, left: u32) -> Result<(), Error> {
131        if self.format != source.format {
132            return Err(Error::Bug);
133        }
134
135        unsafe {
136            match av_picture_crop(
137                source.as_mut_ptr(),
138                self.as_ptr(),
139                self.format.into(),
140                top as c_int,
141                left as c_int,
142            ) {
143                0 => Ok(()),
144                e => Err(Error::from(e)),
145            }
146        }
147    }
148
149    pub fn data(&self) -> Vec<&[u8]> {
150        let mut result = Vec::new();
151
152        unsafe {
153            for (i, length) in (*self.as_ptr())
154                .linesize
155                .iter()
156                .take_while(|l| **l > 0)
157                .enumerate()
158            {
159                result.push(slice::from_raw_parts(
160                    (*self.as_ptr()).data[i],
161                    (*length as usize) * (self.height as usize),
162                ))
163            }
164        }
165
166        result
167    }
168
169    pub fn data_mut(&mut self) -> Vec<&mut [u8]> {
170        let mut result = Vec::new();
171
172        unsafe {
173            for (i, length) in (*self.as_ptr())
174                .linesize
175                .iter()
176                .take_while(|l| **l > 0)
177                .enumerate()
178            {
179                result.push(slice::from_raw_parts_mut(
180                    (*self.as_ptr()).data[i],
181                    (*length as usize) * (self.height as usize),
182                ))
183            }
184        }
185
186        result
187    }
188}
189
190impl<'a> Clone for Picture<'a> {
191    fn clone(&self) -> Self {
192        let mut pic = Picture::new(self.format, self.width, self.height).unwrap();
193        pic.clone_from(self);
194
195        pic
196    }
197
198    fn clone_from(&mut self, source: &Self) {
199        unsafe {
200            av_picture_copy(
201                self.as_mut_ptr(),
202                source.as_ptr(),
203                source.format.into(),
204                source.width as c_int,
205                source.height as c_int,
206            );
207        }
208    }
209}
210
211impl<'a> Drop for Picture<'a> {
212    fn drop(&mut self) {
213        if self._own {
214            unsafe {
215                av_free(self.as_mut_ptr() as *mut _);
216            }
217        }
218    }
219}