/*
 * Copyright (C) 2010 Ole André Vadla Ravnås <oravnas@cisco.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#include "celvideosrc.h"

#include "coremediabuffer.h"

#include <gst/video/video.h>

#define DEFAULT_DEVICE_INDEX  -1
#define DEFAULT_DO_STATS      FALSE

#define QUEUE_READY_LOCK(instance) GST_OBJECT_LOCK (instance)
#define QUEUE_READY_UNLOCK(instance) GST_OBJECT_UNLOCK (instance)
#define QUEUE_READY_WAIT(instance) \
    g_cond_wait (instance->ready_cond, GST_OBJECT_GET_LOCK (instance))
#define QUEUE_READY_NOTIFY(instance) g_cond_signal (instance->ready_cond)

GST_DEBUG_CATEGORY (gst_cel_video_src_debug);
#define GST_CAT_DEFAULT gst_cel_video_src_debug

static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("NV12") ";"
        GST_VIDEO_CAPS_YUV ("YUY2"))
    );

enum
{
  PROP_0,
  PROP_DEVICE_INDEX,
  PROP_DO_STATS,
  PROP_FPS
};

typedef struct
{
  guint index;

  GstVideoFormat video_format;
  guint32 fourcc;
  gint width;
  gint height;
  gint fps_n;
  gint fps_d;
} GstCelVideoFormat;

static gboolean gst_cel_video_src_open_device (GstCelVideoSrc * self);
static void gst_cel_video_src_close_device (GstCelVideoSrc * self);
static void gst_cel_video_src_ensure_device_caps_and_formats
    (GstCelVideoSrc * self);
static void gst_cel_video_src_release_device_caps_and_formats
    (GstCelVideoSrc * self);
static gboolean gst_cel_video_src_select_format (GstCelVideoSrc * self,
    GstCelVideoFormat * format);

static gboolean gst_cel_video_src_parse_stream_format
    (GstCelVideoSrc * self, guint index, CFDictionaryRef stream_format,
    GstCelVideoFormat * format);
static OSStatus gst_cel_video_src_set_stream_property_i32
    (GstCelVideoSrc * self, CFStringRef name, SInt32 value);
static OSStatus gst_cel_video_src_set_stream_property_value
    (GstCelVideoSrc * self, CFStringRef name, CFTypeRef value);

static GstPushSrcClass *parent_class;

GST_BOILERPLATE (GstCelVideoSrc, gst_cel_video_src, GstPushSrc,
    GST_TYPE_PUSH_SRC);

static void
gst_cel_video_src_init (GstCelVideoSrc * self, GstCelVideoSrcClass * gclass)
{
  GstBaseSrc *base_src = GST_BASE_SRC_CAST (self);

  gst_base_src_set_live (base_src, TRUE);
  gst_base_src_set_format (base_src, GST_FORMAT_TIME);

  self->ready_cond = g_cond_new ();
}

static void
gst_cel_video_src_dispose (GObject * object)
{
  G_OBJECT_CLASS (parent_class)->dispose (object);
}

static void
gst_cel_video_src_finalize (GObject * object)
{
  GstCelVideoSrc *self = GST_CEL_VIDEO_SRC_CAST (object);

  g_cond_free (self->ready_cond);

  G_OBJECT_CLASS (parent_class)->finalize (object);
}

static void
gst_cel_video_src_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstCelVideoSrc *self = GST_CEL_VIDEO_SRC_CAST (object);

  switch (prop_id) {
    case PROP_DEVICE_INDEX:
      g_value_set_int (value, self->device_index);
      break;
    case PROP_DO_STATS:
      g_value_set_boolean (value, self->do_stats);
      break;
    case PROP_FPS:
      GST_OBJECT_LOCK (object);
      g_value_set_int (value, self->fps);
      GST_OBJECT_UNLOCK (object);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_cel_video_src_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstCelVideoSrc *self = GST_CEL_VIDEO_SRC_CAST (object);

  switch (prop_id) {
    case PROP_DEVICE_INDEX:
      self->device_index = g_value_get_int (value);
      break;
    case PROP_DO_STATS:
      self->do_stats = g_value_get_boolean (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static GstStateChangeReturn
gst_cel_video_src_change_state (GstElement * element, GstStateChange transition)
{
  GstCelVideoSrc *self = GST_CEL_VIDEO_SRC_CAST (element);
  GstStateChangeReturn ret;

  switch (transition) {
    case GST_STATE_CHANGE_NULL_TO_READY:
      if (!gst_cel_video_src_open_device (self))
        goto open_failed;
      break;
    default:
      break;
  }

  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);

  switch (transition) {
    case GST_STATE_CHANGE_READY_TO_NULL:
      gst_cel_video_src_close_device (self);
      break;
    default:
      break;
  }

  return ret;

  /* ERRORS */
