]>
Commit | Line | Data |
---|---|---|
1 | From a7e89f88df1bff23df6314d592d8e375dfae4048 Mon Sep 17 00:00:00 2001 | |
2 | From: Kostya Shishkov <kostya.shishkov@gmail.com> | |
3 | Date: Wed, 27 Nov 2019 08:22:47 +0100 | |
4 | Subject: [PATCH 4/4] video: add YUV overlay support | |
5 | ||
6 | --- | |
7 | src/sdl/video.rs | 118 +++++++++++++++++++++++++++++++++++++++++++++++++++++- | |
8 | 1 file changed, 116 insertions(+), 2 deletions(-) | |
9 | ||
10 | diff --git a/src/sdl/video.rs b/src/sdl/video.rs | |
11 | index 710a1d6..9acfcb6 100644 | |
12 | --- a/src/sdl/video.rs | |
13 | +++ b/src/sdl/video.rs | |
14 | @@ -51,6 +51,26 @@ pub mod ll { | |
15 | pub refcount: c_int | |
16 | } | |
17 | ||
18 | + pub const SDL_YV12_OVERLAY: uint32_t = 0x32315659; | |
19 | + pub const SDL_IYUV_OVERLAY: uint32_t = 0x56555949; | |
20 | + pub const SDL_YUY2_OVERLAY: uint32_t = 0x32595559; | |
21 | + pub const SDL_UYVY_OVERLAY: uint32_t = 0x59565955; | |
22 | + pub const SDL_YVYU_OVERLAY: uint32_t = 0x55595659; | |
23 | + | |
24 | + #[repr(C)] | |
25 | + #[derive(Copy, Clone)] | |
26 | + pub struct SDL_Overlay { | |
27 | + pub format: uint32_t, | |
28 | + pub w: c_int, | |
29 | + pub h: c_int, | |
30 | + pub planes: c_int, | |
31 | + pub pitches: *const uint16_t, | |
32 | + pub pixels: *const *mut uint8_t, | |
33 | + pub hwfuncs: *mut c_void, | |
34 | + pub hwdata: *mut c_void, | |
35 | + pub flags: uint32_t, | |
36 | + } | |
37 | + | |
38 | #[repr(C)] | |
39 | #[derive(Copy, Clone)] | |
40 | pub struct SDL_Color { | |
41 | @@ -109,7 +129,7 @@ pub mod ll { | |
42 | Gmask: uint32_t, | |
43 | Bmask: uint32_t, | |
44 | Amask: uint32_t) -> *mut SDL_Surface; | |
45 | - pub fn SDL_CreateRGBSurfaceFrom(pixels: *mut c_void, | |
46 | + pub fn SDL_CreateRGBSurfaceFrom(pixels: *const c_void, | |
47 | width: c_int, | |
48 | height: c_int, | |
49 | depth: c_int, | |
50 | @@ -181,6 +201,14 @@ pub mod ll { | |
51 | pub fn SDL_LoadBMP_RW(src: *mut SDL_RWops, freesrc: c_int) -> *mut SDL_Surface; | |
52 | pub fn SDL_SaveBMP_RW(surface: *mut SDL_Surface, dst: *mut SDL_RWops, freedst: c_int) -> c_int; | |
53 | pub fn SDL_GL_SwapBuffers(); | |
54 | + | |
55 | + pub fn SDL_CreateYUVOverlay(width: c_int, height: c_int, format: uint32_t, display: *mut SDL_Surface) | |
56 | + -> *mut SDL_Overlay; | |
57 | + pub fn SDL_LockYUVOverlay(overlay: *mut SDL_Overlay) -> c_int; | |
58 | + pub fn SDL_UnlockYUVOverlay(overlay: *mut SDL_Overlay); | |
59 | + pub fn SDL_DisplayYUVOverlay(overlay: *mut SDL_Overlay, | |
60 | + dstrect: *mut SDL_Rect) -> c_int; | |
61 | + pub fn SDL_FreeYUVOverlay(overlay: *mut SDL_Overlay); | |
62 | } | |
63 | } | |
64 | ||
65 | @@ -351,6 +379,7 @@ pub enum SurfaceFlag { | |
66 | SWSurface = 0x00000000, | |
67 | HWSurface = 0x00000001, | |
68 | AsyncBlit = 0x00000004, | |
69 | + HWAccel = 0x00000100, | |
70 | SrcColorKey = 0x00001000, | |
71 | SrcAlpha = 0x00010000, | |
72 | RLEAccel = 0x00004000 | |
73 | @@ -466,6 +495,15 @@ pub fn get_video_surface() -> Result<Surface, String> { | |
74 | else { Ok(wrap_surface(raw, false)) } | |
75 | } | |
76 | ||
77 | +#[derive(PartialEq, Eq, Copy, Clone)] | |
78 | +pub enum OverlayFormat { | |
79 | + YV12, | |
80 | + IYUV, | |
81 | + YUY2, | |
82 | + UYVY, | |
83 | + YVYU, | |
84 | +} | |
85 | + | |
86 | // TODO: get_video_modes, get_video_driver_name | |
87 | ||
88 | impl Surface { | |
89 | @@ -485,6 +523,38 @@ impl Surface { | |
90 | } | |
91 | } | |
92 | ||
93 | + pub fn new_from(pixels: &[u8], pitch: i32, width: isize, height: isize, bpp: isize, | |
94 | + rmask: u32, gmask: u32, bmask: u32, amask: u32) -> Result<Surface, String> { | |
95 | + unsafe { | |
96 | + let raw = ll::SDL_CreateRGBSurfaceFrom(pixels.as_ptr() as *const libc::c_void, width as c_int, height as c_int, bpp as c_int, pitch as c_int, | |
97 | + rmask, gmask, bmask, amask); | |
98 | + | |
99 | + if raw.is_null() { | |
100 | + Err(get_error()) | |
101 | + } else { | |
102 | + Ok(Surface { raw: raw, owned: true }) | |
103 | + } | |
104 | + } | |
105 | + } | |
106 | + | |
107 | + pub fn create_overlay(&self, width: isize, height: isize, format: OverlayFormat) -> Result<Overlay, String> { | |
108 | + unsafe { | |
109 | + let yuv_fmt = match format { | |
110 | + OverlayFormat::YV12 => ll::SDL_YV12_OVERLAY, | |
111 | + OverlayFormat::IYUV => ll::SDL_IYUV_OVERLAY, | |
112 | + OverlayFormat::YUY2 => ll::SDL_YUY2_OVERLAY, | |
113 | + OverlayFormat::UYVY => ll::SDL_UYVY_OVERLAY, | |
114 | + OverlayFormat::YVYU => ll::SDL_YVYU_OVERLAY, | |
115 | + }; | |
116 | + let raw = ll::SDL_CreateYUVOverlay(width as c_int, height as c_int, yuv_fmt, self.raw); | |
117 | + if raw.is_null() { | |
118 | + Err(get_error()) | |
119 | + } else { | |
120 | + Ok(Overlay { raw: raw }) | |
121 | + } | |
122 | + } | |
123 | + } | |
124 | + | |
125 | pub fn from_bmp(path: &Path) -> Result<Surface, String> { | |
126 | let cpath = CString::new(path.to_str().unwrap()).unwrap(); | |
127 | let mode = CString::new("rb".as_bytes()).unwrap(); | |
128 | @@ -742,4 +812,48 @@ pub fn swap_buffers() { | |
129 | } | |
130 | ||
131 | ||
132 | -// TODO: YUV | |
133 | +#[derive(PartialEq)] | |
134 | +pub struct Overlay { | |
135 | + pub raw: *mut ll::SDL_Overlay, | |
136 | +} | |
137 | + | |
138 | +impl Drop for Overlay { | |
139 | + fn drop(&mut self) { | |
140 | + unsafe { | |
141 | + ll::SDL_FreeYUVOverlay(self.raw); | |
142 | + } | |
143 | + } | |
144 | +} | |
145 | + | |
146 | +impl Overlay { | |
147 | + pub fn display(&self, dest_rect: Option<Rect>) -> bool { | |
148 | + unsafe { | |
149 | + ll::SDL_DisplayYUVOverlay(self.raw, match dest_rect { | |
150 | + Some(ref rect) => mem::transmute(rect), | |
151 | + None => ptr::null_mut() | |
152 | + }) == 0 | |
153 | + } | |
154 | + } | |
155 | + | |
156 | + pub fn lock(&self) -> bool { | |
157 | + unsafe { ll::SDL_LockYUVOverlay(self.raw) == 0 } | |
158 | + } | |
159 | + | |
160 | + pub fn unlock(&self) { | |
161 | + unsafe { ll::SDL_UnlockYUVOverlay(self.raw) } | |
162 | + } | |
163 | + | |
164 | + pub unsafe fn get_pixel_ptr(&self, comp: usize) -> &mut [u8] { | |
165 | + let pitch = self.get_pitch(comp); | |
166 | + let len = if comp == 0 { pitch as usize * ((*self.raw).h as usize) } else | |
167 | + { pitch as usize * (((*self.raw).h / 2) as usize) }; | |
168 | + let ptr = *((*self.raw).pixels.add(comp)); | |
169 | + let pixels: &mut [u8] = mem::transmute((ptr, len)); | |
170 | + | |
171 | + pixels | |
172 | + } | |
173 | + | |
174 | + pub fn get_pitch(&self, comp: usize) -> usize { | |
175 | + unsafe { *((*self.raw).pitches.add(comp)) as usize } | |
176 | + } | |
177 | +} | |
178 | -- | |
179 | 1.7.9.5 | |
180 |