Example #1
0
static void
test_prepare_reusable (GstRTSPThreadPool * pool, const gchar * launch_line)
{
  GstRTSPMediaFactory *factory;
  GstRTSPMedia *media;
  GstRTSPUrl *url;
  GstRTSPThread *thread;

  factory = gst_rtsp_media_factory_new ();
  fail_if (gst_rtsp_media_factory_is_shared (factory));
  fail_unless (gst_rtsp_url_parse ("rtsp://localhost:8554/test",
          &url) == GST_RTSP_OK);

  gst_rtsp_media_factory_set_launch (factory, launch_line);

  media = gst_rtsp_media_factory_construct (factory, url);
  fail_unless (GST_IS_RTSP_MEDIA (media));
  fail_unless (gst_rtsp_media_n_streams (media) == 1);

  g_object_set (G_OBJECT (media), "reusable", TRUE, NULL);

  thread = gst_rtsp_thread_pool_get_thread (pool,
      GST_RTSP_THREAD_TYPE_MEDIA, NULL);
  fail_unless (gst_rtsp_media_prepare (media, thread));
  fail_unless (gst_rtsp_media_unprepare (media));
  fail_unless (gst_rtsp_media_n_streams (media) == 1);

  thread = gst_rtsp_thread_pool_get_thread (pool,
      GST_RTSP_THREAD_TYPE_MEDIA, NULL);
  fail_unless (gst_rtsp_media_prepare (media, thread));
  fail_unless (gst_rtsp_media_unprepare (media));

  g_object_unref (media);
  gst_rtsp_url_free (url);
  g_object_unref (factory);
}
Example #2
0
int
main(int argc, char **argv)
{
  GMainLoop *loop;
  GstRTSPServer *server;
  GstRTSPMediaMapping *mapping;
  GstRTSPCamMediaFactory *factory;
  GstRTSPUrl *local_url;
  GOptionContext *ctx;
  GOptionGroup *gst_group;
  gboolean res;
  GError *error = NULL;

  g_type_init ();
  g_thread_init (NULL);

  ctx = g_option_context_new ("rtsp://host:port/path");
  g_option_context_add_main_entries (ctx, option_entries, NULL);
  gst_group = gst_init_get_option_group ();
  g_option_context_add_group (ctx, gst_group);
  res = g_option_context_parse (ctx, &argc, &argv, &error);
  g_option_context_free (ctx);

  gst_init (&argc, &argv);

  if (!res) {
    g_printerr ("command line error: %s\n", error->message);
    g_error_free (error);

    return 1;
  }

  if (gst_rtsp_url_parse (argc != 2 ? "rtsp://127.0.0.1:8554/test" : argv[1], &local_url) != GST_RTSP_OK) {
    g_printerr ("invalid rtsp url\n");

    return 1;
  }

  loop = g_main_loop_new (NULL, FALSE);

  server = gst_rtsp_server_new ();

  factory = gst_rtsp_cam_media_factory_new ();
  g_object_set (factory, "video-device", video_device,
      "video", !no_video,
      "video-width", video_width,
      "video-height", video_height,
      "video-codec", video_codec,
      "video-framerate", fps_n, fps_d,
      "audio", !no_audio,
      "audio-device", audio_device,
      "audio-codec", audio_codec,
      NULL);

  gst_rtsp_media_factory_set_shared (GST_RTSP_MEDIA_FACTORY (factory), TRUE);
  mapping = gst_rtsp_server_get_media_mapping (server);
  gst_rtsp_media_mapping_add_factory (mapping, local_url->abspath,
      GST_RTSP_MEDIA_FACTORY (factory));
  g_object_unref (mapping);

  gst_rtsp_url_free (local_url);

  gst_rtsp_server_attach (server, NULL);

  g_timeout_add_seconds (5, (GSourceFunc) timeout, server);
  /* start serving */
  g_main_loop_run (loop);

  return 0;
}
Example #3
0
/**
 * gst_rtsp_url_parse:
 * @urlstr: the url string to parse
 * @url: (out): location to hold the result.
 *
 * Parse the RTSP @urlstr into a newly allocated #GstRTSPUrl. Free after usage
 * with gst_rtsp_url_free().
 *
 * Returns: a #GstRTSPResult.
 */