open_failed:
  {
    return GST_STATE_CHANGE_FAILURE;
  }
}

static GstCaps *
gst_cel_video_src_get_caps (GstBaseSrc * basesrc)
{
  GstCelVideoSrc *self = GST_CEL_VIDEO_SRC_CAST (basesrc);
  GstCaps *result;

  if (self->device != NULL) {
    gst_cel_video_src_ensure_device_caps_and_formats (self);

    result = gst_caps_ref (self->device_caps);
  } else {
    result = NULL;
  }

  if (result != NULL) {
    gchar *str;

    str = gst_caps_to_string (result);
    GST_DEBUG_OBJECT (self, "returning: %s", str);
    g_free (str);
  }

  return result;
}

static gboolean
gst_cel_video_src_set_caps (GstBaseSrc * basesrc, GstCaps * caps)
{
  GstCelVideoSrc *self = GST_CEL_VIDEO_SRC_CAST (basesrc);
  GstVideoFormat video_format;
  gint width, height, fps_n, fps_d;
  guint i;
  GstCelVideoFormat *selected_format;

  if (self->device == NULL)
    goto no_device;

  if (!gst_video_format_parse_caps (caps, &video_format, &width, &height))
    goto invalid_format;
  if (!gst_video_parse_caps_framerate (caps, &fps_n, &fps_d))
    goto invalid_format;

  gst_cel_video_src_ensure_device_caps_and_formats (self);

  selected_format = NULL;

  for (i = 0; i != self->device_formats->len; i++) {
    GstCelVideoFormat *format;

    format = &g_array_index (self->device_formats, GstCelVideoFormat, i);
    if (format->video_format == video_format &&
        format->width == width && format->height == height &&
        format->fps_n == fps_n && format->fps_d == fps_d) {
      selected_format = format;
      break;
    }
  }

  if (selected_format == NULL)
    goto invalid_format;

  GST_DEBUG_OBJECT (self, "selecting format %u", selected_format->index);

  if (!gst_cel_video_src_select_format (self, selected_format))
    goto select_failed;

  gst_cel_video_src_release_device_caps_and_formats (self);

  return TRUE;

  /* ERRORS */
no_device:
  {
    GST_ELEMENT_ERROR (self, RESOURCE, FAILED, ("no device"), (NULL));
    return FALSE;
  }
invalid_format:
  {
    GST_ELEMENT_ERROR (self, RESOURCE, FAILED, ("invalid format"), (NULL));
    return FALSE;
  }
select_failed:
  {
    GST_ELEMENT_ERROR (self, RESOURCE, FAILED, ("failed to select format"),
        (NULL));
    return FALSE;
  }
}

static gboolean
gst_cel_video_src_start (GstBaseSrc * basesrc)
{
  GstCelVideoSrc *self = GST_CEL_VIDEO_SRC_CAST (basesrc);

  g_atomic_int_set (&self->is_running, TRUE);
  self->offset = 0;

  self->last_sampling = GST_CLOCK_TIME_NONE;
  self->count = 0;
  self->fps = -1;

  return TRUE;
}

