close
Skip to content

Add video capture API proposal#5477

Merged
slouken merged 1 commit into
libsdl-org:mainfrom
1bsyl:br_video_capture
Nov 9, 2023
Merged

Add video capture API proposal#5477
slouken merged 1 commit into
libsdl-org:mainfrom
1bsyl:br_video_capture

Conversation

@1bsyl
Copy link
Copy Markdown
Contributor

@1bsyl 1bsyl commented Mar 31, 2022

I thought it could be interesting to add a SDL Video Capture API (was also suggested in #4)

This only provides a set of Open/Start/Stop, Get/Release Frame + query format/size features.
With implementation for

  • linux using 'Video4Linux' (software data + dmabuf hardware)
  • Android using ndk / libcamera2 (hardcoded NV12) (software data + hardware buffer)
  • IOS : AVCapture API (hardcoded NV12) (software data)
  • MACOSX: same code as IOS

there is a test program (testvideocapture)

to build, you need to run first ./src/dynapi/gendynapi.py

@sezero
Copy link
Copy Markdown
Contributor

sezero commented Mar 31, 2022

Separation of list procedures is a good thing that can be done without this PR.

@1bsyl
Copy link
Copy Markdown
Contributor Author

1bsyl commented Apr 1, 2022

@sezero yes, this is done thanks ! Should be ok !

@sezero
Copy link
Copy Markdown
Contributor

sezero commented Apr 2, 2022

A few notes (all of which can be rectified easily later when
you finalize things):

  • The current code relies on static linkage to SDL2, because
    SDL_VideoCaptureInit and SDL_VideoCaptureQuit are not public
    in the public header.

  • Dynamic linkage needs dynapi on linux & co, but dynapi fails
    because the SDL_VideoCaptureDeviceID type isn't known to it.

  • testvideocapture.c is plagued with c99-isms.

@1bsyl
Copy link
Copy Markdown
Contributor Author

1bsyl commented Apr 2, 2022

@sezero thanks ! I've fixed. The whole thing is mostly a draft now ...
I just want to call "gendynapi.pl" at the very last moment, to avoid merge each time this is modified

@sezero
Copy link
Copy Markdown
Contributor

sezero commented Apr 2, 2022

Is there a specific reason you want a dedicated SDL_VideoCaptureDeviceID type
instead of plain Sint32 - that way, you won't have to include video_capture.h
from within SDL.h and only its users will have to include it.

Here is a very minor tidy-up: test/Makefile.os2 part is commented out because
we don't have dyapi yet and I don't want CI failures.

diff --git a/Makefile.os2 b/Makefile.os2
index 9060e0e..3902d25 100644
--- a/Makefile.os2
+++ b/Makefile.os2
@@ -77,3 +77,4 @@ SRCS+= SDL_blit.c SDL_blit_0.c SDL_blit_1.c SDL_blit_A.c SDL_blit_auto.c &
        SDL_pixels.c SDL_rect.c SDL_RLEaccel.c SDL_shape.c SDL_stretch.c &
-       SDL_surface.c SDL_video.c SDL_video_capture.c SDL_clipboard.c SDL_vulkan_utils.c SDL_egl.c
+       SDL_surface.c SDL_video.c SDL_clipboard.c SDL_video_capture.c SDL_egl.c &
+       SDL_vulkan_utils.c
 
diff --git a/test/testvideocapture.c b/test/testvideocapture.c
index e1a7816..3672092 100644
--- a/test/testvideocapture.c
+++ b/test/testvideocapture.c
@@ -353,4 +353,6 @@ int main(int argc, char **argv)
         {
+            static int x = 0;
             SDL_Rect r;
-            static int x = 0; x += 10; if (x > 1000) x = 0;
+            x += 10;
+            if (x > 1000) x = 0;
             r.x = x;
diff --git a/test/Makefile.os2 b/test/Makefile.os2
index e238af4..2ea51b0 100644
--- a/test/Makefile.os2
+++ b/test/Makefile.os2
@@ -29,3 +29,3 @@ TARGETS = testatomic.exe testdisplayinfo.exe testbounds.exe testdraw2.exe &
           testsurround.exe testyuv.exe testgl2.exe testvulkan.exe testnative.exe &
-          testautomation.exe
+          testautomation.exe #testvideocapture.exe
 

@1bsyl
Copy link
Copy Markdown
Contributor Author

1bsyl commented Apr 2, 2022

@sezero I think this is fixed. Do you receive also the notification the ci build failed for this branch ?
I hope this is ok now.
SDL_VideoCaptureDeviceID sound better to read the API but that can be changed,
there are also type that would fail the dynapi (like SDL_VideoCaptureSpec)

@sezero
Copy link
Copy Markdown
Contributor

sezero commented Apr 2, 2022

@sezero I think this is fixed. Do you receive also the notification the ci build failed for this branch ? I hope this is ok now.

Yes, CI seems fixed.

SDL_VideoCaptureDeviceID sound better to read the API but that can be changed, there are also type that would fail the dynapi (like SDL_VideoCaptureSpec)

OK

Comment thread include/SDL_video_capture.h Outdated
Comment thread include/SDL_video_capture.h Outdated
*
* \sa SDL_VideoCaptureReleaseFrame
*/
extern DECLSPEC int SDLCALL SDL_VideoCaptureAcquireFrame(SDL_VideoCaptureDeviceID id, SDL_VideoCaptureFrame *frame, Uint64 *ticks);
Copy link
Copy Markdown
Contributor

@Starbuck5 Starbuck5 Apr 13, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've just been looking at the header, I haven't looked at implementation. One important distinction between different video capture APIs is blocking vs non blocking. I assume if you call this function and the webcam hasn't "generated" a new image, it will block until it can give you a new frame?

Copy link
Copy Markdown
Contributor Author

@1bsyl 1bsyl Apr 13, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no, this is a non blocking API. that may change.
But making a blocking api is on top is easier.
I've updated the header

Copy link
Copy Markdown
Contributor

@Starbuck5 Starbuck5 Apr 14, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's cool, I think a non blocking API is more user friendly.

So it might return the same frame pixel data on multiple calls?

I don't see any header updates on this, I'm thinking it should explicitly say it doesn't block if there isn't a new frame available, it does X.

pygame.camera has a query_image() function that returns True if a new frame is ready. That seems very helpful for a non blocking api, you can only UpdateTexture or convert to a surface when needed.

Comment thread include/SDL_video_capture.h Outdated
*
* \sa SDL_GetNumVideoCaptureDevices
*/
extern DECLSPEC const char * SDLCALL SDL_GetVideoCaptureDeviceName(int index);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I love to see it! Seems like lots of video capture APIs don't provide a way to get the device name. On Linux this is probably just /dev/video, but on Windows or Mac this could be nice and descriptive.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes..
on ios this is very verbose. on linux: /dev/video. on android just number ...
maybe this can be improved

Copy link
Copy Markdown
Contributor

@Starbuck5 Starbuck5 Apr 14, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have any ideas to make this better, I just wanted to give it some appreciation 😄 (Feel free to resolve)

Maybe the header should specify UTF8 encoded string, which I assume is what you're using.

Comment thread include/SDL_video_capture.h Outdated
Comment on lines +161 to +162
#define SDL_VIDEO_CAPTURE_TYPE_COMPRESSED 1
#define SDL_VIDEO_CAPTURE_TYPE_EMULATED 2
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How does this work? Every frame format is either compressed or emulated?

I assume if a frame format is in a compressed format, an uncompressed format needs to be emulated. If you have video "compressed" in H263, you would want to emulate that as RGBA32, for instance.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

webcam can output a jpeg frame (compressed) or RGBA (emulated).
this is just some info about format that the driver give (on android I think)
maybe this could be removed if not helpfull

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found the flags in the V4l2 docs: https://www.kernel.org/doc/html/latest/userspace-api/media/v4l/vidioc-enum-fmt.html

I think these are separate things
You can have something compressed and not emulated
You can have something compressed and emulated

I don't think this API is planning to allow people to get compressed formats, since one specifies things in SDL_PixelFormats.

So the useful bit of information is whether the format you're looking at is "native" or "emulated," where "native" is better for performance, theoretically.

It's strange to me that V4l2 allows you to enumerate emulated video types like this. I have some experience with Microsoft Media Foundation, and I am the author of the pygame.camera backend for Windows. In MSMF, you do the emulation yourself using "Media Foundation Transforms." These MFTs, as they are called (no relation to NFTs), give out very little guarantees. So an MSMF function of this function would have to create an MFT of [webcam format] and then try to set the output format to everything in [formats desired] and add the ones that worked to a list. Sorry, that's kind of a ramble-- this can be ported to MSMF, it's just less convenient than the V4L2 API here.

@Starbuck5
Copy link
Copy Markdown
Contributor

I've been chewing on all the ways to enumerate things for a couple days, it just seemed odd to me and I needed to think about why.

It works like this:

enumerate cameras
    enumerate formats
        enumerate dimensions (frame sizes)

The indentation shows the "dependency chain" of the functions. You need a camera, then a format the camera supports, then a frame size.

Looking at how this works, and given the fact that this API returns pixels instead of a Surface, and it makes me think this is meant for use with Textures, with LockTexture or UpdateTexture. Because with that, the user is looking for a valid webcam configuration in a pixelformat supported by the Renderer. Tell me if I'm assuming this all wrong. 😄

Here's an alternative idea-
Given a camera, you can enumerate all workable VideoCaptureSpec structs. Putting the format and dimension information in one "plane" allows easier searching for people who are doing that.
But since lots of people will presumably want to restrict to a certain range of pixelformats, you should be able to enumerate workable VideoCaptureSpecs in a set of pixelformats.

enumerate cameras
    enumerate VideoCaptureSpecs
    enumerate VideoCaptureSpecs in set of pixelformats

Maybe these VideoCaptureSpecs should be sorted so the highest resolution modes are first.

@1bsyl
Copy link
Copy Markdown
Contributor Author

1bsyl commented Apr 14, 2022

@Starbuck5 this is still a work in progress. things are changing while trying on backend. but currently it starts
working on ios/android/linux.
you can try to implement for the window backend. I've no camera so I can´t do this on window.

This can be done progressively:enumerate device / format / sizes. start capture.
There is a small test app
And it's not very long:
for IOS, it's ~400 lines.
for Android, ~650 lines
linux was longer (because there are several methods inside: mmap or useptr)

@sezero
Copy link
Copy Markdown
Contributor

sezero commented Apr 14, 2022

autotools need the equivalent changes made in cmake. Untested patch to
configure.ac follows

diff --git a/configure.ac b/configure.ac
index 1d96004..b18d214 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2189,13 +2189,22 @@ CheckCOCOA()
           #import <Cocoa/Cocoa.h>
         ]],[])], [have_cocoa=yes],[])
         AC_MSG_RESULT($have_cocoa)
