centricular / gstcefsrc

A simple gstreamer wrapper around Chromium Embedded Framework
86 stars 45 forks source link

Reland "Fix build on macosarm64 and pay attention to USE_SANDBOX flag" #83

Closed SteveMcFarlin closed 3 months ago

SteveMcFarlin commented 6 months ago

The issue with the prior PR was USE_SANBOX was ON by default. I clearly did not pay attention enough to that. IMO the default should be OFF, and only be enabled if the arch is arm and the target is macos.

Additionally I had to add a few additional cmake options for the MacARM build otherwise I would get errors, and in one case lib_cef_dllwrapper was being compiled for i386. Let me know if there is something wrong there.

Apple clang version 15.0.0 (clang-1500.1.0.2.5) Target: arm64-apple-darwin23.2.0 cmake version 3.24.1

reinismu commented 6 months ago

It worked on MacOS as well or just compiled?

SteveMcFarlin commented 6 months ago

I compiled and did a gst-inspect-1.0 on it. I did not test but I can run one now... BUMMER. SIGSEGV. Changing to draft. I will work on it tomorrow. It's late for me.

SteveMcFarlin commented 6 months ago

GStreamer 1.22.4

0:00:00.789074000 57748 0x60000396f2a0 LOG               aggregator gstaggregator.c:2194:gst_aggregator_query_latency_unlocked:<mix> Signaling src from thread 0x60000396f2a0
0:00:00.789077000 57748 0x60000396f2a0 DEBUG             aggregator gstaggregator.c:2197:gst_aggregator_query_latency_unlocked:<mix> configured latency live:true min:33219954 max:-1
0:00:00.789096000 57748 0x60000396f2a0 LOG               aggregator gstaggregator.c:488:gst_aggregator_check_pads_ready:<mix> checking pads
0:00:00.789099000 57748 0x60000396f2a0 LOG               aggregator gstaggregator.c:532:gst_aggregator_check_pads_ready:<mix:sink_0> Have no buffer and not EOS yet
0:00:00.789101000 57748 0x60000396f2a0 LOG               aggregator gstaggregator.c:532:gst_aggregator_check_pads_ready:<mix:sink_1> Have no buffer and not EOS yet
0:00:00.789103000 57748 0x60000396f2a0 LOG               aggregator gstaggregator.c:587:gst_aggregator_check_pads_ready:<mix> pad not ready to be aggregated yet
0:00:00.789106000 57748 0x60000396f2a0 LOG               aggregator gstaggregator.c:880:gst_aggregator_wait_and_check:<mix> Waiting for src on thread 0x60000396f2a0
 thread 1 , stop reason = signal SIGSTOP

No such issue on Linux

reinismu commented 6 months ago

You can see here https://github.com/centricular/gstcefsrc/pull/67 Plus I started on my branch to make it work. https://github.com/centricular/gstcefsrc/compare/master...reinismu:gstcefsrc:macos-support but I'm not familiar with cmake and so so with MacOS.

We might put a bounty on this thing. Running this plugin on MacOS would benefit us.

reinismu commented 6 months ago

We had a discussion and we decided to reward 1000$ to someone who can make this plugin work on Apple Silicon MacOS :)

SteveMcFarlin commented 6 months ago

You are headed on the right path with what you have done in gstcefsubprocess. If If I were to do more work on this I would look to the CEF examples. Specifically the mac process helper. If I have time this evening I will see what I can come up with.

SteveMcFarlin commented 6 months ago

