Example #1
0
static GstStateChangeReturn
gst_vtenc_change_state (GstElement * element, GstStateChange transition)
{
  GstVTEnc *self = GST_VTENC_CAST (element);
  GError *error = NULL;
  GstStateChangeReturn ret;

  if (transition == GST_STATE_CHANGE_NULL_TO_READY) {
    self->ctx = gst_core_media_ctx_new (GST_API_CORE_VIDEO | GST_API_CORE_MEDIA
        | GST_API_VIDEO_TOOLBOX, &error);
    if (error != NULL)
      goto api_error;

    self->cur_outbufs = g_ptr_array_new ();
  }

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

  if (transition == GST_STATE_CHANGE_READY_TO_NULL) {
    GST_OBJECT_LOCK (self);

    gst_vtenc_destroy_session (self, &self->session);

    if (self->options != NULL) {
      CFRelease (self->options);
      self->options = NULL;
    }

    self->negotiated_width = self->negotiated_height = 0;
    self->negotiated_fps_n = self->negotiated_fps_d = 0;

    gst_vtenc_clear_cached_caps_downstream (self);

    GST_OBJECT_UNLOCK (self);

    g_ptr_array_free (self->cur_outbufs, TRUE);
    self->cur_outbufs = NULL;

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

  return ret;

api_error:
  {
    GST_ELEMENT_ERROR (self, RESOURCE, FAILED, ("API error"),
        ("%s", error->message));
    g_clear_error (&error);
    return GST_STATE_CHANGE_FAILURE;
  }
}
Example #2
0
static GstStateChangeReturn
gst_vtdec_change_state (GstElement * element, GstStateChange transition)
{
  GstVTDec *self = GST_VTDEC_CAST (element);
  GError *error = NULL;
  GstStateChangeReturn ret;

  if (transition == GST_STATE_CHANGE_NULL_TO_READY) {
    self->ctx = gst_core_media_ctx_new (GST_API_CORE_VIDEO | GST_API_CORE_MEDIA
        | GST_API_VIDEO_TOOLBOX, &error);
    if (error != NULL)
      goto api_error;

    self->cur_outbufs = g_ptr_array_new ();
  }

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

  if (transition == GST_STATE_CHANGE_READY_TO_NULL) {
    gst_vtdec_destroy_session (self, &self->session);

    self->ctx->cm->FigFormatDescriptionRelease (self->fmt_desc);
    self->fmt_desc = NULL;

    gst_video_info_init (&self->vinfo);

    g_ptr_array_free (self->cur_outbufs, TRUE);
    self->cur_outbufs = NULL;

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

  return ret;

api_error:
  {
    GST_ELEMENT_ERROR (self, RESOURCE, FAILED, ("API error"),
        ("%s", error->message));
    g_clear_error (&error);
    return GST_STATE_CHANGE_FAILURE;
  }
}
Example #3
0
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;
  }
}
Example #4
0
static gboolean
gst_mio_video_src_open_device (GstMIOVideoSrc * self)
{
  GError *error = NULL;
  GList *devices = NULL, *walk;
  guint device_idx;

  self->ctx = gst_core_media_ctx_new (GST_API_CORE_VIDEO | GST_API_CORE_MEDIA
      | GST_API_MIO, &error);
  if (error != NULL)
    goto api_error;

  devices = gst_mio_video_device_list_create (self->ctx);
  if (devices == NULL)
    goto no_devices;

  for (walk = devices, device_idx = 0; walk != NULL; walk = walk->next) {
    GstMIOVideoDevice *device = walk->data;
    gboolean match;

    if (self->device_uid != NULL) {
      match = g_ascii_strcasecmp (gst_mio_video_device_get_uid (device),
          self->device_uid) == 0;
    } else if (self->device_name != NULL) {
      match = g_ascii_strcasecmp (gst_mio_video_device_get_name (device),
          self->device_name) == 0;
    } else if (self->device_index >= 0) {
      match = device_idx == self->device_index;
    } else {
      match = TRUE;             /* pick the first entry */
    }

    if (self->device != NULL)
      match = FALSE;

    GST_DEBUG_OBJECT (self, "%c device[%u] = handle: %d name: '%s' uid: '%s'",
        (match) ? '*' : '-', device_idx,
        gst_mio_video_device_get_handle (device),
        gst_mio_video_device_get_name (device),
        gst_mio_video_device_get_uid (device));

    /*gst_mio_video_device_print_debug_info (device); */

    if (match)
      self->device = g_object_ref (device);

    device_idx++;
  }

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

  if (!gst_mio_video_device_open (self->device))
    goto device_busy_or_gone;

  gst_mio_video_device_list_destroy (devices);
  return TRUE;

  /* ERRORS */
api_error:
  {
    GST_ELEMENT_ERROR (self, RESOURCE, FAILED, ("API error"),
        ("%s", error->message));
    g_clear_error (&error);
    goto any_error;
  }
no_devices:
  {
    GST_ELEMENT_ERROR (self, RESOURCE, NOT_FOUND,
        ("no video capture devices found"), (NULL));
    goto any_error;
  }
no_such_device:
  {
    GST_ELEMENT_ERROR (self, RESOURCE, NOT_FOUND,
        ("specified video capture device not found"), (NULL));
    goto any_error;
  }
device_busy_or_gone:
  {
    GST_ELEMENT_ERROR (self, RESOURCE, BUSY,
        ("failed to start capture (device already in use or gone)"), (NULL));
    goto any_error;
  }
any_error:
  {
    if (devices != NULL) {
      gst_mio_video_device_list_destroy (devices);
    }
    if (self->ctx != NULL) {
      g_object_unref (self->ctx);
      self->ctx = NULL;
    }
    return FALSE;
  }
}
Example #5
0
static GValueArray *
gst_mio_video_src_probe_get_values (GstPropertyProbe * probe, guint prop_id,
    const GParamSpec * pspec)
{
  GValueArray *values;
  GstCoreMediaCtx *ctx = NULL;
  GError *error = NULL;
  GList *devices = NULL, *walk;
  guint device_idx;

  values = g_value_array_new (3);

  ctx = gst_core_media_ctx_new (GST_MIO_REQUIRED_APIS, &error);
  if (error != NULL)
    goto beach;

  devices = gst_mio_video_device_list_create (ctx);
  if (devices == NULL)
    goto beach;

  for (walk = devices, device_idx = 0; walk != NULL; walk = walk->next) {
    GstMIOVideoDevice *device = walk->data;
    GValue value = { 0, };

    switch (prop_id) {
      case PROP_DEVICE_UID:
      case PROP_DEVICE_NAME:
      {
        const gchar *str;

        if (prop_id == PROP_DEVICE_UID)
          str = gst_mio_video_device_get_uid (device);
        else
          str = gst_mio_video_device_get_name (device);

        g_value_init (&value, G_TYPE_STRING);
        g_value_set_string (&value, str);

        break;
      }
      case PROP_DEVICE_INDEX:
      {
        g_value_init (&value, G_TYPE_INT);
        g_value_set_int (&value, device_idx);

        break;
      }
      default:
        G_OBJECT_WARN_INVALID_PROPERTY_ID (probe, prop_id, pspec);
        goto beach;
    }

    g_value_array_append (values, &value);
    g_value_unset (&value);

    device_idx++;
  }

beach:
  if (devices != NULL)
    gst_mio_video_device_list_destroy (devices);
  if (ctx != NULL)
    g_object_unref (ctx);
  g_clear_error (&error);

  return values;
}