-        CFLAGS="$save_CFLAGS"
         if test x$have_cocoa = xyes; then
             AC_DEFINE(SDL_VIDEO_DRIVER_COCOA, 1, [ ])
             SOURCES="$SOURCES $srcdir/src/video/cocoa/*.m"
             SUMMARY_video="${SUMMARY_video} cocoa"
             have_video=yes
         fi
+        AC_MSG_CHECKING(for CoreMedia framework)
+        have_coremedia=no
+        AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+          #import <AVFoundation/AVFoundation.h>
+          #import <CoreMedia/CoreMedia.h>
+        ]],[])], [have_coremedia=yes],[])
+        CFLAGS="$save_CFLAGS"
+        if test x$have_coremedia = xyes; then
+            SOURCES="$SOURCES $srcdir/src/video/SDL_video_capture.m"
+        fi
     fi
 }
 
@@ -4218,12 +4227,14 @@     *-ios-*)
         SOURCES="$SOURCES $srcdir/src/video/uikit/*.m"
         SUMMARY_video="${SUMMARY_video} uikit"
         have_video=yes
+        SOURCES="$SOURCES $srcdir/src/video/SDL_video_capture.m"
         EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lm -liconv -lobjc"
         EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,AVFoundation"
         EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,AudioToolbox"
         EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,CoreAudio"
         EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,CoreGraphics"
         EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,CoreMotion"
