/** * gst_switch_server_prepare_composite: * @return TRUE if the composite worker is prepared. * * Preparing the composite worker. */ static gboolean gst_switch_server_prepare_composite (GstSwitchServer * srv, GstCompositeMode mode) { gint port, encode; if (srv->composite) { return TRUE; } port = gst_switch_server_alloc_port (srv); encode = gst_switch_server_alloc_port (srv); INFO ("Compose sink to %d, %d", port, encode); g_assert (srv->composite == NULL); srv->composite = GST_COMPOSITE (g_object_new (GST_TYPE_COMPOSITE, "name", "composite", "port", port, "encode", encode, "mode", mode, NULL)); g_signal_connect (srv->composite, "start-worker", G_CALLBACK (gst_switch_server_worker_start), srv); g_signal_connect (srv->composite, "worker-null", G_CALLBACK (gst_switch_server_worker_null), srv); /* g_signal_connect (srv->composite, "start-output", G_CALLBACK (gst_switch_server_start_output), srv); g_signal_connect (srv->composite, "start-recorder", G_CALLBACK (gst_switch_server_start_recorder), srv); */ g_signal_connect (srv->composite, "end-transition", G_CALLBACK (gst_switch_server_end_transition), srv); GST_SWITCH_SERVER_LOCK_PIP (srv); srv->pip_x = srv->composite->b_x; srv->pip_y = srv->composite->b_y; srv->pip_w = srv->composite->b_width; srv->pip_h = srv->composite->b_height; GST_SWITCH_SERVER_UNLOCK_PIP (srv); if (!gst_worker_start (GST_WORKER (srv->composite))) goto error_start_composite; return TRUE; error_start_composite: { g_object_unref (srv->composite); srv->composite = NULL; return FALSE; } }
static void gst_switch_server_serve (GstSwitchServer *srv, GSocket *client, GstSwitchServeStreamType serve_type) { GSocketInputStreamX *stream = G_SOCKET_INPUT_STREAM (g_object_new ( G_TYPE_SOCKET_INPUT_STREAM, "socket", client, NULL)); GstCaseType type = GST_CASE_UNKNOWN; GstCaseType inputtype = GST_CASE_UNKNOWN; GstCaseType branchtype = GST_CASE_UNKNOWN; gint num_cases = g_list_length (srv->cases); GstCase *input = NULL, *branch = NULL, *workcase = NULL; gchar *name; gint port = 0; GCallback start_callback = G_CALLBACK (gst_switch_server_start_case); GCallback end_callback = G_CALLBACK (gst_switch_server_end_case); GST_SWITCH_SERVER_LOCK_SERVE (srv); GST_SWITCH_SERVER_LOCK_CASES (srv); switch (serve_type) { case GST_SERVE_AUDIO_STREAM: inputtype = GST_CASE_INPUT_a; break; case GST_SERVE_VIDEO_STREAM: inputtype = GST_CASE_INPUT_v; break; default: goto error_unknown_serve_type; } type = gst_switch_server_suggest_case_type (srv, serve_type); switch (type) { case GST_CASE_COMPOSITE_A: branchtype = GST_CASE_BRANCH_A; break; case GST_CASE_COMPOSITE_B: branchtype = GST_CASE_BRANCH_B; break; case GST_CASE_COMPOSITE_a: branchtype = GST_CASE_BRANCH_a; break; case GST_CASE_PREVIEW: branchtype = GST_CASE_BRANCH_p; break; default: goto error_unknown_case_type; } port = gst_switch_server_alloc_port (srv); //INFO ("case-type: %d, %d, %d", type, branchtype, port); name = g_strdup_printf ("input_%d", port); input = GST_CASE (g_object_new (GST_TYPE_CASE, "name", name, "type", inputtype, "port", port, "serve", serve_type, "stream", stream, NULL)); g_object_unref (stream); g_object_unref (client); g_free (name); name = g_strdup_printf ("branch_%d", port); branch = GST_CASE (g_object_new (GST_TYPE_CASE, "name", name, "type", branchtype, "port", port, "serve", serve_type, NULL)); g_free (name); name = g_strdup_printf ("case-%d", num_cases); workcase = GST_CASE (g_object_new (GST_TYPE_CASE, "name", name, "type", type, "port", port, "serve", serve_type, "input", input, "branch", branch, NULL)); g_free (name); srv->cases = g_list_append (srv->cases, input); srv->cases = g_list_append (srv->cases, branch); srv->cases = g_list_append (srv->cases, workcase); GST_SWITCH_SERVER_UNLOCK_CASES (srv); if (serve_type == GST_SERVE_VIDEO_STREAM) { g_object_set (input, "awidth", srv->composite->a_width, "aheight", srv->composite->a_height, "bwidth", srv->composite->b_width, "bheight", srv->composite->b_height, NULL); g_object_set (branch, "awidth", srv->composite->a_width, "aheight", srv->composite->a_height, "bwidth", srv->composite->b_width, "bheight", srv->composite->b_height, NULL); g_object_set (workcase, "awidth", srv->composite->a_width, "aheight", srv->composite->a_height, "bwidth", srv->composite->b_width, "bheight", srv->composite->b_height, NULL); } g_signal_connect (branch, "start-worker", start_callback, srv); g_signal_connect (input, "end-worker", end_callback, srv); g_signal_connect (branch, "end-worker", end_callback, srv); g_signal_connect (workcase, "end-worker", end_callback, srv); if (!gst_worker_start (GST_WORKER (input))) goto error_start_branch; if (!gst_worker_start (GST_WORKER (branch))) goto error_start_branch; if (!gst_worker_start (GST_WORKER (workcase))) goto error_start_workcase; GST_SWITCH_SERVER_UNLOCK_SERVE (srv); return; /* Errors Handling */ error_unknown_serve_type: { ERROR ("unknown serve type %d", serve_type); g_object_unref (stream); g_object_unref (client); GST_SWITCH_SERVER_UNLOCK_CASES (srv); GST_SWITCH_SERVER_UNLOCK_SERVE (srv); return; } error_unknown_case_type: { ERROR ("unknown case type (serve type %d)", serve_type); g_object_unref (stream); g_object_unref (client); GST_SWITCH_SERVER_UNLOCK_CASES (srv); GST_SWITCH_SERVER_UNLOCK_SERVE (srv); return; } error_start_branch: error_start_workcase: { ERROR ("failed serving new client"); GST_SWITCH_SERVER_LOCK_CASES (srv); srv->cases = g_list_remove (srv->cases, branch); srv->cases = g_list_remove (srv->cases, workcase); GST_SWITCH_SERVER_UNLOCK_CASES (srv); g_object_unref (stream); g_object_unref (branch); g_object_unref (workcase); gst_switch_server_revoke_port (srv, port); GST_SWITCH_SERVER_UNLOCK_SERVE (srv); return; } }