GstRTSPResult
gst_rtsp_url_parse (const gchar * urlstr, GstRTSPUrl ** url)
{
  GstRTSPUrl *res;
  gchar *p, *delim, *at, *col;
  gchar *host_end = NULL;
  guint i;

  g_return_val_if_fail (urlstr != NULL, GST_RTSP_EINVAL);
  g_return_val_if_fail (url != NULL, GST_RTSP_EINVAL);

  res = g_new0 (GstRTSPUrl, 1);

  p = (gchar *) urlstr;

  col = strstr (p, "://");
  if (col == NULL)
    goto invalid;

  for (i = 0; i < G_N_ELEMENTS (rtsp_schemes_map); i++) {
    if (g_ascii_strncasecmp (rtsp_schemes_map[i].scheme, p, col - p) == 0) {
      res->transports = rtsp_schemes_map[i].transports;
      p = col + 3;
      break;
    }
  }

  if (res->transports == GST_RTSP_LOWER_TRANS_UNKNOWN)
    goto invalid;

  delim = strpbrk (p, "/?");
  at = strchr (p, '@');

  if (at && delim && at > delim)
    at = NULL;

  if (at) {
    col = strchr (p, ':');

    /* must have a ':' and it must be before the '@' */
    if (col == NULL || col > at)
      goto invalid;

    res->user = g_uri_unescape_segment (p, col, NULL);
    col++;
    res->passwd = g_uri_unescape_segment (col, at, NULL);

    /* move to host */
    p = at + 1;
  }

  if (*p == '[') {
    res->family = GST_RTSP_FAM_INET6;

    /* we have an IPv6 address in the URL, find the ending ] which must be
     * before any delimiter */
    host_end = strchr (++p, ']');
    if (!host_end || (delim && host_end >= delim))
      goto invalid;

    /* a port specifier must follow the address immediately */
    col = host_end[1] == ':' ? host_end + 1 : NULL;
  } else {
    res->family = GST_RTSP_FAM_INET;

    col = strchr (p, ':');

    /* we have a ':' and a delimiter but the ':' is after the delimiter, it's
     * not really part of the hostname */
    if (col && delim && col >= delim)
      col = NULL;

    host_end = col ? col : delim;
  }

  if (!host_end)
    res->host = g_strdup (p);
  else {
    res->host = g_strndup (p, host_end - p);

    if (col) {
      res->port = strtoul (col + 1, NULL, 10);
    } else {
      /* no port specified, set to 0. gst_rtsp_url_get_port() will return the
       * default port */
      res->port = 0;
    }
  }
  p = delim;

  if (p && *p == '/') {
    delim = strchr (p, '?');
    if (!delim)
      res->abspath = g_strdup (p);
    else
      res->abspath = g_strndup (p, delim - p);
    p = delim;
  } else {
    /* IQinVision IQeye 1080p fails if a path '/' is provided
     * and RTSP does not mandate that a non-zero-length path
     * must be used */
    res->abspath = g_strdup ("");
  }

  if (p && *p == '?')
    res->query = g_strdup (p + 1);

  *url = res;

  return GST_RTSP_OK;

  /* ERRORS */
invalid:
  {
    gst_rtsp_url_free (res);
    return GST_RTSP_EINVAL;
  }
}
Example #4
0
/**
 * gst_rtsp_url_parse:
 * @urlstr: the url string to parse
 * @url: location to hold the result.
 *
 * Parse the RTSP @urlstr into a newly allocated #GstRTSPUrl. Free after usage
 * with gst_rtsp_url_free().
 *
 * Returns: a #GstRTSPResult.
 */