+        EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,CoreMedia"
         EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,Foundation"
         EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,GameController"
         EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,OpenGLES"
@@ -4323,6 +4334,9 @@     *-*-darwin* )
         # The Mac OS X platform requires special setup.
         EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lobjc"
         EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,CoreVideo"
+        if test x$have_coremedia = xyes; then
+           EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,CoreMedia"
+        fi
         EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,Cocoa"
         EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,Carbon"
         EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,IOKit"

Comment thread CMakeLists.txt Outdated
Comment thread src/video/SDL_video_capture.m Outdated
@1bsyl
Copy link
Copy Markdown
Contributor Author

1bsyl commented Apr 15, 2022

@sezero Updated thanks ! Maybe we also need a true macosx tester with a webcam !

@sezero
Copy link
Copy Markdown
Contributor

sezero commented Apr 15, 2022

Did some build testing using autotools (cross-compile on Linux).
Here goes:

  • SDL_video_capture.m and SDL_video_capture.c names conflict: autofoo
    doesn't seem to differenciate.
    My solution: Renamed SDL_video_capture.m to SDL_videocap_apple.m,
    adjusted configury, Xcode project file, and cmake script.

  • AVCaptureDeviceTypeBuiltInWideAngleCamera requires macOS SDK 10.15
    at compile time (and obviously 10.15+ at run time.) Same is true for
    AVCaptureDeviceDiscoverySession.
    Solution: Specifically check AVCaptureDeviceTypeBuiltInWideAngleCamera
    in configury (did not touch cmake), define HAVE_COREMEDIA if all
    is good. Define HAVE_COREMEDIA in mocosx and iphoneos config files.
    Undefine HAVE_COREMEDIA in SDL_videocap_apple.m if TVOS or OSX SDK
    is old.

  • If CoreMedia isn't available, linkage fails.
    My solution: added stubs for symbols required by SDL_video_capture.c

  • Linking to CoreMedia.framework wasn't enough:

    "_AVCaptureDeviceTypeBuiltInWideAngleCamera", referenced from:
        _get_device_by_name in SDL_videocap_apple.o
        _GetDeviceName in SDL_videocap_apple.o
        _GetNumDevices in SDL_videocap_apple.o
    "_AVCaptureSessionPresetHigh", referenced from:
        _InitDevice in SDL_videocap_apple.o
    "_AVMediaTypeVideo", referenced from:
        _get_device_by_name in SDL_videocap_apple.o
        _GetDeviceName in SDL_videocap_apple.o
        _GetNumDevices in SDL_videocap_apple.o
    "_OBJC_CLASS_$_AVCaptureDeviceDiscoverySession", referenced from:
        objc-class-ref in SDL_videocap_apple.o
    "_OBJC_CLASS_$_AVCaptureDeviceInput", referenced from:
        objc-class-ref in SDL_videocap_apple.o
    "_OBJC_CLASS_$_AVCaptureSession", referenced from:
        objc-class-ref in SDL_videocap_apple.o
    "_OBJC_CLASS_$_AVCaptureVideoDataOutput", referenced from:
        objc-class-ref in SDL_videocap_apple.o
    

    My solution: Weak-link with AVFoundation.framework, as well.
    (did not touch cmake, and did not touch Xcode: someone else should
    do them.)

  • You may want to add additional if (@available(macOS 10.15, *)) to other
    procedures in SDL_videocap_apple.m (or not..)

