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; } }