So over lunch I took another look at this. The segfault is coming from CefString. In static gpointer run_cef(GstCefSrc *src) { There is the line:

CefString(&settings.browser_subprocess_path)
      .FromASCII(browser_subprocess_path);

That is where the segfault happens. I will look into it more later today if I have time.

SteveMcFarlin commented 6 months ago

At this point not sure what is going on here. From the code CefString str("LETS CRASH");.

* thread #17, name = 'cef-ui-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
    frame #0: 0x0000000000000000
error: memory read failed for 0x0
Target 0: (gst-launch-1.0) stopped.
(lldb) bt
* thread #17, name = 'cef-ui-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
  * frame #0: 0x0000000000000000
    frame #1: 0x0000000104291d98 libgstcef.dylib`cef_string_utf8_to_utf16(src="LETS CRASH", src_len=10, output=0x00006000025189c0) at libcef_dll_dylib.cc:1583:10
    frame #2: 0x00000001041a6f74 libgstcef.dylib`CefStringTraitsUTF16::from_string(data="LETS CRASH", length=10, s=0x00006000025189c0) at cef_string_wrappers.h:269:12
    frame #3: 0x00000001041a6e4c libgstcef.dylib`CefStringBase<CefStringTraitsUTF16>::FromString(this=0x00000001706babe0, data="LETS CRASH", length=10) at cef_string_wrappers.h:684:12
    frame #4: 0x00000001041a6d80 libgstcef.dylib`CefStringBase<CefStringTraitsUTF16>::CefStringBase(this=0x00000001706babe0, src="LETS CRASH", length=0) at cef_string_wrappers.h:385:7
    frame #5: 0x00000001041a620c libgstcef.dylib`CefStringBase<CefStringTraitsUTF16>::CefStringBase(this=0x00000001706babe0, src="LETS CRASH", length=0) at cef_string_wrappers.h:383:38
    frame #6: 0x00000001041ab13c libgstcef.dylib`run_cef(src=0x000000012d80eae0) at gstcefsrc.cc:477:13
    frame #7: 0x00000001007101fc libglib-2.0.0.dylib`g_thread_proxy + 68
    frame #8: 0x0000000188bb6034 libsystem_pthread.dylib`_pthread_start + 136
SteveMcFarlin commented 6 months ago

I thought maybe trying to load the library in gstcefsrc.c might be the issue, but as soon as I touch

// Initialize the macOS sandbox for this helper process.
  CefScopedSandboxContext sandbox_context;

I will get a crash. I think this might be a mem allocator issue? CefString does an allocation, and so does CefScopedSandboxContext. I can do this

CefBrowserSettings browserSettings;

  settings.no_sandbox = !src->sandbox;
  settings.windowless_rendering_enabled = true;
  settings.log_severity = src->log_severity;

which is fine given this is a simple structure on the stack. It has been a while since I have dealt with these types of issues. I guess if I were going to debug this further I would build CEF against my local tool chain.

SteveMcFarlin commented 6 months ago

Closing this as I will not have any more time to tinker with this.

SteveMcFarlin commented 6 months ago

@reinismu I would like to get this working at some point, but I simply do not have the time to dig into it. As I stated above the issue revolves around memory allocation AFAICT. There is a bad access at as you can see. I ran the CEF sample minimal without any issue, so I know CEF works on OS-X and the M series chips. At this point I don't know. I have a habit of closing PR's that I will not work on. However, given minimal amount of traffic here I will reopen in hopes someone will have an aha moment.

reinismu commented 6 months ago

Maybe someone from Centricular will get interested in this as well.

I wonder if bad access is not caused by MacOS security stuff. The last I recall from my try was setting up process metadata

SteveMcFarlin commented 6 months ago

I am compiling CEF locally, so I can at least debug a bit better. I will continue to look into this when I have some free time.

MathieuDuponchelle commented 6 months ago

We had a discussion and we decided to reward 1000$ to someone who can make this plugin work on Apple Silicon MacOS :)

Noted, I will check with our MacOS people :)

reinismu commented 4 months ago

We had a discussion and we decided to reward 1000$ to someone who can make this plugin work on Apple Silicon MacOS :)

Noted, I will check with our MacOS people :)

Did any MacOS people seem interested? :) If price is too low, we can discuss it

MathieuDuponchelle commented 4 months ago

We had a discussion and we decided to reward 1000$ to someone who can make this plugin work on Apple Silicon MacOS :)

Noted, I will check with our MacOS people :)

Did any MacOS people seem interested? :) If price is too low, we can discuss it

Hey, sorry for not following up, I mentioned this in our internal chat but no one picked up on it at the time. Maybe shoot us a mail at contact@centricular.com to get the ball rolling :)

amyspark commented 4 months ago

Hi! @nirbheek told me I could have a look at this. The issue you were facing is that, on macOS, what you're calling is in fact an interposer, lazy-loader dylib: https://github.com/chromiumembedded/cef/blob/00118ddcdbdd6f7a5ed6e131417e6fb222bb33b0/libcef_dll/wrapper/cef_library_loader_mac.mm#L63-L65

Since that library was never initialized in the gstcef side, all CEF calls were rendered null pointer dereferences. I believe these changes should be sufficient to get you going, feel free to include and rebase them : https://github.com/SteveMcFarlin/gstcefsrc/compare/cmake-macosarm64...amyspark:gstcefsrc:cmake-macosarm64

Bear in mind, however, that it seems CEF intends you to consume the library as an Apple framework -- the loader attempts to find the Framework relative to the executable's path, as when deployed into an app bundle.

reinismu commented 4 months ago

Hi! @nirbheek told me I could have a look at this. The issue you were facing is that, on macOS, what you're calling is in fact an interposer, lazy-loader dylib: https://github.com/chromiumembedded/cef/blob/00118ddcdbdd6f7a5ed6e131417e6fb222bb33b0/libcef_dll/wrapper/cef_library_loader_mac.mm#L63-L65

Since that library was never initialized in the gstcef side, all CEF calls were rendered null pointer dereferences. I believe these changes should be sufficient to get you going, feel free to include and rebase them : SteveMcFarlin/gstcefsrc@cmake-macosarm64...amyspark:gstcefsrc:cmake-macosarm64