Here is the patch file I generated: patch_5477a.txt

  • Do read the patch (and the notes I gathered above) before applying.
  • Remember to git mv SDL_video_capture.m SDL_videocap_apple.m before
    applying.

(EDIT: a bad patch was attached, now corrected.)

@1bsyl
Copy link
Copy Markdown
Contributor Author

1bsyl commented Apr 15, 2022

I've applied the patch 5477a.txt
I misread the renaming (SDL_videocap_apple.m vs SDL_video_capture_apple.m) so I've had to change the name inside the patch also

@sezero
Copy link
Copy Markdown
Contributor

sezero commented Apr 15, 2022

OK, either way the same changes are in.

@Starbuck5
Copy link
Copy Markdown
Contributor

A simple attempt to build on MacOS (./configure, make) failed.
Mac OS 10.13 (intel)
make-output.txt

@sezero
Copy link
Copy Markdown
Contributor

sezero commented Apr 18, 2022

A simple attempt to build on MacOS (./configure, make) failed.

Did you run ./autogen.sh before running configure?

@sezero
Copy link
Copy Markdown
Contributor

sezero commented Apr 18, 2022

A simple attempt to build on MacOS (./configure, make) failed.

Did you run ./autogen.sh before running configure?

And here is a patch that just does that for you, for convenience: patch_configure.txt

