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