GstRTSPResult
gst_rtsp_url_parse (const gchar * urlstr, GstRTSPUrl ** url)
{
  GstRTSPUrl *res;
  gchar *p, *delim, *at, *col;

  g_return_val_if_fail (urlstr != NULL, GST_RTSP_EINVAL);
  g_return_val_if_fail (url != NULL, GST_RTSP_EINVAL);

  res = g_new0 (GstRTSPUrl, 1);

  p = (gchar *) urlstr;
  if (g_str_has_prefix (p, RTSP_PROTO)) {
    res->transports =
        GST_RTSP_LOWER_TRANS_TCP | GST_RTSP_LOWER_TRANS_UDP |
        GST_RTSP_LOWER_TRANS_UDP_MCAST;
    p += RTSP_PROTO_LEN;
  } else if (g_str_has_prefix (p, RTSPU_PROTO)) {
    res->transports = GST_RTSP_LOWER_TRANS_UDP | GST_RTSP_LOWER_TRANS_UDP_MCAST;
    p += RTSPU_PROTO_LEN;
  } else if (g_str_has_prefix (p, RTSPT_PROTO)) {
    res->transports = GST_RTSP_LOWER_TRANS_TCP;
    p += RTSPT_PROTO_LEN;
  } else
    goto invalid;

  delim = strpbrk (p, "/?");
  at = strchr (p, '@');

  if (at && delim && at > delim)
    at = NULL;

  if (at) {
    col = strchr (p, ':');

    /* must have a ':' and it must be before the '@' */
    if (col == NULL || col > at)
      goto invalid;

    res->user = g_strndup (p, col - p);
    col++;
    res->passwd = g_strndup (col, at - col);

    /* move to host */
    p = at + 1;
  }

  col = strchr (p, ':');
  /* we have a ':' and a delimiter but the ':' is after the delimiter, it's
   * not really part of the hostname */
  if (col && delim && col >= delim)
    col = NULL;

  if (col) {
    res->host = g_strndup (p, col - p);
    p = col + 1;
    res->port = strtoul (p, (char **) &p, 10);
    if (delim)
      p = delim;
  } else {
    /* no port specified, set to 0. _get_port() will return the default port. */
    res->port = 0;
    if (!delim) {
      res->host = g_strdup (p);
      p = NULL;
    } else {
      res->host = g_strndup (p, delim - p);
      p = delim;
    }
  }

  if (p && *p == '/') {
    delim = strchr (p, '?');
    if (!delim) {
      res->abspath = g_strdup (p);
      p = NULL;
    } else {
      res->abspath = g_strndup (p, delim - p);
      p = delim;
    }
  } else {
    res->abspath = g_strdup ("/");
  }

  if (p && *p == '?')
    res->query = g_strdup (p + 1);

  *url = res;

  return GST_RTSP_OK;

  /* ERRORS */
invalid:
  {
    gst_rtsp_url_free (res);
    return GST_RTSP_EINVAL;
  }
}
Example #5
0
static GstRTSPStatusCode
nmp_rtsp_handle_request(NmpMediaDevice *device, GstRTSPMessage *request)
{
	GstRTSPMethod method;
	GstRTSPVersion version;
	const gchar *url_str;
	GstRTSPUrl *url;
	NmpRtspState state = { NULL };
	GstRTSPMessage response = { 0 };
	GstRTSPStatusCode rtsp_code = GST_RTSP_STS_OK;

	state.request = request;
	state.response = &response;

	gst_rtsp_message_parse_request(request, &method, &url_str, &version);
	if (version != GST_RTSP_VERSION_1_0)
	{
		/* we can only handle 1.0 requests */
		nmp_rtsp_device_send_generic_response(device, 
			GST_RTSP_STS_RTSP_VERSION_NOT_SUPPORTED, &state);
	    return GST_RTSP_STS_RTSP_VERSION_NOT_SUPPORTED;
	}

	state.method = method;

	if (gst_rtsp_url_parse(url_str, &url) != GST_RTSP_OK)
	{
    	nmp_rtsp_device_send_generic_response(device,
    		GST_RTSP_STS_BAD_REQUEST, &state);
		return GST_RTSP_STS_BAD_REQUEST;
	}

	state.url = url;

	switch (method)
	{
	case GST_RTSP_OPTIONS:
		rtsp_code = nmp_rtsp_handle_options_request(device, &state);
		break;

	case GST_RTSP_TEARDOWN:
//		nmp_rtsp_handle_teardown_request(device, &state);
		break;

	case GST_RTSP_DESCRIBE:
	case GST_RTSP_SETUP:
	case GST_RTSP_PLAY:
	case GST_RTSP_PAUSE:
	case GST_RTSP_SET_PARAMETER:
	case GST_RTSP_GET_PARAMETER:
	case GST_RTSP_ANNOUNCE:
	case GST_RTSP_RECORD:
	case GST_RTSP_REDIRECT:
		nmp_rtsp_device_send_generic_response(device,
		GST_RTSP_STS_NOT_IMPLEMENTED, &state);
		break;

	case GST_RTSP_INVALID:
	default:
		nmp_rtsp_device_send_generic_response(device,
		GST_RTSP_STS_BAD_REQUEST, &state);
		break;
	}

	gst_rtsp_url_free(url);
	return rtsp_code;
}