static gboolean
gst_cel_video_src_stop (GstBaseSrc * basesrc)
{
  return TRUE;
}

static gboolean
gst_cel_video_src_query (GstBaseSrc * basesrc, GstQuery * query)
{
  GstCelVideoSrc *self = GST_CEL_VIDEO_SRC_CAST (basesrc);
  gboolean result = FALSE;

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_LATENCY:{
      GstClockTime min_latency, max_latency;

      if (self->device == NULL || !GST_CLOCK_TIME_IS_VALID (self->duration))
        goto beach;

      min_latency = max_latency = self->duration;

      GST_DEBUG_OBJECT (self, "reporting latency of min %" GST_TIME_FORMAT
          " max %" GST_TIME_FORMAT,
          GST_TIME_ARGS (min_latency), GST_TIME_ARGS (max_latency));

      gst_query_set_latency (query, TRUE, min_latency, max_latency);
      result = TRUE;
      break;
    }
    default:
      result = GST_BASE_SRC_CLASS (parent_class)->query (basesrc, query);
      break;
  }

beach:
  return result;
}

static gboolean
gst_cel_video_src_unlock (GstBaseSrc * basesrc)
{
  GstCelVideoSrc *self = GST_CEL_VIDEO_SRC_CAST (basesrc);

  g_atomic_int_set (&self->is_running, FALSE);

  QUEUE_READY_LOCK (self);
  QUEUE_READY_NOTIFY (self);
  QUEUE_READY_UNLOCK (self);

  return TRUE;
}

static gboolean
gst_cel_video_src_unlock_stop (GstBaseSrc * basesrc)
{
  return TRUE;
}

static void
gst_cel_video_src_on_queue_ready (void *triggerRefcon,
    CMBufferQueueTriggerToken triggerToken)
{
  GstCelVideoSrc *self = GST_CEL_VIDEO_SRC_CAST (triggerRefcon);

  QUEUE_READY_LOCK (self);
  self->queue_is_ready = TRUE;
  QUEUE_READY_NOTIFY (self);
  QUEUE_READY_UNLOCK (self);
}

static void
gst_cel_video_src_timestamp_buffer (GstCelVideoSrc * self, GstBuffer * buf)
{
  GstClock *clock;
  GstClockTime ts;

  GST_OBJECT_LOCK (self);
  if ((clock = GST_ELEMENT_CLOCK (self)) != NULL) {
    ts = gst_clock_get_time (clock);

    if (ts > GST_ELEMENT (self)->base_time)
      ts -= GST_ELEMENT (self)->base_time;
    else
      ts = 0;

    if (ts > self->duration)
      ts -= self->duration;
    else
      ts = 0;
  } else {
    ts = GST_CLOCK_TIME_NONE;
  }
  GST_OBJECT_UNLOCK (self);

  GST_BUFFER_OFFSET (buf) = self->offset;
  GST_BUFFER_OFFSET_END (buf) = self->offset + 1;
  GST_BUFFER_TIMESTAMP (buf) = ts;
  GST_BUFFER_DURATION (buf) = self->duration;

  if (self->offset == 0)
    GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);

  self->offset++;
}

static void
gst_cel_video_src_update_statistics (GstCelVideoSrc * self)
{
  GstClock *clock;

  GST_OBJECT_LOCK (self);
  clock = GST_ELEMENT_CLOCK (self);
  if (clock != NULL)
    gst_object_ref (clock);
  GST_OBJECT_UNLOCK (self);

  if (clock != NULL) {
    GstClockTime now = gst_clock_get_time (clock);
    gst_object_unref (clock);

    self->count++;

    if (GST_CLOCK_TIME_IS_VALID (self->last_sampling)) {
      if (now - self->last_sampling >= GST_SECOND) {
        GST_OBJECT_LOCK (self);
        self->fps = self->count;
        GST_OBJECT_UNLOCK (self);

        g_object_notify (G_OBJECT (self), "fps");

        self->last_sampling = now;
        self->count = 0;
      }
    } else {
      self->last_sampling = now;
    }
  }
}

