static void gst_mio_video_device_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) { GstMIOVideoDevice *self = GST_MIO_VIDEO_DEVICE (object); switch (prop_id) { case PROP_CONTEXT: g_value_set_pointer (value, self->ctx); break; case PROP_HANDLE: g_value_set_int (value, gst_mio_video_device_get_handle (self)); break; case PROP_UID: g_value_set_string (value, gst_mio_video_device_get_uid (self)); break; case PROP_NAME: g_value_set_string (value, gst_mio_video_device_get_name (self)); break; case PROP_TRANSPORT: g_value_set_uint (value, gst_mio_video_device_get_transport_type (self)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } }
static gboolean gst_mio_video_src_build_capture_graph_for (GstMIOVideoSrc * self, GstMIOVideoDevice * device) { GstMIOApi *mio = self->ctx->mio; const gchar *last_function_name; TundraGraph *graph = NULL; TundraTargetSpec spec = { 0, }; TundraUnitID input_node = -1; gpointer input_info; TundraObjectID device_handle; TundraUnitID sync_node = -1; guint8 is_master; guint sync_direction; TundraUnitID output_node = -1; TundraStatus status; const gint node_id_input = 1; const gint node_id_sync = 22; const gint node_id_output = 16; /* * Graph */ status = mio->TundraGraphCreate (kCFAllocatorDefault, &graph); CHECK_TUNDRA_ERROR ("TundraGraphCreate"); /* * Node: input */ spec.name = kTundraUnitInput; spec.scope = kTundraScopeDAL; spec.vendor = kTundraVendorApple; status = mio->TundraGraphCreateNode (graph, node_id_input, 0, 0, &spec, 0, &input_node); CHECK_TUNDRA_ERROR ("TundraGraphCreateNode(input)"); /* store node info for setting clock provider */ input_info = NULL; status = mio->TundraGraphGetNodeInfo (graph, input_node, 0, 0, 0, 0, &input_info); CHECK_TUNDRA_ERROR ("TundraGraphGetNodeInfo(input)"); /* set device handle */ device_handle = gst_mio_video_device_get_handle (device); status = mio->TundraGraphSetProperty (graph, node_id_input, 0, kTundraInputPropertyDeviceID, 0, 0, &device_handle, sizeof (device_handle)); CHECK_TUNDRA_ERROR ("TundraGraphSetProperty(input, DeviceID)"); /* * Node: sync */ spec.name = kTundraUnitSync; spec.scope = kTundraScopeVSyn; status = mio->TundraGraphCreateNode (graph, node_id_sync, 0, 0, &spec, 0, &sync_node); CHECK_TUNDRA_ERROR ("TundraGraphCreateNode(sync)"); status = mio->TundraGraphSetProperty (graph, node_id_sync, 0, kTundraSyncPropertyClockProvider, 0, 0, &input_info, sizeof (input_info)); CHECK_TUNDRA_ERROR ("TundraGraphSetProperty(sync, ClockProvider)"); is_master = TRUE; status = mio->TundraGraphSetProperty (graph, node_id_sync, 0, kTundraSyncPropertyMasterSynchronizer, 0, 0, &is_master, sizeof (is_master)); CHECK_TUNDRA_ERROR ("TundraGraphSetProperty(sync, MasterSynchronizer)"); sync_direction = 0; status = mio->TundraGraphSetProperty (graph, node_id_sync, 0, kTundraSyncPropertySynchronizationDirection, 0, 0, &sync_direction, sizeof (sync_direction)); CHECK_TUNDRA_ERROR ("TundraGraphSetProperty(sync, SynchronizationDirection)"); /* * Node: output */ spec.name = kTundraUnitOutput; spec.scope = kTundraScope2PRC; status = mio->TundraGraphCreateNode (graph, node_id_output, 0, 0, &spec, 0, &output_node); CHECK_TUNDRA_ERROR ("TundraGraphCreateNode(output)"); status = gst_mio_video_src_configure_output_node (self, graph, node_id_output); CHECK_TUNDRA_ERROR ("TundraGraphSetProperty(output, Delegate)"); /* * Connect the nodes */ status = mio->TundraGraphConnectNodeInput (graph, input_node, 0, sync_node, 0); CHECK_TUNDRA_ERROR ("TundraGraphConnectNodeInput(input, sync)"); status = mio->TundraGraphConnectNodeInput (graph, sync_node, 0, output_node, 0); CHECK_TUNDRA_ERROR ("TundraGraphConnectNodeInput(sync, output)"); self->graph = graph; return TRUE; tundra_error: { GST_ELEMENT_ERROR (self, RESOURCE, FAILED, ("%s failed (status=%d)", last_function_name, (gint) status), (NULL)); goto any_error; } any_error: { mio->TundraGraphRelease (graph); 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; } }