Bear in mind, however, that it seems CEF intends you to consume the library as an Apple framework -- the loader attempts to find the Framework relative to the executable's path, as when deployed into an app bundle.

Thanks for looking into this :)

Currently trying it out on my M2 Mac Mini. Compiled and set up everything on it.

Sadly for me it segfaults :(

Command

GST_PLUGIN_PATH=Release:$GST_PLUGIN_PATH gst-launch-1.0 -e \
    cefsrc url="https://soundcloud.com/platform/sama" ! \
    video/x-raw, width=1920, height=1080, framerate=60/1 ! \
    cefdemux name=demux ! queue ! videoconvert ! \
    queue max-size-bytes=0 max-size-buffers=0 max-size-time=3000000000 ! x264enc ! queue ! \
    mp4mux name=muxer ! filesink location='test.mp4' \
    audiotestsrc do-timestamp=true is-live=true  volume=0.0 ! audiomixer name=mix ! \
    queue max-size-bytes=0 max-size-buffers=0 max-size-time=3000000000 ! audioconvert ! \
    audiorate ! audioresample ! faac bitrate=128000 ! queue ! muxer. \
    demux. ! queue ! mix.

Logs:

.... setting up pipeline

0:00:00.026971459 30738 0x600000391770 INFO               structure gststructure.c:2957:gst_structure_get_valist: Expected field 'channel-mask' in structure: audio/x-raw, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 2147483647 ];
0:00:00.026979917 30738 0x6000003ac370 INFO              GST_STATES gstelement.c:2825:gst_element_continue_state:<queue5> completed state change to PAUSED
0:00:00.026985000 30738 0x6000003ac370 INFO              GST_STATES gstelement.c:2728:_priv_gst_element_state_changed:<queue5> notifying about state-changed READY to PAUSED (VOID_PENDING pending)
0:00:00.026989375 30738 0x6000003ac370 INFO              GST_STATES gstbin.c:2942:gst_bin_change_state_func:<pipeline0> child 'queue5' changed state to 3(PAUSED) successfully
0:00:00.026992834 30738 0x6000003ac370 INFO              GST_STATES gstbin.c:2484:gst_bin_element_set_state:<demux> current READY pending VOID_PENDING, desired next PAUSED
0:00:00.026996125 30738 0x6000003ac370 INFO              GST_STATES gstelement.c:2825:gst_element_continue_state:<demux> completed state change to PAUSED
0:00:00.026998625 30738 0x6000003ac370 INFO              GST_STATES gstelement.c:2728:_priv_gst_element_state_changed:<demux> notifying about state-changed READY to PAUSED (VOID_PENDING pending)
0:00:00.027001792 30738 0x6000003ac370 INFO              GST_STATES gstbin.c:2942:gst_bin_change_state_func:<pipeline0> child 'demux' changed state to 3(PAUSED) successfully
0:00:00.027004542 30738 0x6000003ac370 INFO              GST_STATES gstbin.c:2484:gst_bin_element_set_state:<capsfilter0> current READY pending VOID_PENDING, desired next PAUSED
0:00:00.027007459 30738 0x6000003ac370 INFO              GST_STATES gstelement.c:2825:gst_element_continue_state:<capsfilter0> completed state change to PAUSED
0:00:00.027009834 30738 0x6000003ac370 INFO              GST_STATES gstelement.c:2728:_priv_gst_element_state_changed:<capsfilter0> notifying about state-changed READY to PAUSED (VOID_PENDING pending)
0:00:00.027012709 30738 0x6000003ac370 INFO              GST_STATES gstbin.c:2942:gst_bin_change_state_func:<pipeline0> child 'capsfilter0' changed state to 3(PAUSED) successfully
0:00:00.027015250 30738 0x6000003ac370 INFO              GST_STATES gstbin.c:2484:gst_bin_element_set_state:<cefsrc0> current READY pending VOID_PENDING, desired next PAUSED
0:00:00.027054750 30738 0x6000003a00a0 WARN              aggregator gstaggregator.c:2283:gst_aggregator_query_latency_unlocked:<mix> Latency query failed
0:00:00.027065417 30738 0x6000003ae620 INFO                  cefsrc gstcefsrc.cc:481:run_cef: Initializing CEF
zsh: segmentation fault  GST_PLUGIN_PATH=Release:$GST_PLUGIN_PATH gst-launch-1.0 -e cefsrc  !     !

I tried running gstcefsubprocess manually and it segfaults as well.

sharehand@SH-MacMini-M2 Release % sudo lldb ./gstcefsubprocess
(lldb) target create "./gstcefsubprocess"
Current executable set to '/Users/sharehand/projects/gstcefsrc/build/Release/gstcefsubprocess' (arm64).
(lldb) run
Process 30799 launched: '/Users/sharehand/projects/gstcefsrc/build/Release/gstcefsubprocess' (arm64)
Process 30799 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
    frame #0: 0x0000000000000000