static GstFlowReturn
gst_cel_video_src_create (GstPushSrc * pushsrc, GstBuffer ** buf)
{
  GstCelVideoSrc *self = GST_CEL_VIDEO_SRC_CAST (pushsrc);
  GstCMApi *cm = self->ctx->cm;
  CMSampleBufferRef sbuf;

  sbuf = cm->CMBufferQueueDequeueAndRetain (self->queue);

  while (sbuf == NULL) {
    QUEUE_READY_LOCK (self);
    while (!self->queue_is_ready && g_atomic_int_get (&self->is_running))
      QUEUE_READY_WAIT (self);
    self->queue_is_ready = FALSE;
    QUEUE_READY_UNLOCK (self);

    if (G_UNLIKELY (!g_atomic_int_get (&self->is_running)))
      goto shutting_down;

    sbuf = cm->CMBufferQueueDequeueAndRetain (self->queue);
  }

  if (G_UNLIKELY (!g_atomic_int_get (&self->is_running)))
    goto shutting_down;

  *buf = gst_core_media_buffer_new (self->ctx, sbuf);
  gst_cel_video_src_timestamp_buffer (self, *buf);

  cm->FigSampleBufferRelease (sbuf);

  if (self->do_stats)
    gst_cel_video_src_update_statistics (self);

  return GST_FLOW_OK;

  /* ERRORS */
shutting_down:
  {
    cm->FigSampleBufferRelease (sbuf);
    return GST_FLOW_FLUSHING;
  }
}