@Starbuck5
Copy link
Copy Markdown
Contributor

This is probably my inexperience in C that I can't resolve these. I didn't run autogen, but after I did I was able to configure, make, and make install the branch of SDL.

I now get problems trying to compile the test program:
compile-output.txt
I get the same thing trying to run make testvideocapture.

@sezero
Copy link
Copy Markdown
Contributor

sezero commented Apr 18, 2022

I now get problems trying to compile the test program: compile-output.txt I get the same thing trying to run make testvideocapture.

That's because @1bsyl hasn't integrated the new capture apis into dynapi yet.

@sezero
Copy link
Copy Markdown
Contributor

sezero commented Apr 18, 2022

That's because @1bsyl hasn't integrated the new capture apis into dynapi yet.

If you want to test things, do:

cd src/dynapi && ./gendynapi.pl
cd ../..

And then build SDL and install. Then testvideocapture should link properly.

@Starbuck5
Copy link
Copy Markdown
Contributor

Starbuck5 commented Apr 18, 2022

I can build it now! It doesn't detect my camera. I'm on a macbook pro with an integrated webcam. When I click devices, it says number of devices is 0.

It's probably because of the DiscoverySession thing, that's new in MacOS 10.15, and I'm running 10.13.

@sezero
Copy link
Copy Markdown
Contributor

sezero commented Apr 18, 2022

I can build it now!

Great!

It doesn't detect my camera. I'm on a macbook pro with an integrated webcam. When I click devices, it says number of devices is 0.

It's probably because of the DiscoverySession thing, that's new in MacOS 10.15, and I'm running 10.13.

That part is for Sylvain

@1bsyl
Copy link
Copy Markdown
Contributor Author

1bsyl commented Apr 18, 2022

@sezero should I apply the previous patch_configure.txt ?

@Starbuck5
indeed, this seems to be a 10.15 function... at least it doesn't crash..
maybe we could do a fallback in the SDL2 code.
in src/video/SDL_video_capture_apple.c
line 113, discover_devices:

instead of:

return devices;

would do something:

if ([devices count] > 0) {
  return devices;
} else {
  AVCaptureDevice *captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
  if (captureDevice == nil) {
    return devices;
  } else {
     NSArray<AVCaptureDevice *> default_device = @[ captureDevice ];
     return default_device;
 }
}

(this is un-tested..)

@1bsyl 1bsyl force-pushed the br_video_capture branch 2 times, most recently from 4e3154e to 2c077d0 Compare November 4, 2023 20:54
@1bsyl
Copy link
Copy Markdown
Contributor Author

1bsyl commented Nov 4, 2023