error: memory read failed for 0x0
Target 0: (gstcefsubprocess) stopped.
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
  * frame #0: 0x0000000000000000
    frame #1: 0x0000000100036f50 gstcefsubprocess`CefExecuteProcess(CefMainArgs const&, scoped_refptr<CefApp>, void*) + 36
    frame #2: 0x000000010000278c gstcefsubprocess`main + 120
    frame #3: 0x000000019547bf28 dyld`start + 2236
(lldb)

Maybe I missed something?

reinismu commented 4 months ago

I investigated a bit further and noticed that my gstcefsubprocess doesn't link to libgstcef.dylib

sharehand@SH-MacMini-M2 Release % otool -L gstcefsubprocess
gstcefsubprocess:
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1336.61.1)
    /System/Library/Frameworks/Cocoa.framework/Versions/A/Cocoa (compatibility version 1.0.0, current version 24.0.0)
    /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit (compatibility version 45.0.0, current version 2487.30.104)
    /usr/lib/libsandbox.1.dylib (compatibility version 1.0.0, current version 1.0.0)
    /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 1600.157.0)

Compared with my linux build folder and realized that cef libs are missing

sharehand@SH-MacMini-M2 Release % ls -l
total 2080
-rwxr-xr-x  1 sharehand  staff  478464 May 21 10:49 gstcefsubprocess
-rwxr-xr-x  1 sharehand  staff  583648 May 21 10:49 libgstcef.dylib

it seems to try to run cef lib functions, but fails to do so

amyspark commented 4 months ago

Hi! That's correct, CEF libraries are missing because on macOS, there are none. What the Spotify tarball ships is instead a framework.

I assume the intention of the developers was to consume it from an app, and so they architected the lazy load to resolve from said path (path_to_executable/../Frameworks/Chromium Embedded Framework.framework/...). It'll fail completely if you try to use it from a standalone executable, are you building such an example?

reinismu commented 4 months ago

Hi! That's correct, CEF libraries are missing because on macOS, there are none. What the Spotify tarball ships is instead a framework.

I assume the intention of the developers was to consume it from an app, and so they architected the lazy load to resolve from said path (path_to_executable/../Frameworks/Chromium Embedded Framework.framework/...). It'll fail completely if you try to use it from a standalone executable, are you building such an example?

Did you manage to run gstcefsrc on your end? If so could you provide example?

reinismu commented 4 months ago

@SteveMcFarlin Hey! Did you manage to run these changes on your end? I feel like something still is missing there or I'm doing something wrong as I didn't get it to work :/

SteveMcFarlin commented 4 months ago

@reinismu I have not yet. I am getting setup to test it either today or tomorrow.

SteveMcFarlin commented 3 months ago

@reinismu I have finally got a system up and running. I installed GStreamer from the downloads. I can not even load the plugin currently.

dyld[53231]: Library not loaded: @rpath/libgstreamer-1.0.0.dylib
  Referenced from: <07B6FD71-26C5-37F7-9B7A-DC944038F101> /Library/Frameworks/GStreamer.framework/Versions/1.0/libexec/gstreamer-1.0/gst-plugin-scanner
  Reason: tried: '/Library/Frameworks/GStreamer.framework/Versions/1.0/libexec/libgstreamer-1.0.0.dylib' (no such file), '/Library/Frameworks/GStreamer.framework/Versions/1.0/libexec/gstreamer-1.0/../libgstreamer-1.0.0.dylib' (no such file), '/Library/Frameworks/GStreamer.framework/Versions/1.0/libexec/lib/libgstreamer-1.0.0.dylib' (no such file), '/Library/Frameworks/GStreamer.framework/Versions/1.0/libexec/gstreamer-1.0/../lib/libgstreamer-1.0.0.dylib' (no such file), '/Library/Frameworks/GStreamer.framework/Versions/1.0/libgstreamer-1.0.0.dylib' (no such file), '/Library/Frameworks/GStreamer.framework/Versions/1.0/libexec/gstreamer-1.0/../../libgstreamer-1.0.0.dylib' (no such file), '/Library/Frameworks/GStreamer.framework/Versions/1.0/libexec/libgstreamer-1.0.0.dylib' (no such file), '/Library/Frameworks/GStreamer.framework/Versions/1.0/libexec/gstreamer-1.0/../libgstreamer-1.0.0.dylib' (no such file), '/Library/Frameworks/GStreamer.framework/Versions/1.0/libexec/lib/libgstreamer-1.0.0.dylib' (no such file), '/Library/Frameworks/GStreamer.framework/Versions/1.0/libexec/gstreamer-1.0/../lib/libgstreamer-1.0.0.dylib' (no such file), '/Library/Frameworks/GStreamer.framework/Versions/1.0/libgstreamer-1.0.0.dylib' (no such file), '/Library/Frameworks/GStreamer.framework/Versions/1.0/libexec/gstreamer-1.0/../../libgstreamer-1.0.0.dylib' (no such file), '/usr/local/lib/libgstreamer-1.0.0.dylib' (no such file), '/usr/lib/libgstreamer-1.0.0.dylib' (no such file, not in dyld cache)

Additionally I get errors related to ../Frameworks/Chromium Embedded Framework.framework/Chromium Embedded Framework. Prior to trying the installers I built from source, and received the same errors. I may try a home-brew installation, but for now I am stuck.

SteveMcFarlin commented 3 months ago

I am now only having issues loading the CEF Framework with the distro from Spotify. I am not used to using those packages, so I am build CEF locally in order to see if I can get something working. I currently have no intention of building an App via the usual methods on MacOS, so I am going to work on that.

SteveMcFarlin commented 3 months ago

@reinismu I had to copy the framework into my gst installation. Now I get a crash. I have a feeling this is due to issues revolving around CEF not being bundled in an app as Amy pointed out.

Setting pipeline to PAUSED ...
Process 54332 stopped
* thread #18, name = 'cef-ui-thread', stop reason = EXC_BREAKPOINT (code=1, subcode=0x147ef4020)
    frame #0: 0x0000000147ef4020 Chromium Embedded Framework`___lldb_unnamed_symbol7480 + 600424
Chromium Embedded Framework`___lldb_unnamed_symbol7480:
->  0x147ef4020 <+600424>: brk    #0
    0x147ef4024 <+600428>: hlt    #0
    0x147ef4028 <+600432>: brk    #0x1
    0x147ef402c <+600436>: mov    w0, #0x2
Target 0: (gst-launch-1.0) stopped.
(lldb) bt
* thread #18, name = 'cef-ui-thread', stop reason = EXC_BREAKPOINT (code=1, subcode=0x147ef4020)
  * frame #0: 0x0000000147ef4020 Chromium Embedded Framework`___lldb_unnamed_symbol7480 + 600424
    frame #1: 0x000000014769171c Chromium Embedded Framework`___lldb_unnamed_symbol7466 + 2518368
    frame #2: 0x0000000147690a68 Chromium Embedded Framework`___lldb_unnamed_symbol7466 + 2515116
    frame #3: 0x000000014459f39c Chromium Embedded Framework`cxxbridge1$rust_vec$u8$set_len + 216008
    frame #4: 0x000000014459f114 Chromium Embedded Framework`cxxbridge1$rust_vec$u8$set_len + 215360
    frame #5: 0x000000014457cd50 Chromium Embedded Framework`cxxbridge1$rust_vec$u8$set_len + 75132
    frame #6: 0x000000014457ca9c Chromium Embedded Framework`cxxbridge1$rust_vec$u8$set_len + 74440
    frame #7: 0x00000001444df0e8 Chromium Embedded Framework`cef_initialize + 312
    frame #8: 0x0000000104025230 libgstcef.dylib`CefInitialize(CefMainArgs const&, CefStructBase<CefSettingsTraits> const&, scoped_refptr<CefApp>, void*) + 184
    frame #9: 0x0000000103fedb60 libgstcef.dylib`run_cef(_GstCefSrc*) + 792
    frame #10: 0x0000000100957c7c libglib-2.0.0.dylib`g_thread_proxy + 68
    frame #11: 0x000000019d73af94 libsystem_pthread.dylib`_pthread_start + 136
SteveMcFarlin commented 3 months ago

Well I give up for now. I spent the day on it. I went so far as to create a console app and link everything properly. Still crashes when cefsrc initializes Cef.

reinismu commented 3 months ago

Well I give up for now. I spent the day on it. I went so far as to create a console app and link everything properly. Still crashes when cefsrc initializes Cef.

Thanks! Currently contracting Centricular (Amy) to try and solve it :) Now I just hope that issue is not too complicated

SteveMcFarlin commented 3 months ago

I am still gong to do a local CEF build the way I do it on linux to see if it is any different. Hopefully this does get fixed. Always wanted it working on OS-X arm64 just for convenience.

amyspark commented 3 months ago

Hi again @SteveMcFarlin @reinismu !

The reason why the update has been so troublesome on macOS is because Chromium's Sandbox V2 goes out of its way to ensure that the framework is loaded from within an app bundle. So far I have discovered the following:

For the first item, I put together an app bundle for gst-launch-1.0 by moving the executable to bin/gst-launch-1.0.app/Contents/MacOS/gst-launch-1.0, symlinking it back to the bin folder, and adding an Info.plist. The complete bundle should look like this: gst-launch-1.0.zip

For the second item, the overrides are in detail here: https://github.com/amyspark/gstcefsrc/commit/9930d07044c56e895e9fa91b154849444787ddf9

For the third item, I started working on that (commit here, but I still need to port the following in the Java bindings: https://github.com/chromiumembedded/java-cef/blob/master/native/util_mac.mm#L70-L73).

I'll keep you posted, you can find what progress I make in this branch.

SteveMcFarlin commented 3 months ago

Great work. Not sure I would have found that.

reinismu commented 3 months ago

Hi @amyspark !

Thanks for your work :)

Tried out your latest branch changes and noticed few issues

1) Couldn't compile it at start

removed as it seemed to not do anything anyway and it worked

-      if (!init_result) {
-        // BAIL OUT, CEF is not loaded.
-        result = GST_STATE_CHANGE_FAILURE;
-        g_thread_join(thread);
-        thread = nullptr;
-      }

2) I'm not sure what you mean by

For the first item, I put together an app bundle for gst-launch-1.0 by moving the executable to bin/gst-launch-1.0.app/Contents/MacOS/gst-launch-1.0, symlinking it back to the bin folder, and adding an Info.plist. The complete bundle should look like this: gst-launch-1.0.zip

I assume that is the reason why it still doesnt work for me

0:00:14.343820209 96241 0x6000003caa30 INFO                  cefsrc gstcefsrc.cc:640:run_cef:<cefsrc0> Initialize2 CEF
warning: Chromium Embedded Framework was compiled with optimization - stepping may behave oddly; variables may not be available.
Process 96241 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BREAKPOINT (code=1, subcode=0x111e57fd8)
    frame #0: 0x0000000111e57fd8 Chromium Embedded Framework`base::apple::(anonymous namespace)::BundleFromPath(base::FilePath const&) [inlined] base::ImmediateCrash() at immediate_crash.h:176:3 [opt]
Target 0: (gst-launch-1.0) stopped.
Process 96241 launched: '/opt/homebrew/bin/gst-launch-1.0' (arm64)
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BREAKPOINT (code=1, subcode=0x111e57fd8)
  * frame #0: 0x0000000111e57fd8 Chromium Embedded Framework`base::apple::(anonymous namespace)::BundleFromPath(base::FilePath const&) [inlined] base::ImmediateCrash() at immediate_crash.h:176:3 [opt]
    frame #1: 0x0000000111e57fd8 Chromium Embedded Framework`base::apple::(anonymous namespace)::BundleFromPath(base::FilePath const&) [inlined] logging::CheckFailure() at check.h:211:3 [opt]
    frame #2: 0x0000000111e57fd8 Chromium Embedded Framework`base::apple::(anonymous namespace)::BundleFromPath(file_path=<unavailable>) at bundle_locations.mm:66:3 [opt]
    frame #3: 0x0000000111e57f38 Chromium Embedded Framework`base::apple::SetOverrideOuterBundlePath(file_path=<unavailable>) at bundle_locations.mm:82:22 [opt]
    frame #4: 0x000000010e69f808 Chromium Embedded Framework`util_mac::BasicStartupComplete() [inlined] util_mac::(anonymous namespace)::OverrideOuterBundlePath() at util_mac.mm:45:3 [opt]
    frame #5: 0x000000010e69f7f0 Chromium Embedded Framework`util_mac::BasicStartupComplete() at util_mac.mm:159:3 [opt]
    frame #6: 0x000000010e6598e4 Chromium Embedded Framework`AlloyMainDelegate::BasicStartupComplete(this=<unavailable>) at alloy_main_delegate.cc:509:3 [opt]
    frame #7: 0x00000001116dd668 Chromium Embedded Framework`content::ContentMainRunnerImpl::Initialize(this=0x00006000023e4a80, params=<unavailable>) at content_main_runner_impl.cc:875:18 [opt]
    frame #8: 0x00000001116dc86c Chromium Embedded Framework`content::ContentMainInitialize(params=<unavailable>, content_main_runner=<unavailable>) at content_main.cc:291:38 [opt]
    frame #9: 0x000000010e5e0a2c Chromium Embedded Framework`CefMainRunner::ContentMainInitialize(this=0x00006000018f0840, args=0x000000016fdfd9b0, windows_sandbox_info=<unavailable>, no_sandbox=<unavailable>) at main_runner.cc:422:10 [opt]
    frame #10: 0x000000010e5e079c Chromium Embedded Framework`CefMainRunner::Initialize(this=0x00006000018f0840, settings=0x0000000132e1c438, application=(ptr_ = 0x0000600000dcefb0), args=0x000000016fdfd9b0, windows_sandbox_info=<unavailable>, initialized=0x0000000132e1c430, context_initialized=base::OnceClosure @ 0x000000016fdfd658) at main_runner.cc:249:7 [opt]
    frame #11: 0x000000010e5b7c08 Chromium Embedded Framework`CefContext::Initialize(this=0x0000000132e1c430, args=0x000000016fdfd9b0, settings=<unavailable>, application=(ptr_ = 0x0000600000dcefb0), windows_sandbox_info=0x0000000000000000) at context.cc:480:22 [opt]
    frame #12: 0x000000010e5b7964 Chromium Embedded Framework`CefInitialize(args=0x000000016fdfd9b0, settings=0x000000016fdfd7e0, application=(ptr_ = 0x0000600000dcefb0), windows_sandbox_info=0x0000000000000000) at context.cc:312:19 [opt]
    frame #13: 0x000000010e524700 Chromium Embedded Framework`cef_initialize(args=<unavailable>, settings=<unavailable>, application=<unavailable>, windows_sandbox_info=0x0000000000000000) at libcef_dll.cc:114:7 [opt]
    frame #14: 0x00000001037113f8 libgstcef.dylib`CefInitialize(CefMainArgs const&, CefStructBase<CefSettingsTraits> const&, scoped_refptr<CefApp>, void*) + 184
    frame #15: 0x00000001036da2c0 libgstcef.dylib`run_cef(_GstCefSrc*) + 1708
    frame #16: 0x000000018d0c4910 libdispatch.dylib`_dispatch_client_callout + 20
    frame #17: 0x000000018d0d2fa8 libdispatch.dylib`_dispatch_main_queue_drain + 984
    frame #18: 0x000000018d0d2bc0 libdispatch.dylib`_dispatch_main_queue_callback_4CF + 44
    frame #19: 0x000000018d394ecc CoreFoundation`__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 16
    frame #20: 0x000000018d3527d0 CoreFoundation`__CFRunLoopRun + 1996
    frame #21: 0x000000018d3519ac CoreFoundation`CFRunLoopRunSpecific + 608
    frame #22: 0x0000000197900448 HIToolbox`RunCurrentEventLoopInMode + 292
    frame #23: 0x0000000197900284 HIToolbox`ReceiveNextEventCommon + 648
    frame #24: 0x00000001978fffdc HIToolbox`_BlockUntilNextEventMatchingListInModeWithFilter + 76
    frame #25: 0x0000000190b2e8a4 AppKit`_DPSNextEvent + 660
    frame #26: 0x0000000191308980 AppKit`-[NSApplication(NSEventRouting) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 716
    frame #27: 0x0000000190b21d50 AppKit`-[NSApplication run] + 476
    frame #28: 0x000000010063b1a8 libgstreamer-1.0.0.dylib`run_main_with_nsapp + 180
    frame #29: 0x000000010063b200 libgstreamer-1.0.0.dylib`gst_macos_main + 36
    frame #30: 0x000000018cef50e0 dyld`start + 2360
amyspark commented 3 months ago

Hey! Yes, that's exactly the reason -- it won't run at all, as it turns out, because Chromium's runtime checks at multiple steps that it is being run from an app bundle. The easiest way to try it out is by converting gst-launch-1.0 to such a bundle. Let me know if you need help with it and I'll attach the steps here.

I should be finishing the branch today, I'll file a PR against @SteveMcFarlin 's repo as soon as I have it ready.

nirbheek commented 3 months ago

I should be finishing the branch today, I'll file a PR against @SteveMcFarlin 's repo as soon as I have it ready.

I've added you as a maintainer @amyspark so you can just push to this PR once you've accepted the invite.

reinismu commented 3 months ago

Some guidance on how to run it as app would be appreciated :) I downloaded your zip and checked it, but wasn't sure what to do next. Not that familiar with MacOS

reinismu commented 3 months ago

Gave it another go and managed to make gst-launch-1.0.app run. It just spent 30 minutes poking every dylib it could find on disk and crashed :/ Could you update readme.md on how to use it in MacOS?

amyspark commented 3 months ago

@reinismu Sure, I'll try to take care of this today.

amyspark commented 3 months ago

@reinismu

It just spent 30 minutes poking every dylib it could find on disk and crashed :/

Was it a RPATH issue (dlopen followed by many not found errors on the console)? I've been working on those, would it be possible for you to check again with the installer package from the latest CI build?

reinismu commented 3 months ago

@reinismu

It just spent 30 minutes poking every dylib it could find on disk and crashed :/

Was it a RPATH issue (dlopen followed by many not found errors on the console)? I've been working on those, would it be possible for you to check again with the installer package from the latest CI build?

I made an MacOS app differently so that's why it didn't work as it should.

I managed to run CefSrc on Mac after following your instructions.

I had to fix BOOL import for compiler to work

gstcefsrc/gstcefnsapplication.h:22:1: error: unknown type name 'BOOL'
BOOL gst_is_main_thread();

improted

#include <objc/objc.h>
#include <stdbool.h>

