Exemplo n.º 1
0
/**
 * gst_switch_server_new_record:
 *  @return: TRUE if succeeded.
 *
 *  Start a new recording.
 *  
 */
gboolean
gst_switch_server_new_record (GstSwitchServer * srv)
{
  GstWorkerClass *worker_class;
  gboolean result = FALSE;

  g_return_val_if_fail (GST_IS_RECORDER (srv->recorder), FALSE);

  if (srv->recorder) {
    GST_SWITCH_SERVER_LOCK_RECORDER (srv);
    if (srv->recorder) {
      gst_worker_stop (GST_WORKER (srv->recorder));
      g_object_set (G_OBJECT (srv->recorder),
          "mode", srv->composite->mode,
          "port", srv->composite->encode_sink_port,
          "width", srv->composite->width,
          "height", srv->composite->height, NULL);
      worker_class = GST_WORKER_CLASS (G_OBJECT_GET_CLASS (srv->recorder));
      if (worker_class->reset (GST_WORKER (srv->recorder))) {
        result = gst_worker_start (GST_WORKER (srv->recorder));
      } else {
        ERROR ("failed to reset composite recorder");
      }
    }
    GST_SWITCH_SERVER_UNLOCK_RECORDER (srv);
  }
  return result;
}
Exemplo n.º 2
0
/**
 * gst_composite_end:
 *
 * This is invoked when the composite pipeline is ended.
 */
static void
gst_composite_end (GstComposite * composite)
{
  g_return_if_fail (GST_IS_COMPOSITE (composite));

  gst_worker_stop (composite->scaler);
}
Exemplo n.º 3
0
/**
 * @brief
 * @param ui The GstSwitchUI instance.
 * @param frame
 * @param visual
 * @memberof GstSwitchUI
 */
static GstAudioVisual *
gst_switch_ui_renew_audio_visual (GstSwitchUI * ui, GtkWidget * frame,
    GstAudioVisual * visual)
{
  gulong handle = visual->handle;
  gint port = visual->port;

  visual->renewing = TRUE;
  gst_worker_stop (GST_WORKER (visual));

  visual = gst_switch_ui_new_audio_visual_unsafe (ui, NULL, handle, port);

  g_object_set_data (G_OBJECT (frame), "audio-visual", visual);
  return visual;
}
Exemplo n.º 4
0
/**
 * gst_composite_start_transition:
 *
 * Start the new transtition request, this will set the %transition flag into
 * TRUE.
 */
static void
gst_composite_start_transition (GstComposite * composite)
{
  g_return_if_fail (GST_IS_COMPOSITE (composite));

  GST_COMPOSITE_LOCK_TRANSITION (composite);

  if (gst_composite_ready_for_transition (composite)) {
    composite->transition = gst_worker_stop (GST_WORKER (composite));
    /*
       INFO ("transtion ok=%d, %d, %dx%d", composite->transition,
       composite->mode, composite->width, composite->height);
     */
  }

  GST_COMPOSITE_UNLOCK_TRANSITION (composite);
}
Exemplo n.º 5
0
static void
gst_switch_server_end_case (GstCase *cas, GstSwitchServer *srv)
{
  gint caseport = 0;
  GList *item;

  GST_SWITCH_SERVER_LOCK_CASES (srv);

  switch (cas->type) {
  default:
    srv->cases = g_list_remove (srv->cases, cas);
    INFO ("Removed %s (%p, %d) (%d cases left)", GST_WORKER (cas)->name,
	cas, G_OBJECT (cas)->ref_count,	g_list_length (srv->cases));
    caseport = cas->sink_port;
    g_object_unref (cas);
    break;
  case GST_CASE_INPUT_a:
  case GST_CASE_INPUT_v:
    srv->cases = g_list_remove (srv->cases, cas);
    INFO ("Removed %s %p (%d cases left)", GST_WORKER (cas)->name, cas,
	g_list_length (srv->cases));
    caseport = cas->sink_port;
    g_object_unref (cas);
    for (item = srv->cases; item;) {
      GstCase *c = GST_CASE (item->data);
      if (c->sink_port == caseport) {
	gst_worker_stop (GST_WORKER (c));
	item = g_list_next (item);
	/*
	srv->cases = g_list_remove (srv->cases, c);
	g_object_unref (G_OBJECT (c));
	*/
      } else {
	item = g_list_next (item);
      }
    }
    break;
  }

  GST_SWITCH_SERVER_UNLOCK_CASES (srv);

  if (caseport)
    gst_switch_server_revoke_port (srv, caseport);
}
Exemplo n.º 6
0
/**
 * @brief
 * @param ui The GstSwitchUI instance.
 * @param port The compose port number.
 * @memberof GstSwitchUI
 */