Is it possible to get the video surface as hardware memory instead of as a software surface? This would be very useful for zero-copy integration with picture-in-picture, or hardware encoding video.

yes, I had a patch at first, with zero copy integration (ryan suggested to remove this).
Not sure if it's well-done, though it was working.
SDL_video_capture_diff_2023-03-29_v5__REMOVE_DMABUFF.txt
this patch need more re-work to be applied I guess

@slouken
Copy link
Copy Markdown
Collaborator

slouken commented Nov 4, 2023

Is it possible to get the video surface as hardware memory instead of as a software surface? This would be very useful for zero-copy integration with picture-in-picture, or hardware encoding video.

yes, I had a patch at first, with zero copy integration (ryan suggested to remove this). Not sure if it's well-done, though it was working. SDL_video_capture_diff_2023-03-29_v5__REMOVE_DMABUFF.txt this patch need more re-work to be applied I guess

Let's come back to that? We'll definitely want it, but we'll probably need something like the hardware surface support in testffmpeg.c to display them and that is a good follow-on to this PR.

@1bsyl
Copy link
Copy Markdown
Contributor Author

1bsyl commented Nov 4, 2023

Is it possible to get the video surface as hardware memory instead of as a software surface? This would be very useful for zero-copy integration with picture-in-picture, or hardware encoding video.

yes, I had a patch at first, with zero copy integration (ryan suggested to remove this). Not sure if it's well-done, though it was working. SDL_video_capture_diff_2023-03-29_v5__REMOVE_DMABUFF.txt this patch need more re-work to be applied I guess

Let's come back to that? We'll definitely want it, but we'll probably need something like the hardware surface support in testffmpeg.c to display them and that is a good follow-on to this PR.

ok, I'll see that next week !

@slouken
Copy link
Copy Markdown
Collaborator

slouken commented Nov 4, 2023

Is it possible to get the video surface as hardware memory instead of as a software surface? This would be very useful for zero-copy integration with picture-in-picture, or hardware encoding video.

yes, I had a patch at first, with zero copy integration (ryan suggested to remove this). Not sure if it's well-done, though it was working. SDL_video_capture_diff_2023-03-29_v5__REMOVE_DMABUFF.txt this patch need more re-work to be applied I guess

Let's come back to that? We'll definitely want it, but we'll probably need something like the hardware surface support in testffmpeg.c to display them and that is a good follow-on to this PR.

ok, I'll see that next week !

I would probably get this PR merged before working on hardware surface support. We'll also want it for Windows as well.

@1bsyl
Copy link
Copy Markdown
Contributor Author

1bsyl commented Nov 6, 2023

@slouken I've just changed to use instance_id, but the list is currently hard-coded, ( no add/remove event)

f9768e8

also added testvideocaputremininal, as a simpler example than testvideocapture which handles several devices + UI

Comment thread include/SDL3/SDL_video_capture.h Outdated
Comment thread include/SDL3/SDL_video_capture.h Outdated
Comment thread src/dynapi/SDL_dynapi.sym Outdated
Comment thread src/dynapi/SDL_dynapi_overrides.h Outdated
Comment thread src/dynapi/SDL_dynapi_procs.h Outdated
Comment thread CMakeLists.txt Outdated
Comment thread CMakeLists.txt
Comment thread src/dynapi/SDL_dynapi.sym Outdated
Comment thread src/dynapi/SDL_dynapi_overrides.h Outdated
Comment thread src/dynapi/SDL_dynapi_procs.h Outdated
@slouken
Copy link
Copy Markdown
Collaborator

slouken commented Nov 7, 2023

@libsdl-org/a-team, any other comments before this is merged?

Copy link
Copy Markdown
Contributor

@madebr madebr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've got a few non-blocking questions.

