Add SDL Video Capture, with back-end for linux/macos/ios/android

This commit is contained in:
Sylvain
2023-11-09 11:11:07 +01:00
committed by Sam Lantinga
parent 3ab98a3572
commit 59f93e20a7
23 changed files with 4768 additions and 0 deletions
+9
View File
@@ -343,6 +343,7 @@ set_option(SDL_METAL "Enable Metal support" ${APPLE})
set_option(SDL_KMSDRM "Use KMS DRM video driver" ${UNIX_SYS})
dep_option(SDL_KMSDRM_SHARED "Dynamically load KMS DRM support" ON "SDL_KMSDRM" OFF)
set_option(SDL_OFFSCREEN "Use offscreen video driver" ON)
dep_option(SDL_VIDEO_CAPTURE "Enable video capturing" ON SDL_VIDEO OFF)
option_string(SDL_BACKGROUNDING_SIGNAL "number to use for magic backgrounding signal or 'OFF'" OFF)
option_string(SDL_FOREGROUNDING_SIGNAL "number to use for magic foregrounding signal or 'OFF'" OFF)
dep_option(SDL_HIDAPI "Enable the HIDAPI subsystem" ON "NOT VISIONOS" OFF)
@@ -2047,6 +2048,10 @@ elseif(APPLE)
set(HAVE_SDL_FILE TRUE)
endif()
if(IOS OR TVOS OR MACOSX OR DARWIN)
sdl_sources("${SDL3_SOURCE_DIR}/src/video/SDL_video_capture_apple.m")
endif()
if(SDL_MISC)
if(IOS OR TVOS OR VISIONOS)
sdl_glob_sources("${SDL3_SOURCE_DIR}/src/misc/ios/*.m")
@@ -2230,6 +2235,10 @@ elseif(APPLE)
# Actually load the frameworks at the end so we don't duplicate include.
if(SDL_FRAMEWORK_COREVIDEO)
find_library(COREMEDIA CoreMedia)
if(COREMEDIA)
sdl_link_dependency(corevideo LINK_OPTIONS "-Wl,-framework,CoreMedia")
endif()
sdl_link_dependency(corevideo LINK_OPTIONS "-Wl,-framework,CoreVideo")
endif()
if(SDL_FRAMEWORK_COCOA)
+3
View File
@@ -89,6 +89,7 @@
<ClInclude Include="..\include\SDL3\SDL_types.h" />
<ClInclude Include="..\include\SDL3\SDL_version.h" />
<ClInclude Include="..\include\SDL3\SDL_video.h" />
<ClInclude Include="..\include\SDL3\SDL_video_capture.h" />
<ClInclude Include="..\src\audio\disk\SDL_diskaudio.h" />
<ClInclude Include="..\src\audio\dummy\SDL_dummyaudio.h" />
<ClInclude Include="..\src\audio\SDL_audiodev_c.h" />
@@ -180,6 +181,7 @@
<ClInclude Include="..\src\video\SDL_RLEaccel_c.h" />
<ClInclude Include="..\src\video\SDL_shape_internals.h" />
<ClInclude Include="..\src\video\SDL_sysvideo.h" />
<ClInclude Include="..\src\video\SDL_sysvidocapture.h" />
<ClInclude Include="..\src\video\SDL_yuv_c.h" />
<ClInclude Include="..\src\video\winrt\SDL_winrtevents_c.h" />
<ClInclude Include="..\src\video\winrt\SDL_winrtgamebar_cpp.h" />
@@ -520,6 +522,7 @@
<ClCompile Include="..\src\video\SDL_stretch.c" />
<ClCompile Include="..\src\video\SDL_surface.c" />
<ClCompile Include="..\src\video\SDL_video.c" />
<ClCompile Include="..\src\video\SDL_video_capture.c" />
<ClCompile Include="..\src\video\SDL_video_unsupported.c" />
<ClCompile Include="..\src\video\SDL_yuv.c" />
<ClCompile Include="..\src\video\winrt\SDL_winrtevents.cpp">
+9
View File
@@ -165,6 +165,9 @@
<ClInclude Include="..\include\SDL3\SDL_video.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\include\SDL3\SDL_video_capture.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\joystick\SDL_gamepad_c.h">
<Filter>Header Files</Filter>
</ClInclude>
@@ -405,6 +408,9 @@
<ClInclude Include="..\src\video\SDL_sysvideo.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="..\src\video\SDL_sysvideocapture.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="..\src\video\winrt\SDL_winrtevents_c.h">
<Filter>Source Files</Filter>
</ClInclude>
@@ -807,6 +813,9 @@
<ClCompile Include="..\src\video\SDL_video.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\video\SDL_video_capture.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\video\SDL_video_unsupported.c">
<Filter>Source Files</Filter>
</ClCompile>
+1
View File
@@ -653,6 +653,7 @@
<ClCompile Include="..\..\src\video\SDL_surface.c" />
<ClCompile Include="..\..\src\video\SDL_video.c" />
<ClCompile Include="..\..\src\video\SDL_video_unsupported.c" />
<ClCompile Include="..\..\src\video\SDL_video_capture.c" />
<ClCompile Include="..\..\src\video\SDL_vulkan_utils.c" />
<ClCompile Include="..\..\src\video\SDL_yuv.c" />
<ClCompile Include="..\..\src\video\windows\SDL_windowsclipboard.c" />
+3
View File
@@ -1185,6 +1185,9 @@
<ClCompile Include="..\..\src\video\SDL_video_unsupported.c">
<Filter>video</Filter>
</ClCompile>
<ClCompile Include="..\..\src\video\SDL_video_capture.c">
<Filter>video</Filter>
</ClCompile>
<ClCompile Include="..\..\src\video\SDL_yuv.c">
<Filter>video</Filter>
</ClCompile>
+1
View File
@@ -76,6 +76,7 @@
#include <SDL3/SDL_touch.h>
#include <SDL3/SDL_version.h>
#include <SDL3/SDL_video.h>
#include "SDL3/SDL_video_capture.h"
#include <SDL3/SDL_oldnames.h>
#endif /* SDL_h_ */
+369
View File
@@ -0,0 +1,369 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
/**
* \file SDL_video_capture.h
*
* Video Capture for the SDL library.
*/
#ifndef SDL_video_capture_h_
#define SDL_video_capture_h_
#include "SDL3/SDL_video.h"
#include <SDL3/SDL_begin_code.h>
/* Set up for C function definitions, even when using C++ */
#ifdef __cplusplus
extern "C" {
#endif
/**
* This is a unique ID for a video capture device for the time it is connected to the system,
* and is never reused for the lifetime of the application. If the device is
* disconnected and reconnected, it will get a new ID.
*
* The ID value starts at 1 and increments from there. The value 0 is an invalid ID.
*
* \sa SDL_GetVideoCaptureDevices
*/
typedef Uint32 SDL_VideoCaptureDeviceID;
/**
* The structure used to identify an SDL video capture device
*/
struct SDL_VideoCaptureDevice;
typedef struct SDL_VideoCaptureDevice SDL_VideoCaptureDevice;
#define SDL_VIDEO_CAPTURE_ALLOW_ANY_CHANGE 1
/**
* SDL_VideoCaptureSpec structure
*
* Only those field can be 'desired' when configuring the device:
* - format
* - width
* - height
*
* \sa SDL_GetVideoCaptureFormat
* \sa SDL_GetVideoCaptureFrameSize
*
*/
typedef struct SDL_VideoCaptureSpec
{
Uint32 format; /**< Frame SDL_PixelFormatEnum format */
int width; /**< Frame width */
int height; /**< Frame height */
} SDL_VideoCaptureSpec;
/**
* SDL Video Capture Status
*
* Change states but calling the function in this order:
*
* SDL_OpenVideoCapture()
* SDL_SetVideoCaptureSpec() -> Init
* SDL_StartVideoCapture() -> Playing
* SDL_StopVideoCapture() -> Stopped
* SDL_CloseVideoCapture()
*
*/
typedef enum
{
SDL_VIDEO_CAPTURE_FAIL = -1, /**< Failed */
SDL_VIDEO_CAPTURE_INIT = 0, /**< Init, spec hasn't been set */
SDL_VIDEO_CAPTURE_STOPPED, /**< Stopped */
SDL_VIDEO_CAPTURE_PLAYING /**< Playing */
} SDL_VideoCaptureStatus;
/**
* SDL Video Capture Status
*/
typedef struct SDL_VideoCaptureFrame
{
Uint64 timestampNS; /**< Frame timestamp in nanoseconds when read from the driver */
int num_planes; /**< Number of planes */
Uint8 *data[3]; /**< Pointer to data of i-th plane */
int pitch[3]; /**< Pitch of i-th plane */
void *internal; /**< Private field */
} SDL_VideoCaptureFrame;
/**
* Get a list of currently connected video capture devices.
*
* \param count a pointer filled in with the number of video capture devices
* \returns a 0 terminated array of video capture instance IDs which should be
* freed with SDL_free(), or NULL on error; call SDL_GetError() for
* more details.
*
* \since This function is available since SDL 3.0.0.
*
* \sa SDL_OpenVideoCapture
*/
extern DECLSPEC SDL_VideoCaptureDeviceID *SDLCALL SDL_GetVideoCaptureDevices(int *count);
/**
* Open a Video Capture device
*
* \param instance_id the video capture device instance ID
* \returns device, or NULL on failure; call
* SDL_GetError() for more information.
*
* \since This function is available since SDL 3.0.0.
*
* \sa SDL_GetVideoCaptureDeviceName
* \sa SDL_GetVideoCaptureDevices
* \sa SDL_OpenVideoCaptureWithSpec
*/
extern DECLSPEC SDL_VideoCaptureDevice *SDLCALL SDL_OpenVideoCapture(SDL_VideoCaptureDeviceID instance_id);
/**
* Set specification
*
* \param device opened video capture device
* \param desired desired video capture spec
* \param obtained obtained video capture spec
* \param allowed_changes allow changes or not
* \returns 0 on success or a negative error code on failure; call
* SDL_GetError() for more information.
*
* \since This function is available since SDL 3.0.0.
*
* \sa SDL_OpenVideoCapture
* \sa SDL_OpenVideoCaptureWithSpec
* \sa SDL_GetVideoCaptureSpec
*/
extern DECLSPEC int SDLCALL SDL_SetVideoCaptureSpec(SDL_VideoCaptureDevice *device,
const SDL_VideoCaptureSpec *desired,
SDL_VideoCaptureSpec *obtained,
int allowed_changes);
/**
* Open a Video Capture device and set specification
*
* \param instance_id the video capture device instance ID
* \param desired desired video capture spec
* \param obtained obtained video capture spec
* \param allowed_changes allow changes or not
* \returns device, or NULL on failure; call
* SDL_GetError() for more information.
*
* \since This function is available since SDL 3.0.0.
*
* \sa SDL_OpenVideoCapture
* \sa SDL_SetVideoCaptureSpec
* \sa SDL_GetVideoCaptureSpec
*/
extern DECLSPEC SDL_VideoCaptureDevice *SDLCALL SDL_OpenVideoCaptureWithSpec(SDL_VideoCaptureDeviceID instance_id,
const SDL_VideoCaptureSpec *desired,
SDL_VideoCaptureSpec *obtained,
int allowed_changes);
/**
* Get device name
*
* \param instance_id the video capture device instance ID
* \returns device name, shouldn't be freed
*
* \since This function is available since SDL 3.0.0.
*
* \sa SDL_GetVideoCaptureDevices
*/
extern DECLSPEC const char * SDLCALL SDL_GetVideoCaptureDeviceName(SDL_VideoCaptureDeviceID instance_id);
/**
* Get the obtained video capture spec
*
* \param device opened video capture device
* \param spec The SDL_VideoCaptureSpec to be initialized by this function.
* \returns 0 on success or a negative error code on failure; call
* SDL_GetError() for more information.
*
* \since This function is available since SDL 3.0.0.
*
* \sa SDL_SetVideoCaptureSpec
* \sa SDL_OpenVideoCaptureWithSpec
*/
extern DECLSPEC int SDLCALL SDL_GetVideoCaptureSpec(SDL_VideoCaptureDevice *device, SDL_VideoCaptureSpec *spec);
/**
* Get frame format of video capture device.
* The value can be used to fill SDL_VideoCaptureSpec structure.
*
* \param device opened video capture device
* \param index format between 0 and num -1
* \param format pointer output format (SDL_PixelFormatEnum)
* \returns 0 on success or a negative error code on failure; call
* SDL_GetError() for more information.
*
* \since This function is available since SDL 3.0.0.
*
* \sa SDL_GetNumVideoCaptureFormats
*/
extern DECLSPEC int SDLCALL SDL_GetVideoCaptureFormat(SDL_VideoCaptureDevice *device,
int index,
Uint32 *format);
/**
* Number of available formats for the device
*
* \param device opened video capture device
* \returns number of formats or a negative error code on failure; call
* SDL_GetError() for more information.
*
* \since This function is available since SDL 3.0.0.
*
* \sa SDL_GetVideoCaptureFormat
* \sa SDL_SetVideoCaptureSpec
*/
extern DECLSPEC int SDLCALL SDL_GetNumVideoCaptureFormats(SDL_VideoCaptureDevice *device);
/**
* Get frame sizes of the device and the specified input format.
* The value can be used to fill SDL_VideoCaptureSpec structure.
*
* \param device opened video capture device
* \param format a format that can be used by the device (SDL_PixelFormatEnum)
* \param index framesize between 0 and num -1
* \param width output width
* \param height output height
* \returns 0 on success or a negative error code on failure; call
* SDL_GetError() for more information.
*
* \since This function is available since SDL 3.0.0.
*
* \sa SDL_GetNumVideoCaptureFrameSizes
*/
extern DECLSPEC int SDLCALL SDL_GetVideoCaptureFrameSize(SDL_VideoCaptureDevice *device, Uint32 format, int index, int *width, int *height);
/**
* Number of different framesizes available for the device and pixel format.
*
* \param device opened video capture device
* \param format frame pixel format (SDL_PixelFormatEnum)
* \returns number of framesizes or a negative error code on failure; call
* SDL_GetError() for more information.
*
* \since This function is available since SDL 3.0.0.
*
* \sa SDL_GetVideoCaptureFrameSize
* \sa SDL_SetVideoCaptureSpec
*/
extern DECLSPEC int SDLCALL SDL_GetNumVideoCaptureFrameSizes(SDL_VideoCaptureDevice *device, Uint32 format);
/**
* Get video capture status
*
* \param device opened video capture device
* \returns 0 on success or a negative error code on failure; call
* SDL_GetError() for more information.
*
* \since This function is available since SDL 3.0.0.
*
* \sa SDL_VideoCaptureStatus
*/
extern DECLSPEC SDL_VideoCaptureStatus SDLCALL SDL_GetVideoCaptureStatus(SDL_VideoCaptureDevice *device);
/**
* Start video capture
*
* \param device opened video capture device
* \returns 0 on success or a negative error code on failure; call
* SDL_GetError() for more information.
*
* \since This function is available since SDL 3.0.0.
*
* \sa SDL_StopVideoCapture
*/
extern DECLSPEC int SDLCALL SDL_StartVideoCapture(SDL_VideoCaptureDevice *device);
/**
* Acquire a frame.
* The frame is a memory pointer to the image data, whose size and format
* are given by the the obtained spec.
*
* Non blocking API. If there is a frame available, frame->num_planes is non 0.
* If frame->num_planes is 0 and returned code is 0, there is no frame at that time.
*
* After used, the frame should be released with SDL_ReleaseVideoCaptureFrame
*
* \param device opened video capture device
* \param frame pointer to get the frame
* \returns 0 on success or a negative error code on failure; call
* SDL_GetError() for more information.
*
* \since This function is available since SDL 3.0.0.
*
* \sa SDL_ReleaseVideoCaptureFrame
*/
extern DECLSPEC int SDLCALL SDL_AcquireVideoCaptureFrame(SDL_VideoCaptureDevice *device, SDL_VideoCaptureFrame *frame);
/**
* Release a frame. Let the back-end re-use the internal buffer for video capture.
*
* All acquired frames should be released before closing the device.
*
* \param device opened video capture device
* \param frame frame pointer.
* \returns 0 on success or a negative error code on failure; call
* SDL_GetError() for more information.
*
* \since This function is available since SDL 3.0.0.
*
* \sa SDL_AcquireVideoCaptureFrame
*/
extern DECLSPEC int SDLCALL SDL_ReleaseVideoCaptureFrame(SDL_VideoCaptureDevice *device, SDL_VideoCaptureFrame *frame);
/**
* Stop Video Capture
*
* \param device opened video capture device
* \returns 0 on success or a negative error code on failure; call
* SDL_GetError() for more information.
*
* \since This function is available since SDL 3.0.0.
*
* \sa SDL_StartVideoCapture
*/
extern DECLSPEC int SDLCALL SDL_StopVideoCapture(SDL_VideoCaptureDevice *device);
/**
* Use this function to shut down video_capture processing and close the video_capture device.
*
* \param device opened video capture device
*
* \since This function is available since SDL 3.0.0.
*
* \sa SDL_OpenVideoCaptureWithSpec
* \sa SDL_OpenVideoCapture
*/
extern DECLSPEC void SDLCALL SDL_CloseVideoCapture(SDL_VideoCaptureDevice *device);
/* Ends C function definitions when using C++ */
#ifdef __cplusplus
}
#endif
#include <SDL3/SDL_close_code.h>
#endif /* SDL_video_capture_h_ */
@@ -244,11 +244,15 @@
#cmakedefine USE_POSIX_SPAWN @USE_POSIX_SPAWN@
#cmakedefine HAVE_COREMEDIA
/* SDL internal assertion support */
#if @SDL_DEFAULT_ASSERT_LEVEL_CONFIGURED@
#cmakedefine SDL_DEFAULT_ASSERT_LEVEL @SDL_DEFAULT_ASSERT_LEVEL@
#endif
#cmakedefine SDL_VIDEO_CAPTURE
/* Allow disabling of core subsystems */
#cmakedefine SDL_ATOMIC_DISABLED @SDL_ATOMIC_DISABLED@
#cmakedefine SDL_AUDIO_DISABLED @SDL_AUDIO_DISABLED@
@@ -197,6 +197,8 @@
#define SDL_VIDEO_METAL 1
#endif
#define HAVE_COREMEDIA 1
/* Enable system power support */
#define SDL_POWER_UIKIT 1
@@ -260,6 +260,8 @@
#endif
#endif
#define HAVE_COREMEDIA 1
/* Enable system power support */
#define SDL_POWER_MACOSX 1
+16
View File
@@ -923,6 +923,22 @@ SDL3_0.0.0 {
SDL_SetPropertyWithCleanup;
SDL_SetX11EventHook;
SDL_GetGlobalProperties;
SDL_OpenVideoCapture;
SDL_SetVideoCaptureSpec;
SDL_OpenVideoCaptureWithSpec;
SDL_GetVideoCaptureDeviceName;
SDL_GetVideoCaptureSpec;
SDL_GetVideoCaptureFormat;
SDL_GetNumVideoCaptureFormats;
SDL_GetVideoCaptureFrameSize;
SDL_GetNumVideoCaptureFrameSizes;
SDL_GetVideoCaptureStatus;
SDL_StartVideoCapture;
SDL_AcquireVideoCaptureFrame;
SDL_ReleaseVideoCaptureFrame;
SDL_StopVideoCapture;
SDL_CloseVideoCapture;
SDL_GetVideoCaptureDevices;
# extra symbols go here (don't modify this line)
local: *;
};
+16
View File
@@ -948,3 +948,19 @@
#define SDL_SetPropertyWithCleanup SDL_SetPropertyWithCleanup_REAL
#define SDL_SetX11EventHook SDL_SetX11EventHook_REAL
#define SDL_GetGlobalProperties SDL_GetGlobalProperties_REAL
#define SDL_OpenVideoCapture SDL_OpenVideoCapture_REAL
#define SDL_SetVideoCaptureSpec SDL_SetVideoCaptureSpec_REAL
#define SDL_OpenVideoCaptureWithSpec SDL_OpenVideoCaptureWithSpec_REAL
#define SDL_GetVideoCaptureDeviceName SDL_GetVideoCaptureDeviceName_REAL
#define SDL_GetVideoCaptureSpec SDL_GetVideoCaptureSpec_REAL
#define SDL_GetVideoCaptureFormat SDL_GetVideoCaptureFormat_REAL
#define SDL_GetNumVideoCaptureFormats SDL_GetNumVideoCaptureFormats_REAL
#define SDL_GetVideoCaptureFrameSize SDL_GetVideoCaptureFrameSize_REAL
#define SDL_GetNumVideoCaptureFrameSizes SDL_GetNumVideoCaptureFrameSizes_REAL
#define SDL_GetVideoCaptureStatus SDL_GetVideoCaptureStatus_REAL
#define SDL_StartVideoCapture SDL_StartVideoCapture_REAL
#define SDL_AcquireVideoCaptureFrame SDL_AcquireVideoCaptureFrame_REAL
#define SDL_ReleaseVideoCaptureFrame SDL_ReleaseVideoCaptureFrame_REAL
#define SDL_StopVideoCapture SDL_StopVideoCapture_REAL
#define SDL_CloseVideoCapture SDL_CloseVideoCapture_REAL
#define SDL_GetVideoCaptureDevices SDL_GetVideoCaptureDevices_REAL
+16
View File
@@ -981,3 +981,19 @@ SDL_DYNAPI_PROC(SDL_PropertiesID,SDL_GetDisplayProperties,(SDL_DisplayID a),(a),
SDL_DYNAPI_PROC(int,SDL_SetPropertyWithCleanup,(SDL_PropertiesID a, const char *b, void *c, void (SDLCALL *d)(void *userdata, void *value), void *e),(a,b,c,d,e),return)
SDL_DYNAPI_PROC(void,SDL_SetX11EventHook,(SDL_X11EventHook a, void *b),(a,b),)
SDL_DYNAPI_PROC(SDL_PropertiesID,SDL_GetGlobalProperties,(void),(),return)
SDL_DYNAPI_PROC(SDL_VideoCaptureDevice*,SDL_OpenVideoCapture,(SDL_VideoCaptureDeviceID a),(a),return)
SDL_DYNAPI_PROC(int,SDL_SetVideoCaptureSpec,(SDL_VideoCaptureDevice *a, const SDL_VideoCaptureSpec *b, SDL_VideoCaptureSpec *c, int d),(a,b,c,d),return)
SDL_DYNAPI_PROC(SDL_VideoCaptureDevice*,SDL_OpenVideoCaptureWithSpec,(SDL_VideoCaptureDeviceID a, const SDL_VideoCaptureSpec *b, SDL_VideoCaptureSpec *c, int d),(a,b,c,d),return)
SDL_DYNAPI_PROC(const char*,SDL_GetVideoCaptureDeviceName,(SDL_VideoCaptureDeviceID a),(a),return)
SDL_DYNAPI_PROC(int,SDL_GetVideoCaptureSpec,(SDL_VideoCaptureDevice *a, SDL_VideoCaptureSpec *b),(a,b),return)
SDL_DYNAPI_PROC(int,SDL_GetVideoCaptureFormat,(SDL_VideoCaptureDevice *a, int b, Uint32 *c),(a,b,c),return)
SDL_DYNAPI_PROC(int,SDL_GetNumVideoCaptureFormats,(SDL_VideoCaptureDevice *a),(a),return)
SDL_DYNAPI_PROC(int,SDL_GetVideoCaptureFrameSize,(SDL_VideoCaptureDevice *a, Uint32 b, int c, int *d, int *e),(a,b,c,d,e),return)
SDL_DYNAPI_PROC(int,SDL_GetNumVideoCaptureFrameSizes,(SDL_VideoCaptureDevice *a, Uint32 b),(a,b),return)
SDL_DYNAPI_PROC(SDL_VideoCaptureStatus,SDL_GetVideoCaptureStatus,(SDL_VideoCaptureDevice *a),(a),return)
SDL_DYNAPI_PROC(int,SDL_StartVideoCapture,(SDL_VideoCaptureDevice *a),(a),return)
SDL_DYNAPI_PROC(int,SDL_AcquireVideoCaptureFrame,(SDL_VideoCaptureDevice *a, SDL_VideoCaptureFrame *b),(a,b),return)
SDL_DYNAPI_PROC(int,SDL_ReleaseVideoCaptureFrame,(SDL_VideoCaptureDevice *a, SDL_VideoCaptureFrame *b),(a,b),return)
SDL_DYNAPI_PROC(int,SDL_StopVideoCapture,(SDL_VideoCaptureDevice *a),(a),return)
SDL_DYNAPI_PROC(void,SDL_CloseVideoCapture,(SDL_VideoCaptureDevice *a),(a),)
SDL_DYNAPI_PROC(SDL_VideoCaptureDeviceID*,SDL_GetVideoCaptureDevices,(int *a),(a),return)
+90
View File
@@ -0,0 +1,90 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../SDL_internal.h"
#ifndef SDL_sysvideocapture_h_
#define SDL_sysvideocapture_h_
#include "../SDL_list.h"
/* The SDL video_capture driver */
typedef struct SDL_VideoCaptureDevice SDL_VideoCaptureDevice;
/* Define the SDL video_capture driver structure */
struct SDL_VideoCaptureDevice
{
/* * * */
/* Data common to all devices */
/* The device's current video_capture specification */
SDL_VideoCaptureSpec spec;
/* Device name */
char *dev_name;
/* Current state flags */
SDL_AtomicInt shutdown;
SDL_AtomicInt enabled;
SDL_bool is_spec_set;
/* A mutex for locking the queue buffers */
SDL_Mutex *device_lock;
SDL_Mutex *acquiring_lock;
/* A thread to feed the video_capture device */
SDL_Thread *thread;
SDL_threadID threadid;
/* Queued buffers (if app not using callback). */
SDL_ListNode *buffer_queue;
/* * * */
/* Data private to this driver */
struct SDL_PrivateVideoCaptureData *hidden;
};
extern int OpenDevice(SDL_VideoCaptureDevice *_this);
extern void CloseDevice(SDL_VideoCaptureDevice *_this);
extern int InitDevice(SDL_VideoCaptureDevice *_this);
extern int GetDeviceSpec(SDL_VideoCaptureDevice *_this, SDL_VideoCaptureSpec *spec);
extern int StartCapture(SDL_VideoCaptureDevice *_this);
extern int StopCapture(SDL_VideoCaptureDevice *_this);
extern int AcquireFrame(SDL_VideoCaptureDevice *_this, SDL_VideoCaptureFrame *frame);
extern int ReleaseFrame(SDL_VideoCaptureDevice *_this, SDL_VideoCaptureFrame *frame);
extern int GetNumFormats(SDL_VideoCaptureDevice *_this);
extern int GetFormat(SDL_VideoCaptureDevice *_this, int index, Uint32 *format);
extern int GetNumFrameSizes(SDL_VideoCaptureDevice *_this, Uint32 format);
extern int GetFrameSize(SDL_VideoCaptureDevice *_this, Uint32 format, int index, int *width, int *height);
extern int GetDeviceName(int index, char *buf, int size);
extern int GetNumDevices(void);
extern SDL_bool check_all_device_closed(void);
extern SDL_bool check_device_playing(void);
#endif /* SDL_sysvideocapture_h_ */
+10
View File
@@ -31,6 +31,7 @@
#include "SDL_video_c.h"
#include "../events/SDL_events_c.h"
#include "../timer/SDL_timer_c.h"
#include "SDL_video_capture_c.h"
#ifdef SDL_VIDEO_OPENGL
#include <SDL3/SDL_opengl.h>
@@ -443,6 +444,7 @@ int SDL_VideoInit(const char *driver_name)
SDL_bool init_keyboard = SDL_FALSE;
SDL_bool init_mouse = SDL_FALSE;
SDL_bool init_touch = SDL_FALSE;
SDL_bool init_video_capture = SDL_FALSE;
int i = 0;
/* Check to make sure we don't overwrite '_this' */
@@ -471,6 +473,10 @@ int SDL_VideoInit(const char *driver_name)
goto pre_driver_error;
}
init_touch = SDL_TRUE;
if (SDL_VideoCaptureInit() < 0) {
goto pre_driver_error;
}
init_video_capture = SDL_TRUE;
/* Select the proper video driver */
video = NULL;
@@ -565,6 +571,9 @@ int SDL_VideoInit(const char *driver_name)
pre_driver_error:
SDL_assert(_this == NULL);
if (init_video_capture) {
SDL_QuitVideoCapture();
}
if (init_touch) {
SDL_QuitTouch();
}
@@ -3684,6 +3693,7 @@ void SDL_VideoQuit(void)
SDL_ClearClipboardData();
/* Halt event processing before doing anything else */
SDL_QuitVideoCapture();
SDL_QuitTouch();
SDL_QuitMouse();
SDL_QuitKeyboard();
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+33
View File
@@ -0,0 +1,33 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../SDL_internal.h"
#include "../../include/SDL3/SDL_video_capture.h"
#ifndef SDL_video_capture_c_h_
#define SDL_video_capture_c_h_
/* Initialize the video_capture subsystem */
int SDL_VideoCaptureInit(void);
/* Shutdown the video_capture subsystem */
void SDL_QuitVideoCapture(void);
#endif /* SDL_video_capture_c_h_ */
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+2
View File
@@ -358,6 +358,8 @@ add_sdl_test_executable(teststreaming NEEDS_RESOURCES TESTUTILS SOURCES teststre
add_sdl_test_executable(testtimer NONINTERACTIVE NONINTERACTIVE_ARGS --no-interactive NONINTERACTIVE_TIMEOUT 60 SOURCES testtimer.c)
add_sdl_test_executable(testurl SOURCES testurl.c)
add_sdl_test_executable(testver NONINTERACTIVE SOURCES testver.c)
add_sdl_test_executable(testvideocapture SOURCES testvideocapture.c)
add_sdl_test_executable(testvideocaptureminimal SOURCES testvideocaptureminimal.c)
add_sdl_test_executable(testviewport NEEDS_RESOURCES TESTUTILS SOURCES testviewport.c)
add_sdl_test_executable(testwm SOURCES testwm.c)
add_sdl_test_executable(testyuv NONINTERACTIVE NONINTERACTIVE_ARGS "--automated" NEEDS_RESOURCES TESTUTILS SOURCES testyuv.c testyuv_cvt.c)
File diff suppressed because it is too large Load Diff
+206
View File
@@ -0,0 +1,206 @@
/*
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely.
*/
#include "SDL3/SDL_main.h"
#include "SDL3/SDL.h"
#include "SDL3/SDL_test.h"
#include "SDL3/SDL_video_capture.h"
#include <stdio.h>
#ifdef __EMSCRIPTEN__
#include <emscripten/emscripten.h>
#endif
int main(int argc, char **argv)
{
SDL_Window *window = NULL;
SDL_Renderer *renderer = NULL;
SDL_Event evt;
int quit = 0;
SDLTest_CommonState *state = NULL;
SDL_VideoCaptureDevice *device = NULL;
SDL_VideoCaptureSpec obtained;
SDL_VideoCaptureFrame frame_current;
SDL_Texture *texture = NULL;
int texture_updated = 0;
SDL_zero(evt);
SDL_zero(obtained);
SDL_zero(frame_current);
/* Set 0 to disable TouchEvent to be duplicated as MouseEvent with SDL_TOUCH_MOUSEID */
SDL_SetHint(SDL_HINT_TOUCH_MOUSE_EVENTS, "0");
/* Set 0 to disable MouseEvent to be duplicated as TouchEvent with SDL_MOUSE_TOUCHID */
SDL_SetHint(SDL_HINT_MOUSE_TOUCH_EVENTS, "0");
/* Initialize test framework */
state = SDLTest_CommonCreateState(argv, 0);
if (state == NULL) {
return 1;
}
/* Enable standard application logging */
SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
/* Load the SDL library */
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s", SDL_GetError());
return 1;
}
window = SDL_CreateWindow("Local Video", 1000, 800, 0);
if (window == NULL) {
SDL_Log("Couldn't create window: %s", SDL_GetError());
return 1;
}
SDL_LogSetAllPriority(SDL_LOG_PRIORITY_VERBOSE);
renderer = SDL_CreateRenderer(window, NULL, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
if (renderer == NULL) {
/* SDL_Log("Couldn't create renderer: %s", SDL_GetError()); */
return 1;
}
device = SDL_OpenVideoCaptureWithSpec(0, NULL, &obtained, SDL_VIDEO_CAPTURE_ALLOW_ANY_CHANGE);
if (!device) {
SDL_Log("No video capture? %s", SDL_GetError());
return 1;
}
if (SDL_StartVideoCapture(device) < 0) {
SDL_Log("error SDL_StartVideoCapture(): %s", SDL_GetError());
return 1;
}
/* Create texture with appropriate format */
if (texture == NULL) {
texture = SDL_CreateTexture(renderer, obtained.format, SDL_TEXTUREACCESS_STATIC, obtained.width, obtained.height);
if (texture == NULL) {
SDL_Log("Couldn't create texture: %s", SDL_GetError());
return 1;
}
}
while (!quit) {
while (SDL_PollEvent(&evt)) {
int sym = 0;
switch (evt.type)
{
case SDL_EVENT_KEY_DOWN:
{
sym = evt.key.keysym.sym;
break;
}
case SDL_EVENT_QUIT:
{
quit = 1;
SDL_Log("Ctlr+C : Quit!");
}
}
if (sym == SDLK_ESCAPE || sym == SDLK_AC_BACK) {
quit = 1;
SDL_Log("Key : Escape!");
}
}
{
SDL_VideoCaptureFrame frame_next;
SDL_zero(frame_next);
if (SDL_AcquireVideoCaptureFrame(device, &frame_next) < 0) {
SDL_Log("err SDL_AcquireVideoCaptureFrame: %s", SDL_GetError());
}
#if 0
if (frame_next.num_planes) {
SDL_Log("frame: %p at %" SDL_PRIu64, (void*)frame_next.data[0], frame_next.timestampNS);
}
#endif
if (frame_next.num_planes) {
if (frame_current.num_planes) {
if (SDL_ReleaseVideoCaptureFrame(device, &frame_current) < 0) {
SDL_Log("err SDL_ReleaseVideoCaptureFrame: %s", SDL_GetError());
}
}
/* It's not needed to keep the frame once updated the texture is updated.
* But in case of 0-copy, it's needed to have the frame while using the texture.
*/
frame_current = frame_next;
texture_updated = 0;
}
}
/* Update SDL_Texture with last video frame (only once per new frame) */
if (frame_current.num_planes && texture_updated == 0) {
/* Use software data */
if (frame_current.num_planes == 1) {
SDL_UpdateTexture(texture, NULL,
frame_current.data[0], frame_current.pitch[0]);
} else if (frame_current.num_planes == 2) {
SDL_UpdateNVTexture(texture, NULL,
frame_current.data[0], frame_current.pitch[0],
frame_current.data[1], frame_current.pitch[1]);
} else if (frame_current.num_planes == 3) {
SDL_UpdateYUVTexture(texture, NULL, frame_current.data[0], frame_current.pitch[0],
frame_current.data[1], frame_current.pitch[1],
frame_current.data[2], frame_current.pitch[2]);
}
texture_updated = 1;
}
SDL_SetRenderDrawColor(renderer, 0x99, 0x99, 0x99, 255);
SDL_RenderClear(renderer);
{
int win_w, win_h, tw, th, w;
SDL_FRect d;
SDL_QueryTexture(texture, NULL, NULL, &tw, &th);
SDL_GetRenderOutputSize(renderer, &win_w, &win_h);
w = win_w;
if (tw > w - 20) {
float scale = (float) (w - 20) / (float) tw;
tw = w - 20;
th = (int)((float) th * scale);
}
d.x = (float)(10 );
d.y = (float)(win_h - th);
d.w = (float)tw;
d.h = (float)(th - 10);
SDL_RenderTexture(renderer, texture, NULL, &d);
}
SDL_Delay(10);
SDL_RenderPresent(renderer);
}
if (SDL_StopVideoCapture(device) < 0) {
SDL_Log("error SDL_StopVideoCapture(): %s", SDL_GetError());
}
if (frame_current.num_planes) {
SDL_ReleaseVideoCaptureFrame(device, &frame_current);
}
SDL_CloseVideoCapture(device);
if (texture) {
SDL_DestroyTexture(texture);
}
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
SDLTest_CommonDestroyState(state);
return 0;
}