summaryrefslogtreecommitdiffstats
path: root/old/sdl-patches/0004-video-add-YUV-overlay-support.patch
blob: 74c7201d450e64ec9f492f051e7651e49b5c0c2b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
From a7e89f88df1bff23df6314d592d8e375dfae4048 Mon Sep 17 00:00:00 2001
From: Kostya Shishkov <kostya.shishkov@gmail.com>
Date: Wed, 27 Nov 2019 08:22:47 +0100
Subject: [PATCH 4/4] video: add YUV overlay support

---
 src/sdl/video.rs |  118 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 116 insertions(+), 2 deletions(-)

diff --git a/src/sdl/video.rs b/src/sdl/video.rs
index 710a1d6..9acfcb6 100644
--- a/src/sdl/video.rs
+++ b/src/sdl/video.rs
@@ -51,6 +51,26 @@ pub mod ll {
         pub refcount: c_int
     }
 
+    pub const SDL_YV12_OVERLAY: uint32_t = 0x32315659;
+    pub const SDL_IYUV_OVERLAY: uint32_t = 0x56555949;
+    pub const SDL_YUY2_OVERLAY: uint32_t = 0x32595559;
+    pub const SDL_UYVY_OVERLAY: uint32_t = 0x59565955;
+    pub const SDL_YVYU_OVERLAY: uint32_t = 0x55595659;
+
+    #[repr(C)]
+    #[derive(Copy, Clone)]
+    pub struct SDL_Overlay {
+        pub format: uint32_t,
+        pub w: c_int,
+        pub h: c_int,
+        pub planes: c_int,
+        pub pitches: *const uint16_t,
+        pub pixels: *const *mut uint8_t,
+        pub hwfuncs: *mut c_void,
+        pub hwdata: *mut c_void,
+        pub flags: uint32_t,
+    }
+
     #[repr(C)]
     #[derive(Copy, Clone)]
     pub struct SDL_Color {
@@ -109,7 +129,7 @@ pub mod ll {
                                     Gmask: uint32_t,
                                     Bmask: uint32_t,
                                     Amask: uint32_t) -> *mut SDL_Surface;
-        pub fn SDL_CreateRGBSurfaceFrom(pixels: *mut c_void,
+        pub fn SDL_CreateRGBSurfaceFrom(pixels: *const c_void,
                                         width: c_int,
                                         height: c_int,
                                         depth: c_int,
@@ -181,6 +201,14 @@ pub mod ll {
         pub fn SDL_LoadBMP_RW(src: *mut SDL_RWops, freesrc: c_int) -> *mut SDL_Surface;
         pub fn SDL_SaveBMP_RW(surface: *mut SDL_Surface, dst: *mut SDL_RWops, freedst: c_int) -> c_int;
         pub fn SDL_GL_SwapBuffers();
+
+        pub fn SDL_CreateYUVOverlay(width: c_int, height: c_int, format: uint32_t, display: *mut SDL_Surface)
+                        -> *mut SDL_Overlay;
+        pub fn SDL_LockYUVOverlay(overlay: *mut SDL_Overlay) -> c_int;
+        pub fn SDL_UnlockYUVOverlay(overlay: *mut SDL_Overlay);
+        pub fn SDL_DisplayYUVOverlay(overlay: *mut SDL_Overlay,
+                             dstrect: *mut SDL_Rect) -> c_int;
+        pub fn SDL_FreeYUVOverlay(overlay: *mut SDL_Overlay);
     }
 }
 
@@ -351,6 +379,7 @@ pub enum SurfaceFlag {
     SWSurface = 0x00000000,
     HWSurface = 0x00000001,
     AsyncBlit = 0x00000004,
+    HWAccel   = 0x00000100,
     SrcColorKey = 0x00001000,
     SrcAlpha = 0x00010000,
     RLEAccel = 0x00004000
@@ -466,6 +495,15 @@ pub fn get_video_surface() -> Result<Surface, String> {
     else { Ok(wrap_surface(raw, false)) }
 }
 
+#[derive(PartialEq, Eq, Copy, Clone)]
+pub enum OverlayFormat {
+    YV12,
+    IYUV,
+    YUY2,
+    UYVY,
+    YVYU,
+}
+
 // TODO: get_video_modes, get_video_driver_name
 
 impl Surface {
@@ -485,6 +523,38 @@ impl Surface {
         }
     }
 
+    pub fn new_from(pixels: &[u8], pitch: i32, width: isize, height: isize, bpp: isize,
+               rmask: u32, gmask: u32, bmask: u32, amask: u32) -> Result<Surface, String> {
+        unsafe {
+            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,
+                                               rmask, gmask, bmask, amask);
+
+            if raw.is_null() {
+                Err(get_error())
+            } else {
+                Ok(Surface { raw: raw, owned: true })
+            }
+        }
+    }
+
+    pub fn create_overlay(&self, width: isize, height: isize, format: OverlayFormat) -> Result<Overlay, String> {
+        unsafe {
+            let yuv_fmt = match format {
+                    OverlayFormat::YV12 => ll::SDL_YV12_OVERLAY,
+                    OverlayFormat::IYUV => ll::SDL_IYUV_OVERLAY,
+                    OverlayFormat::YUY2 => ll::SDL_YUY2_OVERLAY,
+                    OverlayFormat::UYVY => ll::SDL_UYVY_OVERLAY,
+                    OverlayFormat::YVYU => ll::SDL_YVYU_OVERLAY,
+                };
+            let raw = ll::SDL_CreateYUVOverlay(width as c_int, height as c_int, yuv_fmt, self.raw);
+            if raw.is_null() {
+                Err(get_error())
+            } else {
+                Ok(Overlay { raw: raw })
+            }
+        }
+    }
+
     pub fn from_bmp(path: &Path) -> Result<Surface, String> {
         let cpath = CString::new(path.to_str().unwrap()).unwrap();
         let mode = CString::new("rb".as_bytes()).unwrap();
@@ -742,4 +812,48 @@ pub fn swap_buffers() {
 }
 
 
-// TODO: YUV
+#[derive(PartialEq)]
+pub struct Overlay {
+    pub raw: *mut ll::SDL_Overlay,
+}
+
+impl Drop for Overlay {
+    fn drop(&mut self) {
+        unsafe {
+            ll::SDL_FreeYUVOverlay(self.raw);
+        }
+    }
+}
+
+impl Overlay {
+    pub fn display(&self, dest_rect: Option<Rect>) -> bool {
+        unsafe {
+            ll::SDL_DisplayYUVOverlay(self.raw, match dest_rect {
+                Some(ref rect) => mem::transmute(rect),
+                None => ptr::null_mut()
+            }) == 0
+        }
+    }
+
+    pub fn lock(&self) -> bool {
+        unsafe { ll::SDL_LockYUVOverlay(self.raw) == 0 }
+    }
+
+    pub fn unlock(&self) {
+        unsafe { ll::SDL_UnlockYUVOverlay(self.raw) }
+    }
+
+    pub unsafe fn get_pixel_ptr(&self, comp: usize) -> &mut [u8] {
+        let pitch = self.get_pitch(comp);
+        let len = if comp == 0 { pitch as usize * ((*self.raw).h as usize) } else
+                    { pitch as usize * (((*self.raw).h / 2) as usize) };
+        let ptr = *((*self.raw).pixels.add(comp));
+        let pixels: &mut [u8] = mem::transmute((ptr, len));
+
+        pixels
+    }
+
+    pub fn get_pitch(&self, comp: usize) -> usize {
+        unsafe { *((*self.raw).pitches.add(comp)) as usize }
+    }
+}
-- 
1.7.9.5