Blame tests/examples/gl/cocoa/cocoa-videooverlay.m

Packit 0652a1
/*
Packit 0652a1
 * GStreamer
Packit 0652a1
 * Copyright (C) 2009 Julien Isorce <julien.isorce@gmail.com>
Packit 0652a1
 *
Packit 0652a1
 * This library is free software; you can redistribute it and/or
Packit 0652a1
 * modify it under the terms of the GNU Library General Public
Packit 0652a1
 * License as published by the Free Software Foundation; either
Packit 0652a1
 * version 2 of the License, or (at your option) any later version.
Packit 0652a1
 *
Packit 0652a1
 * This library is distributed in the hope that it will be useful,
Packit 0652a1
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 0652a1
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 0652a1
 * Library General Public License for more details.
Packit 0652a1
 *
Packit 0652a1
 * You should have received a copy of the GNU Library General Public
Packit 0652a1
 * License along with this library; if not, write to the
Packit 0652a1
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
Packit 0652a1
 * Boston, MA 02110-1301, USA.
Packit 0652a1
 */
Packit 0652a1
Packit 0652a1
#include <Cocoa/Cocoa.h>
Packit 0652a1
#include <gst/gst.h>
Packit 0652a1
#include <gst/video/videooverlay.h>
Packit 0652a1
Packit 0652a1
#if MAC_OS_X_VERSION_MAX_ALLOWED < 101200
Packit 0652a1
#define NSEventMaskAny                       NSAnyEventMask
Packit 0652a1
#define NSWindowStyleMaskTitled              NSTitledWindowMask
Packit 0652a1
#define NSWindowStyleMaskClosable            NSClosableWindowMask
Packit 0652a1
#define NSWindowStyleMaskResizable           NSResizableWindowMask
Packit 0652a1
#define NSWindowStyleMaskMiniaturizable      NSMiniaturizableWindowMask
Packit 0652a1
#endif
Packit 0652a1
Packit 0652a1
/* ============================================================= */
Packit 0652a1
/*                                                               */
Packit 0652a1
/*                          MainWindow                           */
Packit 0652a1
/*                                                               */
Packit 0652a1
/* ============================================================= */
Packit 0652a1
Packit 0652a1
@interface MainWindow: NSWindow <NSApplicationDelegate> {
Packit 0652a1
  GMainLoop *m_loop;
Packit 0652a1
  GstElement *m_pipeline;
Packit 0652a1
  gboolean m_isClosed;
Packit 0652a1
}
Packit 0652a1
- (id) initWithContentRect:(NSRect) contentRect Loop:(GMainLoop*)loop Pipeline:(GstElement*)pipeline;
Packit 0652a1
- (GMainLoop*) loop;
Packit 0652a1
- (GstElement*) pipeline;
Packit 0652a1
- (gboolean) isClosed;
Packit 0652a1
@end
Packit 0652a1
Packit 0652a1
@implementation MainWindow
Packit 0652a1
Packit 0652a1
- (id) initWithContentRect:(NSRect)contentRect Loop:(GMainLoop*)loop Pipeline:(GstElement*)pipeline
Packit 0652a1
{
Packit 0652a1
  m_loop = loop;
Packit 0652a1
  m_pipeline = pipeline;
Packit 0652a1
  m_isClosed = FALSE;
Packit 0652a1
Packit 0652a1
  self = [super initWithContentRect: contentRect
Packit 0652a1
    styleMask: (NSWindowStyleMaskTitled | NSWindowStyleMaskClosable |
Packit 0652a1
                NSWindowStyleMaskResizable | NSWindowStyleMaskMiniaturizable)
Packit 0652a1
    backing: NSBackingStoreBuffered defer: NO screen: nil];
Packit 0652a1
Packit 0652a1
  [self setReleasedWhenClosed:NO];
Packit 0652a1
  [[NSApplication sharedApplication] setDelegate:self];
Packit 0652a1
Packit 0652a1
  [self setTitle:@"gst-plugins-gl implements videooverlay interface"];
Packit 0652a1
Packit 0652a1
  return self;
Packit 0652a1
}
Packit 0652a1
Packit 0652a1
- (GMainLoop*) loop {
Packit 0652a1
  return m_loop;
Packit 0652a1
}
Packit 0652a1
Packit 0652a1
- (GstElement*) pipeline {
Packit 0652a1
  return m_pipeline;
Packit 0652a1
}
Packit 0652a1
Packit 0652a1
- (gboolean) isClosed {
Packit 0652a1
  return m_isClosed;
Packit 0652a1
}
Packit 0652a1
Packit 0652a1
- (void) customClose {
Packit 0652a1
  m_isClosed = TRUE;
Packit 0652a1
}
Packit 0652a1
Packit 0652a1
- (BOOL) windowShouldClose:(id)sender {
Packit 0652a1
  gst_element_send_event (m_pipeline, gst_event_new_eos ());
Packit 0652a1
  return YES;
Packit 0652a1
}
Packit 0652a1
Packit 0652a1
- (void) applicationDidFinishLaunching: (NSNotification *) not {
Packit 0652a1
  [self makeMainWindow];
Packit 0652a1
  [self center];
Packit 0652a1
  [self orderFront:self];
Packit 0652a1
}
Packit 0652a1
Packit 0652a1
- (BOOL) applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)app {
Packit 0652a1
  return NO;
Packit 0652a1
}
Packit 0652a1
Packit 0652a1
@end
Packit 0652a1
Packit 0652a1
Packit 0652a1
/* ============================================================= */
Packit 0652a1
/*                                                               */
Packit 0652a1
/*                   gstreamer callbacks                         */
Packit 0652a1
/*                                                               */
Packit 0652a1
/* ============================================================= */
Packit 0652a1
Packit 0652a1
Packit 0652a1
static GstBusSyncReply create_window (GstBus* bus, GstMessage* message, MainWindow* window)
Packit 0652a1
{
Packit 0652a1
  // ignore anything but 'prepare-window-handle' element messages
Packit 0652a1
  if (GST_MESSAGE_TYPE (message) != GST_MESSAGE_ELEMENT)
Packit 0652a1
    return GST_BUS_PASS;
Packit 0652a1
Packit 0652a1
  if (!gst_is_video_overlay_prepare_window_handle_message (message))
Packit 0652a1
    return GST_BUS_PASS;
Packit 0652a1
Packit 0652a1
  g_print ("setting window handle %lud\n", (gulong) window);
Packit 0652a1
Packit 0652a1
  gst_video_overlay_set_window_handle (GST_VIDEO_OVERLAY (GST_MESSAGE_SRC (message)), (guintptr) [window contentView]);
Packit 0652a1
Packit 0652a1
  gst_message_unref (message);
Packit 0652a1
Packit 0652a1
  return GST_BUS_DROP;
Packit 0652a1
}
Packit 0652a1
Packit 0652a1
Packit 0652a1
static void end_stream_cb(GstBus* bus, GstMessage* message, MainWindow* window)
Packit 0652a1
{
Packit 0652a1
  g_print ("end of stream\n");
Packit 0652a1
Packit 0652a1
  gst_element_set_state ([window pipeline], GST_STATE_NULL);
Packit 0652a1
  gst_object_unref ([window pipeline]);
Packit 0652a1
  g_main_loop_quit ([window loop]);
Packit 0652a1
Packit 0652a1
  [window performSelectorOnMainThread:@selector(customClose) withObject:nil waitUntilDone:YES];
Packit 0652a1
}
Packit 0652a1
Packit 0652a1
static gpointer thread_func (MainWindow* window)
Packit 0652a1
{
Packit 0652a1
  g_main_loop_run ([window loop]);
Packit 0652a1
Packit 0652a1
  return NULL;
Packit 0652a1
}
Packit 0652a1
Packit 0652a1
Packit 0652a1
/* ============================================================= */
Packit 0652a1
/*                                                               */
Packit 0652a1
/*                         application                           */
Packit 0652a1
/*                                                               */
Packit 0652a1
/* ============================================================= */
Packit 0652a1
Packit 0652a1
int main(int argc, char **argv)
Packit 0652a1
{
Packit 0652a1
	int width = 640;
Packit 0652a1
  int height = 480;
Packit 0652a1
Packit 0652a1
  GMainLoop *loop = NULL;
Packit 0652a1
  GstElement *pipeline = NULL;
Packit 0652a1
Packit 0652a1
  GstElement *videosrc  = NULL;
Packit 0652a1
  GstElement *videosink = NULL;
Packit 0652a1
  GstCaps *caps=NULL;
Packit 0652a1
  gboolean ok=FALSE;
Packit 0652a1
  GstBus *bus=NULL;
Packit 0652a1
  GThread *loop_thread=NULL;
Packit 0652a1
  NSRect rect;
Packit 0652a1
  MainWindow *window=nil;
Packit 0652a1
Packit 0652a1
  [NSApplication sharedApplication];
Packit 0652a1
Packit 0652a1
  g_print("app created\n");
Packit 0652a1
Packit 0652a1
  gst_init (&argc, &argv);
Packit 0652a1
Packit 0652a1
  loop = g_main_loop_new (NULL, FALSE);
Packit 0652a1
  pipeline = gst_pipeline_new ("pipeline");
Packit 0652a1
Packit 0652a1
  videosrc  = gst_element_factory_make ("videotestsrc", "videotestsrc");
Packit 0652a1
  videosink = gst_element_factory_make ("glimagesink", "glimagesink");
Packit 0652a1
Packit 0652a1
  g_object_set(G_OBJECT(videosrc), "num-buffers", 500, NULL);
Packit 0652a1
Packit 0652a1
  gst_bin_add_many (GST_BIN (pipeline), videosrc, videosink, NULL);
Packit 0652a1
Packit 0652a1
  caps = gst_caps_new_simple("video/x-raw",
Packit 0652a1
    "width", G_TYPE_INT, width,
Packit 0652a1
    "height", G_TYPE_INT, height,
Packit 0652a1
    "framerate", GST_TYPE_FRACTION, 25, 1,
Packit 0652a1
    "format", G_TYPE_STRING, "I420",
Packit 0652a1
    NULL);
Packit 0652a1
Packit 0652a1
  ok = gst_element_link_filtered(videosrc, videosink, caps);
Packit 0652a1
  gst_caps_unref(caps);
Packit 0652a1
  if (!ok)
Packit 0652a1
    g_warning("could not link videosrc to videosink\n");
Packit 0652a1
Packit 0652a1
  rect.origin.x = 0; rect.origin.y = 0;
Packit 0652a1
  rect.size.width = width; rect.size.height = height;
Packit 0652a1
Packit 0652a1
  window = [[MainWindow alloc] initWithContentRect:rect Loop:loop Pipeline:pipeline];
Packit 0652a1
Packit 0652a1
  bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
Packit 0652a1
  gst_bus_add_signal_watch (bus);
Packit 0652a1
  /* NOTE: window is not bridge_retained because its lifetime is just this function */
Packit 0652a1
  g_signal_connect(bus, "message::error", G_CALLBACK(end_stream_cb), (__bridge gpointer)window);
Packit 0652a1
  g_signal_connect(bus, "message::warning", G_CALLBACK(end_stream_cb), (__bridge gpointer)window);
Packit 0652a1
  g_signal_connect(bus, "message::eos", G_CALLBACK(end_stream_cb), (__bridge gpointer)window);
Packit 0652a1
  gst_bus_set_sync_handler (bus, (GstBusSyncHandler) create_window, (__bridge gpointer)window, NULL);
Packit 0652a1
  gst_object_unref (bus);
Packit 0652a1
Packit 0652a1
  loop_thread = g_thread_new (NULL,
Packit 0652a1
      (GThreadFunc) thread_func, (__bridge gpointer)window);
Packit 0652a1
Packit 0652a1
  gst_element_set_state (pipeline, GST_STATE_PLAYING);
Packit 0652a1
Packit 0652a1
  [window orderFront:window];
Packit 0652a1
Packit 0652a1
  while (![window isClosed]) {
Packit 0652a1
    NSEvent *event = [NSApp nextEventMatchingMask:NSEventMaskAny
Packit 0652a1
      untilDate:[NSDate dateWithTimeIntervalSinceNow:1]
Packit 0652a1
      inMode:NSDefaultRunLoopMode dequeue:YES];
Packit 0652a1
    if (event)
Packit 0652a1
      [NSApp sendEvent:event];
Packit 0652a1
  }
Packit 0652a1
Packit 0652a1
  g_thread_join (loop_thread);
Packit 0652a1
Packit 0652a1
  return 0;
Packit 0652a1
}