static void
gst_switch_ui_set_compose_port (GstSwitchUI * ui, gint port)
{
  GstElement *overlay = NULL;

  GST_SWITCH_UI_LOCK_COMPOSE (ui);
  if (ui->compose) {
    gst_worker_stop (GST_WORKER (ui->compose));
    g_object_unref (ui->compose);
  }

  ui->compose = gst_switch_ui_new_video_disp (ui, ui->compose_view, port);
  overlay = gst_worker_get_element (GST_WORKER (ui->compose), "overlay");
  if (overlay) {
    g_signal_connect (overlay, "draw",
        G_CALLBACK (gst_switch_ui_compose_draw), ui);
  }
  GST_SWITCH_UI_UNLOCK_COMPOSE (ui);
}
Exemplo n.º 7
0
gboolean
gst_switch_server_switch (GstSwitchServer * srv, gint channel, gint port)
{
  GList *item;
  gboolean result = FALSE;
  GstCase *compose_case, *candidate_case;
  GstCase *work1, *work2;
  GCallback callback = G_CALLBACK (gst_switch_server_end_case);
  gchar *name;

  compose_case = NULL;
  candidate_case = NULL;

  GST_SWITCH_SERVER_LOCK_CASES (srv);

  for (item = srv->cases; item; item = g_list_next (item)) {
    GstCase *cas = GST_CASE (item->data);
    switch (channel) {
    case 'A':
      if (cas->type == GST_CASE_COMPOSITE_A) goto get_target_stream;
      break;      
    case 'B':
      if (cas->type == GST_CASE_COMPOSITE_B) goto get_target_stream;
      break;
    case 'a':
      if (cas->type == GST_CASE_COMPOSITE_a) goto get_target_stream;
      break;
    default:
      WARN ("unknown channel %c", (gchar) channel);
      break;
    get_target_stream:
      if (compose_case == NULL) {
	compose_case = cas;
      }
    }
    switch (cas->type) {
    case GST_CASE_COMPOSITE_A:
    case GST_CASE_COMPOSITE_B:
    case GST_CASE_COMPOSITE_a:
    case GST_CASE_PREVIEW:
      if (cas->sink_port == port) {
	candidate_case = cas;
      }
    default:
      break;
    }
  }

  if (!candidate_case) {
    ERROR ("no stream for port %d (candidate)", port);
    goto end;
  }

  if (!compose_case) {
    ERROR ("no stream for port %d (compose)", port);
    goto end;
  }

  if (candidate_case == compose_case) {
    ERROR ("stream on %d already at %c", port, (gchar) channel);
    goto end;
  }

  INFO ("switching: %s (%d), %s (%d)",
      GST_WORKER (compose_case)->name, compose_case->type,
      GST_WORKER (candidate_case)->name, candidate_case->type);

  if (candidate_case->serve_type != compose_case->serve_type) {
    ERROR ("stream type not matched");
    goto end;
  }

  name = g_strdup (GST_WORKER (compose_case)->name);
  work1 = GST_CASE (g_object_new (GST_TYPE_CASE, "name", name,
	  "type",    compose_case->type,
	  "serve",   compose_case->serve_type,
	  "port",    candidate_case->sink_port,
	  "input",   candidate_case->input,
	  "branch",  candidate_case->branch,
	  NULL));
  g_free (name);

  name = g_strdup (GST_WORKER (candidate_case)->name);
  work2 = GST_CASE (g_object_new (GST_TYPE_CASE, "name", name,
	  "type",    candidate_case->type,
	  "serve",   candidate_case->serve_type,
	  "port",    compose_case->sink_port,
	  "input",   compose_case->input,
	  "branch",  compose_case->branch,
	  NULL));
  g_free (name);

  if (compose_case->serve_type == GST_SERVE_VIDEO_STREAM) {
    g_object_set (work1,
	"awidth",  compose_case->a_width,
	"aheight", compose_case->a_height,
	"bwidth",  compose_case->b_width,
	"bheight", compose_case->b_height,
	NULL);
    g_object_set (work2,
	"awidth",  candidate_case->a_width,
	"aheight", candidate_case->a_height,
	"bwidth",  candidate_case->b_width,
	"bheight", candidate_case->b_height,
	NULL);
  } else {
    g_signal_connect (G_OBJECT (work1), "start-worker",
	G_CALLBACK (gst_switch_server_start_audio), srv);
  }

  compose_case->switching = TRUE;
  candidate_case->switching = TRUE;
  gst_worker_stop (GST_WORKER (compose_case));
  gst_worker_stop (GST_WORKER (candidate_case));

  g_signal_connect (work1, "end-worker", callback, srv);
  g_signal_connect (work2, "end-worker", callback, srv);

  if (!gst_worker_start (GST_WORKER (work1)))
    goto error_start_work;
  if (!gst_worker_start (GST_WORKER (work2)))
    goto error_start_work;

  srv->cases = g_list_append (srv->cases, work1);
  srv->cases = g_list_append (srv->cases, work2);

  result = TRUE;

  INFO ("switched: %s <-> %s",
      GST_WORKER (work1)->name, GST_WORKER (work2)->name);

 end:
  GST_SWITCH_SERVER_UNLOCK_CASES (srv);
  return result;

 error_start_work:
  {
    ERROR ("failed to start works");
    g_object_unref (work1);
    g_object_unref (work2);
    GST_SWITCH_SERVER_UNLOCK_CASES (srv);
    return result;
  }
}
Exemplo n.º 8
0
/**
 * gst_composite_adjust_pip:
 *  @param composite The GstComposite instance
 *  @param x the X position of the PIP
 *  @param y the Y position of the PIP
 *  @param w the width of the PIP
 *  @param h the height of the PIP
 *  @return PIP has been changed succefully 
 *
 *  Change the PIP position and size.
 */
gboolean
gst_composite_adjust_pip (GstComposite * composite, gint x, gint y,
    gint w, gint h)
{
  gboolean result = FALSE;
  GstIterator *iter = NULL;
  GValue value = { 0 };
  GstElement *element = NULL;
  gboolean done = FALSE;

  g_return_val_if_fail (GST_IS_COMPOSITE (composite), FALSE);

  GST_COMPOSITE_LOCK (composite);
  if (composite->adjusting) {
    WARN ("last PIP adjustment request is progressing");
    goto end;
  }

  composite->b_x = x;
  composite->b_y = y;

  if (composite->b_width != w || composite->b_height != h) {
    composite->b_width = w;
    composite->b_height = h;
    composite->adjusting = TRUE;
    gst_worker_stop (GST_WORKER (composite));
    result = TRUE;
    goto end;
  }

  element = gst_worker_get_element (GST_WORKER (composite), "mix");
  iter = gst_element_iterate_sink_pads (element);
  while (iter && !done) {
    switch (gst_iterator_next (iter, &value)) {
      case GST_ITERATOR_OK:
      {
        GstPad *pad = g_value_get_object (&value);
        if (g_strcmp0 (gst_pad_get_name (pad), "sink_1") == 0) {
          g_object_set (pad, "xpos", composite->b_x,
              "ypos", composite->b_y, NULL);
          done = TRUE;
          result = TRUE;
        }
        g_value_reset (&value);
      }
        break;
      case GST_ITERATOR_RESYNC:
        gst_iterator_resync (iter);
        break;
      case GST_ITERATOR_DONE:
        done = TRUE;
        break;
      default:
        /* iterator returned _ERROR or premature end with _OK,
         * mark an error and exit */
        done = TRUE;
        result = FALSE;
        break;
    }
  }

  if (G_IS_VALUE (&value))
    g_value_unset (&value);
  if (iter)
    gst_iterator_free (iter);

  composite->adjusting = FALSE;

  /*
     if (!result) {
     WARN ("failed to adjust PIP: %d, %d, %d, %d", x, y, w, h);
     }
   */

end:
  GST_COMPOSITE_UNLOCK (composite);
  return result;
}