static gboolean
gst_cel_video_src_open_device (GstCelVideoSrc * self)
{
  GstCoreMediaCtx *ctx = NULL;
  GError *error = NULL;
  GstCMApi *cm = NULL;
  GstMTApi *mt = NULL;
  GstCelApi *cel = NULL;
  OSStatus status;
  FigCaptureDeviceRef device = NULL;
  FigBaseObjectRef device_base;
  FigBaseVTable *device_vt;
  CFArrayRef stream_array = NULL;
  CFIndex stream_index;
  FigCaptureStreamRef stream = NULL;
  FigBaseObjectRef stream_base;
  FigBaseVTable *stream_vt;
  CMBufferQueueRef queue = NULL;
  CMTime ignored_time;

  ctx = gst_core_media_ctx_new (GST_API_CORE_VIDEO | GST_API_CORE_MEDIA
      | GST_API_MEDIA_TOOLBOX | GST_API_CELESTIAL, &error);
  if (error != NULL)
    goto api_error;
  cm = ctx->cm;
  mt = ctx->mt;
  cel = ctx->cel;

  status = cel->FigCreateCaptureDevicesAndStreamsForPreset (NULL,
      *(cel->kFigRecorderCapturePreset_VideoRecording), NULL,
      &device, &stream, NULL, NULL);
  if (status == kCelError_ResourceBusy)
    goto device_busy;
  else if (status != noErr)
    goto unexpected_error;

  device_base = mt->FigCaptureDeviceGetFigBaseObject (device);
  device_vt = cm->FigBaseObjectGetVTable (device_base);

  status = device_vt->base->CopyProperty (device_base,
      *(mt->kFigCaptureDeviceProperty_StreamArray), NULL,
      (CFTypeRef *) & stream_array);
  if (status != noErr)
    goto unexpected_error;

  if (self->device_index >= 0)
    stream_index = self->device_index;
  else
    stream_index = 0;

  if (stream_index >= CFArrayGetCount (stream_array))
    goto invalid_device_index;

  CFRelease (stream);
  stream = (FigCaptureStreamRef) CFArrayGetValueAtIndex (stream_array,
      stream_index);
  CFRetain (stream);

  stream_base = mt->FigCaptureStreamGetFigBaseObject (stream);
  stream_vt = cm->FigBaseObjectGetVTable (stream_base);

  status = stream_vt->base->CopyProperty (stream_base,
      *(mt->kFigCaptureStreamProperty_BufferQueue), NULL, &queue);
  if (status != noErr)
    goto unexpected_error;

  self->queue_is_ready = FALSE;

  ignored_time = cm->CMTimeMake (1, 1);
  status = cm->CMBufferQueueInstallTrigger (queue,
      gst_cel_video_src_on_queue_ready, self,
      kCMBufferQueueTrigger_WhenDataBecomesReady, ignored_time,
      &self->ready_trigger);
  if (status != noErr)
    goto unexpected_error;

  self->ctx = ctx;

  self->device = device;
  self->device_iface = device_vt->derived;
  self->device_base = device_base;
  self->device_base_iface = device_vt->base;
  self->stream = stream;
  self->stream_iface = stream_vt->derived;
  self->stream_base = stream_base;
  self->stream_base_iface = stream_vt->base;

  self->queue = queue;
  self->duration = GST_CLOCK_TIME_NONE;

  CFRelease (stream_array);

  return TRUE;

  /* ERRORS */
api_error:
  {
    GST_ELEMENT_ERROR (self, RESOURCE, FAILED, ("API error"),
        ("%s", error->message));
    g_clear_error (&error);
    goto any_error;
  }
device_busy:
  {
    GST_ELEMENT_ERROR (self, RESOURCE, BUSY,
        ("device is already in use"), (NULL));
    goto any_error;
  }
invalid_device_index:
  {
    GST_ELEMENT_ERROR (self, RESOURCE, NOT_FOUND,
        ("invalid video capture device index"), (NULL));
    goto any_error;
  }
unexpected_error:
  {
    GST_ELEMENT_ERROR (self, RESOURCE, FAILED,
        ("unexpected error while opening device (%d)", (gint) status), (NULL));
    goto any_error;
  }
any_error:
  {
    if (stream != NULL)
      CFRelease (stream);
    if (stream_array != NULL)
      CFRelease (stream_array);
    if (device != NULL)
      CFRelease (device);

    if (ctx != NULL) {
      cm->FigBufferQueueRelease (queue);
      g_object_unref (ctx);
    }

    return FALSE;
  }
}

static void
gst_cel_video_src_close_device (GstCelVideoSrc * self)
{
  gst_cel_video_src_release_device_caps_and_formats (self);

  self->stream_iface->Stop (self->stream);
  self->stream_base_iface->Finalize (self->stream_base);
  CFRelease (self->stream);
  self->stream = NULL;
  self->stream_iface = NULL;
  self->stream_base = NULL;
  self->stream_base_iface = NULL;

  self->device_base_iface->Finalize (self->device_base);
  CFRelease (self->device);
  self->device = NULL;
  self->device_iface = NULL;
  self->device_base = NULL;
  self->device_base_iface = NULL;

  self->ctx->cm->CMBufferQueueRemoveTrigger (self->queue, self->ready_trigger);
  self->ctx->cm->FigBufferQueueRelease (self->queue);
  self->ready_trigger = NULL;
  self->queue = NULL;

  g_object_unref (self->ctx);
  self->ctx = NULL;
}