*
* \sa SDL_GetNumVideoCaptureFormats
*/
extern DECLSPEC int SDLCALL SDL_GetVideoCaptureFormat(SDL_VideoCaptureDevice *device,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would returning an array of struct SDL_VideoCaptureFormat be a nicer API instead of a combination of SDL_GetVideoCaptureFormat and SDL_GetNumVideoCaptureFormats?
You're also returning an array that should be freed with SDL_GetVideoCaptureDevices.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, this is a possibility.
format is: SDL_PixelFormatEnum
but there are also sometimes unknow eg: MPEG compressed frame.
(per format, there is a list of framesize available)

Comment on lines +306 to +307
* 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.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is polling this function the only way to know a new frame is available?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, it's a non-blocking function, it checks if a frame get received

* 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
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can multiple SDL_VideoCaptureFrames be used simultaneously? Or will this function fail until the previous frmame is released?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd say yes. because there several buffer available internally.
but it may also depend on the hardware, which could prevent from acquiring a new frame it the first one haven't been release.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

edit:
the generic layer, doesn't limit the number of buffer.
it's the video capture back-end that can push as many frame as it want/can.
for linux, the backend is hard-coded at 8 buffers.
if the user doesn't release the 8 frame, the acquisition is stucked / lacking free buffers

extern DECLSPEC int SDLCALL SDL_StopVideoCapture(SDL_VideoCaptureDevice *device);

/**
* Use this function to shut down video_capture processing and close the video_capture device.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if a SDL_VideoCaptureFrame is not released prior to closing the capture device?
Does SDL_ReleaseVideoCaptureFrame after SDL_CloseVideoCapture still work (and not leak)?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, good point...
currently SDL_ReleaseVideoCaptureFrame need the "device", so a releaseFrame won't work.

maybe for some driver, it's not possible to use the frame after the device is closed.
for some other maybe it would be possible.

We could for the release all frame in the CloseDevice (or StopDevice?)
or prevent a CloseDevice if some frame a not released ?
also. frame that are recorded but not acquired would also need to be release :)
-> so probably, best is to release all frame (acquirer or not) in CloseDevice

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(btw CloseDevice invalidates the 'device', so SDL_ReleaseVideoCaptureFrame would do invalid memory read/write)

Copy link
Copy Markdown
Contributor Author

@1bsyl 1bsyl Nov 7, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done here: 987edfa

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, I am wrong. here.
when a frame is acquired, it has to be release before closing the device

  • on android, it's an AImage, so we could release the image anyway
  • but on linux, we need the file descriptor of the device

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(but we still need to release the non acquired frames!!) so the commit is ok

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added a comment in the public header, for ReleaseFrame()

@1bsyl
Copy link
Copy Markdown
Contributor Author

1bsyl commented Nov 7, 2023

so still maybe:

  • window back-end missing ?
  • should SDL_GetVideoCaptureFormat and SDL_GetNumVideoCaptureFormats just return an array?
  • should format, be extended, (eg MPEG format for the frame..) instead of being just a SDL_PixelFormat .
  • ...

@1bsyl 1bsyl force-pushed the br_video_capture branch 2 times, most recently from 2814f33 to 2d21db5 Compare November 7, 2023 21:41
@icculus
Copy link
Copy Markdown
Collaborator

icculus commented Nov 8, 2023

I'm thinking I'd like to move away from the ALLOW_ANY_CHANGE flag thing, like we did for the audio subsystem, but I'm also thinking I'd like to iterate on that in main, so @1bsyl doesn't have to manage this in a branch any longer.

So let's resolve whatever else is pending here, merge, and deal with those sort of tweaks where it's easier for all of us to make changes and Sylvain doesn't have to keep merging a PR with the latest.

@1bsyl
Copy link
Copy Markdown
Contributor Author

1bsyl commented Nov 9, 2023

yet, another detach-merge-commit-rebase-push :)

@slouken slouken merged commit 59f93e2 into libsdl-org:main Nov 9, 2023
@slouken
Copy link
Copy Markdown
Collaborator

slouken commented Nov 9, 2023

Merged, thank you!

@icculus icculus mentioned this pull request Feb 20, 2024
@1bsyl 1bsyl deleted the br_video_capture branch August 27, 2025 08:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants