move experimental code to old/
[nihav-player.git] / old / sdl-patches / 0004-video-add-YUV-overlay-support.patch
diff --git a/old/sdl-patches/0004-video-add-YUV-overlay-support.patch b/old/sdl-patches/0004-video-add-YUV-overlay-support.patch
new file mode 100644 (file)
index 0000000..74c7201
--- /dev/null
@@ -0,0 +1,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
+