I have been doing a little bit of research around this issue:

Turns out that Qt is still using the older Carbon windowing framework, which means that the ID I am getting from Qt is actually a HIViewRef.

The "have-ns-view" message contains a value called "nsview", which can be cast to a "NSView*", which is a Cocoa based view (the system used by almost all OSX apps).

According to Apple's dev docs, there are a handful of Carbon functions, which allow one to attach a Cocoa view to a special wrapper, which makes it look like a Carbon view. I have tried this using the following code:

WindowHandle 

CocoaHelper::AttachCocoaViewFromMessage(GstMessage* message, const WindowHandle& handle)

{

    WindowHandle outputHandle;

    

    // Extract the cocoa view from the message:

    NSView* cocoaView = (NSView*)g_value_get_pointer(

        gst_structure_get_value(message->structure, "nsview"));

    

    if (cocoaView == 0)

    {

        MEDIA_LOG_ERROR("Message does not contain a value with name \"nsview\"");

        return outputHandle;

    }

    

    // Create Cocoa wrapper view:

    HIViewRef cocoaWrapperView;

    OSStatus retVal;

        

    retVal = HICocoaViewCreate(cocoaView, 0, &cocoaWrapperView);

    

    [cocoaView release];

    

    if (retVal != 0)

    {

        MEDIA_LOG_ERROR("Unable to create Cocoa wrapper view, return value: ", retVal);

        return outputHandle;

    }


    // Attach view to incoming Carbon view:


    // From Qt sources "qwidget_mac.cpp" confirms that a WId can be

    // safely converted to a HIViewRef on the mac. (see qt_mac_hiview_for line 254)

    HIViewRef renderView = (HIViewRef)handle.GetHandle();


    if ((retVal = HIViewAddSubview(renderView, cocoaWrapperView)) != 0)

    {

        MEDIA_LOG_ERROR("Unable to attach Cocoa wrapper view to render view. "

            " return value: ", retVal);

        return outputHandle;

    }

    

    outputHandle = WindowHandle((HandleType)cocoaWrapperView);

    

    MEDIA_LOG_INFO("Successfully attached Cocoa view ", static_cast<void*>(cocoaView),

        " to Carbon view with handle ", handle,

        ". Handle of view wrapper view is ", outputHandle);


    return outputHandle;

}


The WindowHandle object is just a simple wrapper around the window ID I am getting from Qt (GetHandle() returns the same value as QWidget::winid()).

I am also calling NSApplicationLoad() during startup to ensure I can use Cocoa in my Carbon based app.

When I run my app, I don't see any video, instead I get a lot of the following messages in my debugger:

2008-06-27 11:05:38.106 com.neokast.stream.player.ui.view_TESTCASES[92020:a80b] invalid drawable

2008-06-27 11:05:38.147 com.neokast.stream.player.ui.view_TESTCASES[92020:a80b] *** _NSAutoreleaseNoPool(): Object 0x1af9cb10 of class NSSurface autoreleased with no pool in place - just leaking

Stack: (0x90c9e12f 0x90baaec2 0x92cdef8b 0x92daa15c 0x190b3bca 0x190b2af7 0x31791f2 0x317acf0 0x317b351 0x317b970 0x31f5d86 0x31f657a 0x31890e3 0x31f5d86 0x31f657a 0x18f13fff 0x3212309 0x32f97ec 0x32f76de 0x94ef3c55 0x94ef3b12)

2008-06-27 11:05:38.147 com.neokast.stream.player.ui.view_TESTCASES[92020:a80b] *** _NSAutoreleaseNoPool(): Object 0x1afc2dd0 of class NSCFString autoreleased with no pool in place - just leaking

Stack: (0x90c9e12f 0x90baaec2 0x92ddbc92 0x92daa15c 0x190b3bca 0x190b2af7 0x31791f2 0x317acf0 0x317b351 0x317b970 0x31f5d86 0x31f657a 0x31890e3 0x31f5d86 0x31f657a 0x18f13fff 0x3212309 0x32f97ec 0x32f76de 0x94ef3c55 0x94ef3b12)




I am less concerned about the apparent leakage (I have been experimenting with the NSAutoReleasePool to fix those), I think the main problem is the "invalid drawable" message. I would guess that the frequency of those messages roughly corresponds to the framerate.


I would greatly appreciate any input from more experienced Mac developers. I understand that my situation is further complicated by the fact that I am using Carbon. I will keep digging and post the solution when I find it. It would be great is someone could then take this code and use it for a proper implementation of the GstXOverlay interface for the OSX video sink.

Thanks,

Andreas



On Thu, Jun 26, 2008 at 9:41 AM, Andreas Schuler <andreas@neokast.com> wrote:
Thanks for your detailed response. I have taken a closer look at the source code for osxvideosink and found that it supports an "embed" property (which is FALSE by default).

I can tell that when TRUE it will emit a message called "have-ns-view", where it passes a GstGLView object to the callback. This object is an NSView (part of the Apple Cocoa framework). I have learned that I am supposed to attach that to a NSWindow.

Unfortunately I am pretty new to programming on the Mac. Thus far I have been using OS abstraction libraries such as Qt to avoid dealing with different windowing systems. Qt gives me back a window handle, which turns out to be integer but I have no idea how to retrieve a NSWindow object from that.

So if anyone has done this before on the Mac (with or without Qt) I would greatly appreciate your input.

Thanks,

Andreas


On Wed, Jun 25, 2008 at 5:26 PM, Michael Smith <msmith@xiph.org> wrote:
On Wed, Jun 25, 2008 at 3:16 PM, Andreas Schuler <andreas@neokast.com> wrote:
> Hi all,
>
> I am trying to get an application to run on a Max OSX 10.5.2. I have
> downloaded and built the latest tar balls and everything seems to be running
> fine when I use gst-launch.
>
> >From within my app, which also runs on Windows, I am doing the following to
> set the id of the window I want the video to be rendered on:
>
> - get_bus_set_sync_handler to setup my callback
> - The callback function looks as follows:

That looks good for Win32 and linux. On linux the 'window handle' will
need to be the XID for the window, but that's just a matter of
different platform-specific types, not a big problem.

On OSX, you're presumably using osxvideosink (well, you say you're
using autovideosink, but that'll be selecting osxvideosink
internally).

osxvideosink doesn't implement GstXOverlay, so you can't do this with
it. Because of this it won't ever even emit the prepare-xwindow-id
signal, which is what you're seeing.

osxvideosink has some other interface to set this up, but I don't know
the details of how it works. You may find looking at the output of
"gst-inspect-0.10 osxvideosink" to be helpful - it'll tell you what
signals exist, etc.

If possible, it would be best to make osxvideosink implement the
GstXOverlay interface - that would let people use more common code
across different platforms. Looking into whether that's possible is on
my TODO list, but pretty far down right now - I probably won't get to
it for a month or two. If you manage to do that sooner, that'd be
great - patches would be very welcome.

Mike