I will make my own gstreamer native app that will create pipeline in the end. I assume I will need to make it as an MacOS app as well for Cef to work properly

nirbheek commented 3 months ago

@amyspark can we squash some of these commits before merging?

MathieuDuponchelle commented 3 months ago

Just checked, still builds and runs on Linux, annoyingly I can reproduce the choppy audio that Piotr was mentioning in private chats. That's both with this version and main so obviously not a blocker here, but that will require attention eventually :|

I will review further tomorrow but this looks quite ready from a quick look at it :)

amyspark commented 3 months ago

@amyspark can we squash some of these commits before merging?

Sure @nirbheek , I've pushed a cleaned up version. Let me know if it looks OK.

MathieuDuponchelle commented 3 months ago

I have no other remarks, this is ready to merge for me after those are addressed, that's great work @amyspark thanks for tackling that (also @SteveMcFarlin for the initial work), and thank you for the sponsoring @reinismu !

amyspark commented 3 months ago

Working on those nits, I'm marking them as resolved as I go through them in VS Code. I'll push the amended commits once done 👍

amyspark commented 3 months ago

Nits addressed and initialization variables converted (thanks @MathieuDuponchelle for the insight!), I'd need one more look before merging. @sdroege ?

nirbheek commented 3 months ago

If you haven't already @amyspark, I would suggest testing it once last time on macOS before merging, because non-trivial changes were made to the code.

amyspark commented 3 months ago

@nirbheek I did just before pushing, I found another race condition in the event pump (active timers must always be cancelled if the pump is called, irrespective of the plugin's status). Both macOS and Windows launch, run and exit without any issues.

reinismu commented 3 months ago

~Found one issue, but not sure if it is related to changes here or not.~

Build works fine for me on MacOS, but if I try to package it together with Nix I run into issue ld: library not found for -lsandbox

Here is the nix file https://gist.github.com/reinismu/31452372283a7b89715399bd7e763aad

I did some investigation and came to that clang that is installed by Nix only throws this.

Not working command

/nix/store/24ljvc5iwbs01svv9s8zvfcl5qs876kp-clang-wrapper-16.0.6/bin/clang++ -O3 -DNDEBUG -arch arm64 -mmacosx-version-min=10.15 -Wl,-search_paths_first -Wl,-headerpad_max_install_names -Wl,-search_paths_first -Wl,-ObjC -Wl,-pie -Wl,-dead_strip -L/nix/store/wmkr30nbg14vrg08xxvyggwgkixppa3g-gstreamer-1.22.9/lib -L/nix/store/pnafnhig3vz9h0zixvp2gxr5wcywq7kz-glib-2.78.4/lib -L/nix/store/yjzrvf8mppc3yj3qyixkjpvqar0w900k-gst-plugins-base-1.22.9/lib -lgstvideo-1.0 -lgstaudio-1.0 -lgstbase-1.0 -lgstreamer-1.0 -Wl,-rpath,/nix/store/wmkr30nbg14vrg08xxvyggwgkixppa3g-gstreamer-1.22.9/lib -lgobject-2.0 -lglib-2.0 CMakeFiles/gstcefsubprocess.dir/gstcefloader.cc.o CMakeFiles/gstcefsubprocess.dir/gstcefsubprocess.cc.o -o Release/gstcefsubprocess.app/Contents/MacOS/gstcefsubprocess  libcef_dll_wrapper/libcef_dll_wrapper.a -lpthread -framework Cocoa -framework AppKit -lsandbox /tmp/nix-build-gstcefsrc-0.1.0.drv-0/source/third_party/cef/cef_binary_122.1.13+gde5b724+chromium-122.0.6261.130_macosarm64/Release/cef_sandbox.a /nix/store/pnafnhig3vz9h0zixvp2gxr5wcywq7kz-glib-2.78.4/lib/libglib-2.0.dylib -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk -F/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks

if I call it with /Library/Developer/CommandLineTools/usr/bin/c++ and the same arguments it works

I tried both V15 and V16 Clang and they had the same issue

Update:

Adding export LIBRARY_PATH=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/lib:$LIBRARY_PATH for build script solved the issue

MathieuDuponchelle commented 3 months ago

Let's gooo! Thanks again everyone, this is so nice to finally see this solved :)

reinismu commented 3 months ago

@amyspark Was this commit https://github.com/centricular/gstcefsrc/pull/83/commits/1255b317e6058559d05cd56da10924739391b38a related to my nix build issue?

If it was it seems that it still won't build without export LIBRARY_PATH=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/lib:$LIBRARY_PATH

Today was trying to get all my stack building in nix and run into issue :( It seems that it doesn't start the browser and just stucks here https://github.com/centricular/gstcefsrc/blob/master/gstcefsrc.cc#L786

Maybe this is something obvious in your eyes. If not I will just bundle all binaries and distribute it that way :)