static void
gst_cel_video_src_ensure_device_caps_and_formats (GstCelVideoSrc * self)
{
  OSStatus status;
  CFArrayRef stream_formats = NULL;
  CFIndex format_count, i;

  if (self->device_caps != NULL)
    goto already_probed;

  self->device_caps = gst_caps_new_empty ();
  self->device_formats = g_array_new (FALSE, FALSE, sizeof (GstCelVideoFormat));

  status = self->stream_base_iface->CopyProperty (self->stream_base,
      *(self->ctx->mt->kFigCaptureStreamProperty_SupportedFormatsArray),
      NULL, (CFTypeRef *) & stream_formats);
  if (status != noErr)
    goto beach;

  format_count = CFArrayGetCount (stream_formats);
  GST_DEBUG_OBJECT (self, "device supports %d formats", (gint) format_count);

  for (i = 0; i != format_count; i++) {
    CFDictionaryRef sformat;
    GstCelVideoFormat format;

    sformat = CFArrayGetValueAtIndex (stream_formats, i);

    if (gst_cel_video_src_parse_stream_format (self, i, sformat, &format)) {
      gst_caps_append_structure (self->device_caps,
          gst_structure_new ("video/x-raw-yuv",
              "format", GST_TYPE_FOURCC, format.fourcc,
              "width", G_TYPE_INT, format.width,
              "height", G_TYPE_INT, format.height,
              "framerate", GST_TYPE_FRACTION, format.fps_n, format.fps_d,
              "pixel-aspect-ratio", GST_TYPE_FRACTION, 1, 1, NULL));
      g_array_append_val (self->device_formats, format);
    } else {
      GST_WARNING_OBJECT (self, "ignoring unknown format #%d", (gint) i);
    }
  }

  CFRelease (stream_formats);

already_probed:
beach:
  return;
}

static void
gst_cel_video_src_release_device_caps_and_formats (GstCelVideoSrc * self)
{
  if (self->device_caps != NULL) {
    gst_caps_unref (self->device_caps);
    self->device_caps = NULL;
  }

  if (self->device_formats != NULL) {
    g_array_free (self->device_formats, TRUE);
    self->device_formats = NULL;
  }
}

static gboolean
gst_cel_video_src_select_format (GstCelVideoSrc * self,
    GstCelVideoFormat * format)
{
  gboolean result = FALSE;
  GstMTApi *mt = self->ctx->mt;
  GstCelApi *cel = self->ctx->cel;
  OSStatus status;
  SInt32 framerate;

  status = gst_cel_video_src_set_stream_property_i32 (self,
      *(mt->kFigCaptureStreamProperty_FormatIndex), format->index);
  if (status != noErr)
    goto beach;

  framerate = format->fps_n / format->fps_d;

  status = gst_cel_video_src_set_stream_property_i32 (self,
      *(mt->kFigCaptureStreamProperty_MinimumFrameRate), framerate);
  if (status != noErr)
    goto beach;

  status = gst_cel_video_src_set_stream_property_i32 (self,
      *(mt->kFigCaptureStreamProperty_MaximumFrameRate), framerate);
  if (status != noErr)
    goto beach;

  status = gst_cel_video_src_set_stream_property_value (self,
      *(cel->kFigCaptureStreamProperty_ColorRange),
      *(cel->kFigCapturePropertyValue_ColorRangeSDVideo));
  if (status != noErr)
    goto beach;

  status = self->stream_iface->Start (self->stream);
  if (status != noErr)
    goto beach;

  GST_DEBUG_OBJECT (self, "configured format %d (%d x %d @ %d Hz)",
      format->index, format->width, format->height, (gint) framerate);

  self->duration =
      gst_util_uint64_scale (GST_SECOND, format->fps_d, format->fps_n);

  result = TRUE;

beach:
  return result;
}

static gboolean
gst_cel_video_src_parse_stream_format (GstCelVideoSrc * self,
    guint index, CFDictionaryRef stream_format, GstCelVideoFormat * format)
{
  GstCMApi *cm = self->ctx->cm;
  GstMTApi *mt = self->ctx->mt;
  CMFormatDescriptionRef desc;
  CMVideoDimensions dim;
  UInt32 subtype;
  CFNumberRef framerate_value;
  SInt32 fps_n;

  format->index = index;

  desc = CFDictionaryGetValue (stream_format,
      *(mt->kFigSupportedFormat_FormatDescription));

  dim = cm->CMVideoFormatDescriptionGetDimensions (desc);
  format->width = dim.width;
  format->height = dim.height;

  subtype = cm->CMFormatDescriptionGetMediaSubType (desc);

  switch (subtype) {
    case kComponentVideoUnsigned:
      format->video_format = GST_VIDEO_FORMAT_YUY2;
      format->fourcc = GST_MAKE_FOURCC ('Y', 'U', 'Y', '2');
      break;
    case kYUV420vCodecType:
      format->video_format = GST_VIDEO_FORMAT_NV12;
      format->fourcc = GST_MAKE_FOURCC ('N', 'V', '1', '2');
      break;
    default:
      goto unsupported_format;
  }

  framerate_value = CFDictionaryGetValue (stream_format,
      *(mt->kFigSupportedFormat_VideoMaxFrameRate));
  CFNumberGetValue (framerate_value, kCFNumberSInt32Type, &fps_n);
  format->fps_n = fps_n;
  format->fps_d = 1;

  return TRUE;

unsupported_format:
  return FALSE;
}

static OSStatus
gst_cel_video_src_set_stream_property_i32 (GstCelVideoSrc * self,
    CFStringRef name, SInt32 value)
{
  OSStatus status;
  CFNumberRef number;

  number = CFNumberCreate (NULL, kCFNumberSInt32Type, &value);
  status = self->stream_base_iface->SetProperty (self->stream_base, name,
      number);
  CFRelease (number);

  return status;
}

static OSStatus
gst_cel_video_src_set_stream_property_value (GstCelVideoSrc * self,
    CFStringRef name, CFTypeRef value)
{
  return self->stream_base_iface->SetProperty (self->stream_base, name, value);
}

static void
gst_cel_video_src_base_init (gpointer gclass)
{
  GstElementClass *element_class = GST_ELEMENT_CLASS (gclass);

  gst_element_class_set_details_simple (element_class,
      "Video Source (Celestial)", "Source/Video",
      "Reads frames from an iOS Celestial device",
      "Ole André Vadla Ravnås <oravnas@cisco.com>");

  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&src_template));
}

static void
gst_cel_video_src_class_init (GstCelVideoSrcClass * klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
  GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
  GstBaseSrcClass *gstbasesrc_class = GST_BASE_SRC_CLASS (klass);
  GstPushSrcClass *gstpushsrc_class = GST_PUSH_SRC_CLASS (klass);

  gobject_class->dispose = gst_cel_video_src_dispose;
  gobject_class->finalize = gst_cel_video_src_finalize;
  gobject_class->get_property = gst_cel_video_src_get_property;
  gobject_class->set_property = gst_cel_video_src_set_property;

  gstelement_class->change_state = gst_cel_video_src_change_state;

  gstbasesrc_class->get_caps = gst_cel_video_src_get_caps;
  gstbasesrc_class->set_caps = gst_cel_video_src_set_caps;
  gstbasesrc_class->start = gst_cel_video_src_start;
  gstbasesrc_class->stop = gst_cel_video_src_stop;
  gstbasesrc_class->query = gst_cel_video_src_query;
  gstbasesrc_class->unlock = gst_cel_video_src_unlock;
  gstbasesrc_class->unlock_stop = gst_cel_video_src_unlock_stop;

  gstpushsrc_class->create = gst_cel_video_src_create;

  g_object_class_install_property (gobject_class, PROP_DEVICE_INDEX,
      g_param_spec_int ("device-index", "Device Index",
          "The zero-based device index",
          -1, G_MAXINT, DEFAULT_DEVICE_INDEX,
          G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_DO_STATS,
      g_param_spec_boolean ("do-stats", "Enable statistics",
          "Enable logging of statistics", DEFAULT_DO_STATS,
          G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_FPS,
      g_param_spec_int ("fps", "Frames per second",
          "Last measured framerate, if statistics are enabled",
          -1, G_MAXINT, -1, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));

  GST_DEBUG_CATEGORY_INIT (gst_cel_video_src_debug, "celvideosrc",
      0, "iOS Celestial video source");
}
