예제 #1
0
/**
 * 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;
  }
}
예제 #2
0
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;
  }
}