mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-23 10:11:08 +00:00
curl: new curlfilesink element
https://bugzilla.gnome.org/show_bug.cgi?id=653741
This commit is contained in:
parent
ae39cbfa57
commit
f139656bec
6 changed files with 812 additions and 3 deletions
|
@ -3,7 +3,8 @@ plugin_LTLIBRARIES = libgstcurl.la
|
|||
libgstcurl_la_SOURCES = gstcurl.c \
|
||||
gstcurlbasesink.c \
|
||||
gstcurltlssink.c \
|
||||
gstcurlhttpsink.c
|
||||
gstcurlhttpsink.c \
|
||||
gstcurlfilesink.c
|
||||
libgstcurl_la_CFLAGS = \
|
||||
$(GST_PLUGINS_BAD_CFLAGS) \
|
||||
$(GST_BASE_CFLAGS) \
|
||||
|
@ -19,4 +20,5 @@ libgstcurl_la_LIBTOOLFLAGS = --tag=disable-static
|
|||
|
||||
noinst_HEADERS = gstcurlbasesink.h \
|
||||
gstcurltlssink.h \
|
||||
gstcurlhttpsink.h
|
||||
gstcurlhttpsink.h \
|
||||
gstcurlfilesink.h
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "gstcurlbasesink.h"
|
||||
#include "gstcurltlssink.h"
|
||||
#include "gstcurlhttpsink.h"
|
||||
#include "gstcurlfilesink.h"
|
||||
|
||||
static gboolean
|
||||
plugin_init (GstPlugin * plugin)
|
||||
|
@ -32,6 +33,10 @@ plugin_init (GstPlugin * plugin)
|
|||
GST_TYPE_CURL_HTTP_SINK))
|
||||
return FALSE;
|
||||
|
||||
if (!gst_element_register (plugin, "curlfilesink", GST_RANK_NONE,
|
||||
GST_TYPE_CURL_FILE_SINK))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
233
ext/curl/gstcurlfilesink.c
Normal file
233
ext/curl/gstcurlfilesink.c
Normal file
|
@ -0,0 +1,233 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) 2011 Axis Communications <dev-gstreamer@axis.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:element-curlfilesink
|
||||
* @short_description: sink that uploads data to a server using libcurl
|
||||
* @see_also:
|
||||
*
|
||||
* This is a network sink that uses libcurl as a client to upload data to
|
||||
* a local or network drive.
|
||||
*
|
||||
* <refsect2>
|
||||
* <title>Example launch line (upload a JPEG file to /home/test/images directory)</title>
|
||||
* |[
|
||||
* gst-launch filesrc location=image.jpg ! jpegparse ! curlfilesink \
|
||||
* file-name=image.jpg \
|
||||
* location=file:///home/test/images/
|
||||
* ]|
|
||||
* </refsect2>
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <unistd.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "gstcurlbasesink.h"
|
||||
#include "gstcurlfilesink.h"
|
||||
|
||||
/* Default values */
|
||||
#define GST_CAT_DEFAULT gst_curl_file_sink_debug
|
||||
|
||||
|
||||
/* Plugin specific settings */
|
||||
|
||||
GST_DEBUG_CATEGORY_STATIC (gst_curl_file_sink_debug);
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_CREATE_DIRS
|
||||
};
|
||||
|
||||
|
||||
/* Object class function declarations */
|
||||
|
||||
|
||||
/* private functions */
|
||||
static void gst_curl_file_sink_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec);
|
||||
static void gst_curl_file_sink_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec);
|
||||
|
||||
static gboolean set_file_options_unlocked (GstCurlBaseSink * curlbasesink);
|
||||
static gboolean set_file_dynamic_options_unlocked
|
||||
(GstCurlBaseSink * curlbasesink);
|
||||
static gboolean gst_curl_file_sink_prepare_transfer (GstCurlBaseSink *
|
||||
curlbasesink);
|
||||
|
||||
#define gst_curl_file_sink_parent_class parent_class
|
||||
G_DEFINE_TYPE (GstCurlFileSink, gst_curl_file_sink, GST_TYPE_CURL_BASE_SINK);
|
||||
|
||||
static void
|
||||
gst_curl_file_sink_class_init (GstCurlFileSinkClass * klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
GstCurlBaseSinkClass *gstcurlbasesink_class = (GstCurlBaseSinkClass *) klass;
|
||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
||||
|
||||
GST_DEBUG_CATEGORY_INIT (gst_curl_file_sink_debug, "curlfilesink", 0,
|
||||
"curl file sink element");
|
||||
GST_DEBUG_OBJECT (klass, "class_init");
|
||||
|
||||
gst_element_class_set_details_simple (element_class,
|
||||
"Curl file sink",
|
||||
"Sink/Network",
|
||||
"Upload data over FILE protocol using libcurl",
|
||||
"Patricia Muscalu <patricia@axis.com>");
|
||||
|
||||
gobject_class->set_property = gst_curl_file_sink_set_property;
|
||||
gobject_class->get_property = gst_curl_file_sink_get_property;
|
||||
|
||||
gstcurlbasesink_class->set_protocol_dynamic_options_unlocked =
|
||||
set_file_dynamic_options_unlocked;
|
||||
gstcurlbasesink_class->set_options_unlocked = set_file_options_unlocked;
|
||||
gstcurlbasesink_class->prepare_transfer = gst_curl_file_sink_prepare_transfer;
|
||||
|
||||
g_object_class_install_property (gobject_class, PROP_CREATE_DIRS,
|
||||
g_param_spec_boolean ("create-dirs", "Create missing directories",
|
||||
"Attempt to create missing directory included in the path",
|
||||
FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
}
|
||||
|
||||
static void
|
||||
gst_curl_file_sink_init (GstCurlFileSink * sink)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gst_curl_file_sink_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstCurlFileSink *sink;
|
||||
GstState cur_state;
|
||||
|
||||
g_return_if_fail (GST_IS_CURL_FILE_SINK (object));
|
||||
sink = GST_CURL_FILE_SINK (object);
|
||||
|
||||
gst_element_get_state (GST_ELEMENT (sink), &cur_state, NULL, 0);
|
||||
if (cur_state != GST_STATE_PLAYING && cur_state != GST_STATE_PAUSED) {
|
||||
GST_OBJECT_LOCK (sink);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_CREATE_DIRS:
|
||||
sink->create_dirs = g_value_get_boolean (value);
|
||||
GST_DEBUG_OBJECT (sink, "create-dirs set to %d", sink->create_dirs);
|
||||
break;
|
||||
|
||||
default:
|
||||
GST_DEBUG_OBJECT (sink, "invalid property id %d", prop_id);
|
||||
break;
|
||||
}
|
||||
|
||||
GST_OBJECT_UNLOCK (sink);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_curl_file_sink_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstCurlFileSink *sink;
|
||||
|
||||
g_return_if_fail (GST_IS_CURL_FILE_SINK (object));
|
||||
sink = GST_CURL_FILE_SINK (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_CREATE_DIRS:
|
||||
g_value_set_boolean (value, sink->create_dirs);
|
||||
break;
|
||||
default:
|
||||
GST_DEBUG_OBJECT (sink, "invalid property id");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
set_file_dynamic_options_unlocked (GstCurlBaseSink * basesink)
|
||||
{
|
||||
gchar *tmp = g_strdup_printf ("%s%s", basesink->url, basesink->file_name);
|
||||
|
||||
curl_easy_setopt (basesink->curl, CURLOPT_URL, tmp);
|
||||
|
||||
g_free (tmp);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
set_file_options_unlocked (GstCurlBaseSink * basesink)
|
||||
{
|
||||
curl_easy_setopt (basesink->curl, CURLOPT_UPLOAD, 1L);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_curl_file_sink_prepare_transfer (GstCurlBaseSink * basesink)
|
||||
{
|
||||
GstCurlFileSink *sink = GST_CURL_FILE_SINK (basesink);
|
||||
|
||||
if (sink->create_dirs) {
|
||||
gchar *file_name;
|
||||
gchar *last_slash;
|
||||
|
||||
gchar *url = g_strdup_printf ("%s%s", basesink->url, basesink->file_name);
|
||||
file_name = g_filename_from_uri (url, NULL, NULL);
|
||||
if (file_name == NULL) {
|
||||
GST_DEBUG_OBJECT (sink, "failed to parse file name of '%s'", url);
|
||||
GST_ELEMENT_ERROR (sink, RESOURCE, WRITE, ("failed to parse file name"),
|
||||
(NULL));
|
||||
g_free (url);
|
||||
return FALSE;
|
||||
}
|
||||
g_free (url);
|
||||
|
||||
last_slash = strrchr (file_name, G_DIR_SEPARATOR);
|
||||
if (last_slash != NULL) {
|
||||
/* create dir if file name contains dir component */
|
||||
gchar *dir_name = g_strndup (file_name, last_slash - file_name);
|
||||
if (g_mkdir_with_parents (dir_name, S_IRWXU) < 0) {
|
||||
GST_DEBUG_OBJECT (sink, "failed to create directory '%s'", dir_name);
|
||||
GST_ELEMENT_ERROR (sink, RESOURCE, WRITE,
|
||||
("failed to create directory"), (NULL));
|
||||
g_free (file_name);
|
||||
g_free (dir_name);
|
||||
return FALSE;
|
||||
}
|
||||
g_free (dir_name);
|
||||
}
|
||||
g_free (file_name);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
58
ext/curl/gstcurlfilesink.h
Normal file
58
ext/curl/gstcurlfilesink.h
Normal file
|
@ -0,0 +1,58 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) 2011 Axis Communications <dev-gstreamer@axis.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GST_CURL_FILE_SINK__
|
||||
#define __GST_CURL_FILE_SINK__
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/base/gstbasesink.h>
|
||||
#include <curl/curl.h>
|
||||
#include "gstcurlbasesink.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
#define GST_TYPE_CURL_FILE_SINK \
|
||||
(gst_curl_file_sink_get_type())
|
||||
#define GST_CURL_FILE_SINK(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj), GST_TYPE_CURL_FILE_SINK, GstCurlFileSink))
|
||||
#define GST_CURL_FILE_SINK_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_CURL_FILE_SINK, GstCurlFileSinkClass))
|
||||
#define GST_IS_CURL_FILE_SINK(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_CURL_FILE_SINK))
|
||||
#define GST_IS_CURL_FILE_SINK_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_CURL_FILE_SINK))
|
||||
typedef struct _GstCurlFileSink GstCurlFileSink;
|
||||
typedef struct _GstCurlFileSinkClass GstCurlFileSinkClass;
|
||||
|
||||
struct _GstCurlFileSink
|
||||
{
|
||||
GstCurlBaseSink parent;
|
||||
|
||||
/*< private > */
|
||||
gboolean create_dirs;
|
||||
};
|
||||
|
||||
struct _GstCurlFileSinkClass
|
||||
{
|
||||
GstCurlBaseSinkClass parent_class;
|
||||
};
|
||||
|
||||
GType gst_curl_file_sink_get_type (void);
|
||||
|
||||
G_END_DECLS
|
||||
#endif
|
|
@ -148,7 +148,8 @@ check_opus =
|
|||
endif
|
||||
|
||||
if USE_CURL
|
||||
check_curl = elements/curlhttpsink
|
||||
check_curl = elements/curlhttpsink \
|
||||
elements/curlfilesink
|
||||
else
|
||||
check_curl =
|
||||
endif
|
||||
|
|
510
tests/check/elements/curlfilesink.c
Normal file
510
tests/check/elements/curlfilesink.c
Normal file
|
@ -0,0 +1,510 @@
|
|||
/*
|
||||
* Unittest for curlfilesink
|
||||
*/
|
||||
|
||||
#include <gst/check/gstcheck.h>
|
||||
#include <glib/gstdio.h>
|
||||
#include <curl/curl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS_ANY);
|
||||
|
||||
static GstPad *srcpad;
|
||||
|
||||
static GstElement *sink;
|
||||
|
||||
static GstElement *
|
||||
setup_curlfilesink (void)
|
||||
{
|
||||
GST_DEBUG ("setup_curlfielsink");
|
||||
sink = gst_check_setup_element ("curlfilesink");
|
||||
srcpad = gst_check_setup_src_pad (sink, &srctemplate);
|
||||
gst_pad_set_active (srcpad, TRUE);
|
||||
|
||||
return sink;
|
||||
}
|
||||
|
||||
static void
|
||||
cleanup_curlfilesink (GstElement * sink)
|
||||
{
|
||||
GST_DEBUG ("cleanup_curlfilesink");
|
||||
|
||||
gst_check_teardown_src_pad (sink);
|
||||
gst_check_teardown_element (sink);
|
||||
}
|
||||
|
||||
static void
|
||||
test_verify_file_data (const gchar *dir, gchar *file_name,
|
||||
const gchar *expected_file_content)
|
||||
{
|
||||
GError *err = NULL;
|
||||
gchar *res_file_content = NULL;
|
||||
gchar *path = NULL;
|
||||
|
||||
path = g_strdup_printf ("%s/%s", dir, file_name);
|
||||
g_free (file_name);
|
||||
|
||||
if (!g_file_get_contents (path, &res_file_content, NULL, &err)) {
|
||||
GST_WARNING ("Error loading file: %s (%s)", file_name, err->message);
|
||||
g_error_free (err);
|
||||
}
|
||||
|
||||
fail_unless (res_file_content != NULL);
|
||||
|
||||
fail_unless (strncmp (res_file_content, expected_file_content,
|
||||
strlen (expected_file_content)) == 0);
|
||||
g_free (res_file_content);
|
||||
g_unlink (path);
|
||||
g_free (path);
|
||||
}
|
||||
|
||||
static void
|
||||
test_set_and_play_buffer (const gchar * _data)
|
||||
{
|
||||
gpointer data = (gpointer) _data;
|
||||
GstBuffer *buffer;
|
||||
gint num_bytes;
|
||||
|
||||
num_bytes = strlen (data);
|
||||
buffer = gst_buffer_new ();
|
||||
gst_buffer_insert_memory (buffer, 0,
|
||||
gst_memory_new_wrapped (GST_MEMORY_FLAG_READONLY,
|
||||
data, num_bytes, 0, num_bytes, data, NULL));
|
||||
|
||||
fail_unless (gst_pad_push (srcpad, buffer) == GST_FLOW_OK);
|
||||
}
|
||||
|
||||
static void
|
||||
test_set_and_fail_to_play_buffer (const gchar * _data)
|
||||
{
|
||||
gpointer data = (gpointer) _data;
|
||||
GstBuffer *buffer;
|
||||
gint num_bytes;
|
||||
|
||||
num_bytes = strlen (data);
|
||||
buffer = gst_buffer_new ();
|
||||
gst_buffer_insert_memory (buffer, 0,
|
||||
gst_memory_new_wrapped (GST_MEMORY_FLAG_READONLY,
|
||||
data, num_bytes, 0, num_bytes, data, NULL));
|
||||
|
||||
fail_unless (gst_pad_push (srcpad, buffer) == GST_FLOW_ERROR);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
sebras_gst_pad_set_caps (GstPad * pad, GstCaps * caps)
|
||||
{
|
||||
GstEvent *event;
|
||||
gboolean res = TRUE;
|
||||
|
||||
GST_WARNING ("sebraz: a %p %p", pad, caps);
|
||||
g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
|
||||
GST_WARNING ("sebraz: b");
|
||||
g_return_val_if_fail (caps != NULL && gst_caps_is_fixed (caps), FALSE);
|
||||
GST_WARNING ("sebraz: c");
|
||||
|
||||
GST_WARNING ("sebraz: d");
|
||||
event = gst_event_new_caps (caps);
|
||||
GST_WARNING ("sebraz: e");
|
||||
|
||||
if (GST_PAD_IS_SRC (pad)) {
|
||||
GST_WARNING ("sebraz: f1");
|
||||
res = gst_pad_push_event (pad, event);
|
||||
} else {
|
||||
GST_WARNING ("sebraz: f2");
|
||||
res = gst_pad_send_event (pad, event);
|
||||
}
|
||||
|
||||
GST_WARNING ("sebraz: g");
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
GST_START_TEST (test_properties)
|
||||
{
|
||||
GstElement *sink;
|
||||
GstCaps *caps;
|
||||
const gchar *location= "file:///tmp/";
|
||||
const gchar *file_contents = "line 1\r\n";
|
||||
gchar *file_name = g_strdup_printf ("curlfilesink_%d", g_random_int ());
|
||||
gchar *res_location = NULL;
|
||||
gchar *res_file_name = NULL;
|
||||
gboolean res_create_dirs = FALSE;
|
||||
gchar *path = NULL;
|
||||
|
||||
GST_WARNING ("sebras: a");
|
||||
|
||||
sink = setup_curlfilesink ();
|
||||
GST_WARNING ("sebras: b");
|
||||
|
||||
g_object_set (G_OBJECT (sink), "location", "mylocation", NULL);
|
||||
g_object_set (G_OBJECT (sink), "file-name", "myfile", NULL);
|
||||
g_object_set (G_OBJECT (sink), "create-dirs", TRUE, NULL);
|
||||
GST_WARNING ("sebras: c");
|
||||
|
||||
g_object_get (sink,
|
||||
"location", &res_location,
|
||||
"file-name", &res_file_name,
|
||||
"create-dirs", &res_create_dirs,
|
||||
NULL);
|
||||
GST_WARNING ("sebras: d");
|
||||
|
||||
fail_unless (strncmp (res_location, "mylocation", strlen ("mylocation"))
|
||||
== 0);
|
||||
GST_WARNING ("sebras: e");
|
||||
fail_unless (strncmp (res_file_name, "myfile", strlen ("myfile"))
|
||||
== 0);
|
||||
GST_WARNING ("sebras: f");
|
||||
fail_unless (res_create_dirs == TRUE);
|
||||
GST_WARNING ("sebras: g");
|
||||
g_free (res_location);
|
||||
g_free (res_file_name);
|
||||
GST_WARNING ("sebras: h");
|
||||
|
||||
/* change properties */
|
||||
g_object_set (G_OBJECT (sink), "location", location, NULL);
|
||||
g_object_set (G_OBJECT (sink), "file-name", file_name, NULL);
|
||||
g_object_set (G_OBJECT (sink), "create-dirs", FALSE, NULL);
|
||||
GST_WARNING ("sebras: i");
|
||||
|
||||
g_object_get (sink,
|
||||
"location", &res_location,
|
||||
"file-name", &res_file_name,
|
||||
"create-dirs", &res_create_dirs,
|
||||
NULL);
|
||||
GST_WARNING ("sebras: j");
|
||||
|
||||
fail_unless (strncmp (res_location, location, strlen (location))
|
||||
== 0);
|
||||
GST_WARNING ("sebras: k");
|
||||
fail_unless (strncmp (res_file_name, file_name, strlen (file_name))
|
||||
== 0);
|
||||
GST_WARNING ("sebras: l");
|
||||
fail_unless (res_create_dirs == FALSE);
|
||||
GST_WARNING ("sebras: m");
|
||||
g_free (res_location);
|
||||
g_free (res_file_name);
|
||||
GST_WARNING ("sebras: n");
|
||||
|
||||
/* start playing */
|
||||
ASSERT_SET_STATE (sink, GST_STATE_PLAYING, GST_STATE_CHANGE_ASYNC);
|
||||
GST_WARNING ("sebras: o");
|
||||
caps = gst_caps_from_string ("application/x-gst-check");
|
||||
GST_WARNING ("sebras: p");
|
||||
fail_unless (sebras_gst_pad_set_caps (srcpad, caps));
|
||||
fail_unless (gst_pad_set_caps (srcpad, caps));
|
||||
GST_WARNING ("sebras: q");
|
||||
|
||||
/* setup buffer */
|
||||
test_set_and_play_buffer (file_contents);
|
||||
GST_WARNING ("sebras: r");
|
||||
|
||||
/* try to change location property while in PLAYING state */
|
||||
g_object_set (G_OBJECT (sink), "location", "newlocation", NULL);
|
||||
g_object_get (sink, "location", &res_location, NULL);
|
||||
|
||||
/* verify that locaiton has not been altered */
|
||||
fail_unless (strncmp (res_location, location, strlen (location))
|
||||
== 0);
|
||||
g_free (res_location);
|
||||
|
||||
/* eos */
|
||||
fail_unless (gst_pad_push_event (srcpad, gst_event_new_eos ()));
|
||||
ASSERT_SET_STATE (sink, GST_STATE_NULL, GST_STATE_CHANGE_SUCCESS);
|
||||
|
||||
gst_caps_unref (caps);
|
||||
cleanup_curlfilesink (sink);
|
||||
|
||||
path = g_strdup_printf ("/tmp/%s", file_name);
|
||||
g_unlink (path);
|
||||
g_free (file_name);
|
||||
g_free (path);
|
||||
}
|
||||
GST_END_TEST;
|
||||
|
||||
GST_START_TEST (test_one_file)
|
||||
{
|
||||
GstElement *sink;
|
||||
GstCaps *caps;
|
||||
const gchar *location= "file:///tmp/";
|
||||
gchar *file_name = g_strdup_printf ("curlfilesink_%d", g_random_int ());
|
||||
const gchar *file_content = "line 1\r\n";
|
||||
gchar *res_location = NULL;
|
||||
gchar *res_file_name = NULL;
|
||||
|
||||
sink = setup_curlfilesink ();
|
||||
|
||||
g_object_set (G_OBJECT (sink), "location", location, NULL);
|
||||
g_object_set (G_OBJECT (sink), "file-name", file_name, NULL);
|
||||
|
||||
g_object_get (sink,
|
||||
"location", &res_location,
|
||||
"file-name", &res_file_name,
|
||||
NULL);
|
||||
|
||||
fail_unless (strncmp (res_location, location, strlen (location))
|
||||
== 0);
|
||||
fail_unless (strncmp (res_file_name, file_name, strlen (file_name))
|
||||
== 0);
|
||||
|
||||
g_free (res_location);
|
||||
g_free (res_file_name);
|
||||
|
||||
/* start playing */
|
||||
ASSERT_SET_STATE (sink, GST_STATE_PLAYING, GST_STATE_CHANGE_ASYNC);
|
||||
caps = gst_caps_from_string ("application/x-gst-check");
|
||||
fail_unless (gst_pad_set_caps (srcpad, caps));
|
||||
|
||||
/* setup buffer */
|
||||
test_set_and_play_buffer (file_content);
|
||||
|
||||
/* eos */
|
||||
fail_unless (gst_pad_push_event (srcpad, gst_event_new_eos ()));
|
||||
ASSERT_SET_STATE (sink, GST_STATE_NULL, GST_STATE_CHANGE_SUCCESS);
|
||||
|
||||
gst_caps_unref (caps);
|
||||
cleanup_curlfilesink (sink);
|
||||
|
||||
/* verify file content */
|
||||
test_verify_file_data ("/tmp", file_name, file_content);
|
||||
}
|
||||
GST_END_TEST;
|
||||
|
||||
GST_START_TEST (test_one_big_file)
|
||||
{
|
||||
GstElement *sink;
|
||||
GstCaps *caps;
|
||||
const gchar *location= "file:///tmp/";
|
||||
gchar *file_name = g_strdup_printf ("curlfilesink_%d", g_random_int ());
|
||||
const gchar *file_line1 = "line 1\r\n";
|
||||
const gchar *file_line2 = "line 2\r\n";
|
||||
const gchar *file_line3 = "line 3\r\n";
|
||||
const gchar *expected_file_content = "line 1\r\n" \
|
||||
"line 2\r\n" \
|
||||
"line 3\r\n";
|
||||
gchar *res_location = NULL;
|
||||
gchar *res_file_name = NULL;
|
||||
|
||||
sink = setup_curlfilesink ();
|
||||
|
||||
g_object_set (G_OBJECT (sink), "location", location, NULL);
|
||||
g_object_set (G_OBJECT (sink), "file-name", file_name, NULL);
|
||||
|
||||
g_object_get (sink,
|
||||
"location", &res_location,
|
||||
"file-name", &res_file_name,
|
||||
NULL);
|
||||
|
||||
fail_unless (strncmp (res_location, location, strlen (location))
|
||||
== 0);
|
||||
fail_unless (strncmp (res_file_name, file_name, strlen (file_name))
|
||||
== 0);
|
||||
|
||||
g_free (res_location);
|
||||
g_free (res_file_name);
|
||||
|
||||
/* start playing */
|
||||
ASSERT_SET_STATE (sink, GST_STATE_PLAYING, GST_STATE_CHANGE_ASYNC);
|
||||
caps = gst_caps_from_string ("application/x-gst-check");
|
||||
fail_unless (gst_pad_set_caps (srcpad, caps));
|
||||
|
||||
/* setup first buffer */
|
||||
test_set_and_play_buffer (file_line1);
|
||||
|
||||
/* setup second buffer */
|
||||
test_set_and_play_buffer (file_line2);
|
||||
|
||||
/* setup third buffer */
|
||||
test_set_and_play_buffer (file_line3);
|
||||
|
||||
/* eos */
|
||||
fail_unless (gst_pad_push_event (srcpad, gst_event_new_eos ()));
|
||||
ASSERT_SET_STATE (sink, GST_STATE_NULL, GST_STATE_CHANGE_SUCCESS);
|
||||
|
||||
gst_caps_unref (caps);
|
||||
cleanup_curlfilesink (sink);
|
||||
|
||||
/* verify file content */
|
||||
test_verify_file_data ("/tmp", file_name, expected_file_content);
|
||||
}
|
||||
GST_END_TEST;
|
||||
|
||||
GST_START_TEST (test_two_files)
|
||||
{
|
||||
GstElement *sink;
|
||||
GstCaps *caps;
|
||||
const gchar *location= "file:///tmp/";
|
||||
gchar *file_name1 = g_strdup_printf ("curlfilesink_%d", g_random_int ());
|
||||
gchar *file_name2 = g_strdup_printf ("curlfilesink_%d", g_random_int ());
|
||||
const gchar *file_content1 = "file content 1\r\n";
|
||||
const gchar *file_content2 = "file content 2\r\n";
|
||||
gchar *res_location = NULL;
|
||||
gchar *res_file_name = NULL;
|
||||
|
||||
sink = setup_curlfilesink ();
|
||||
|
||||
g_object_set (G_OBJECT (sink), "location", location, NULL);
|
||||
g_object_set (G_OBJECT (sink), "file-name", file_name1, NULL);
|
||||
|
||||
g_object_get (sink,
|
||||
"location", &res_location,
|
||||
"file-name", &res_file_name,
|
||||
NULL);
|
||||
|
||||
fail_unless (strncmp (res_location, location, strlen (location))
|
||||
== 0);
|
||||
fail_unless (strncmp (res_file_name, file_name1, strlen (file_name1))
|
||||
== 0);
|
||||
|
||||
g_free (res_location);
|
||||
g_free (res_file_name);
|
||||
|
||||
/* start playing */
|
||||
ASSERT_SET_STATE (sink, GST_STATE_PLAYING, GST_STATE_CHANGE_ASYNC);
|
||||
caps = gst_caps_from_string ("application/x-gst-check");
|
||||
fail_unless (gst_pad_set_caps (srcpad, caps));
|
||||
|
||||
/* setup first buffer - content of the first file */
|
||||
test_set_and_play_buffer (file_content1);
|
||||
|
||||
g_object_set (G_OBJECT (sink), "file-name", file_name2, NULL);
|
||||
g_object_get (sink, "file-name", &res_file_name, NULL);
|
||||
fail_unless (strncmp (res_file_name, file_name2, strlen (file_name2))
|
||||
== 0);
|
||||
g_free (res_file_name);
|
||||
|
||||
/* setup second buffer - content of the second file */
|
||||
test_set_and_play_buffer (file_content2);
|
||||
|
||||
/* eos */
|
||||
fail_unless (gst_pad_push_event (srcpad, gst_event_new_eos ()));
|
||||
ASSERT_SET_STATE (sink, GST_STATE_NULL, GST_STATE_CHANGE_SUCCESS);
|
||||
|
||||
gst_caps_unref (caps);
|
||||
cleanup_curlfilesink (sink);
|
||||
|
||||
/* verify file contents of the first file */
|
||||
test_verify_file_data ("/tmp", file_name1, file_content1);
|
||||
test_verify_file_data ("/tmp", file_name2, file_content2);
|
||||
}
|
||||
GST_END_TEST;
|
||||
|
||||
GST_START_TEST (test_create_dirs)
|
||||
{
|
||||
GstElement *sink;
|
||||
GstCaps *caps;
|
||||
gchar *tmp_dir = g_strdup ("/tmp/curlfilesink_XXXXXX");
|
||||
gchar *sub_dir;
|
||||
gchar *sub_sub_dir;
|
||||
gchar *location;
|
||||
gchar *file_name = g_strdup_printf ("curlfilesink_%d", g_random_int ());
|
||||
const gchar *file_content = "line 1\r\n";
|
||||
|
||||
/* create temp dir as base dir (mkdtemp saves dir name in tmp_dir) */
|
||||
fail_unless (mkdtemp (tmp_dir) != NULL);
|
||||
|
||||
/* use sub-sub directory as location */
|
||||
sub_dir = g_strdup_printf ("%s/a", tmp_dir);
|
||||
sub_sub_dir = g_strdup_printf ("%s/b", sub_dir);
|
||||
location = g_strdup_printf ("file://%s/", sub_sub_dir);
|
||||
|
||||
sink = setup_curlfilesink ();
|
||||
|
||||
g_object_set (G_OBJECT (sink), "location", location, NULL);
|
||||
g_object_set (G_OBJECT (sink), "file-name", file_name, NULL);
|
||||
g_object_set (G_OBJECT (sink), "create-dirs", TRUE, NULL);
|
||||
|
||||
/* start playing */
|
||||
ASSERT_SET_STATE (sink, GST_STATE_PLAYING, GST_STATE_CHANGE_ASYNC);
|
||||
caps = gst_caps_from_string ("application/x-gst-check");
|
||||
fail_unless (gst_pad_set_caps (srcpad, caps));
|
||||
|
||||
/* setup buffer */
|
||||
test_set_and_play_buffer (file_content);
|
||||
|
||||
/* eos */
|
||||
fail_unless (gst_pad_push_event (srcpad, gst_event_new_eos ()));
|
||||
ASSERT_SET_STATE (sink, GST_STATE_NULL, GST_STATE_CHANGE_SUCCESS);
|
||||
|
||||
gst_caps_unref (caps);
|
||||
cleanup_curlfilesink (sink);
|
||||
|
||||
/* verify file content in sub-sub dir created by sink */
|
||||
test_verify_file_data (sub_sub_dir, file_name, file_content);
|
||||
|
||||
/* remove directories */
|
||||
fail_unless (g_rmdir (sub_sub_dir) == 0);
|
||||
fail_unless (g_rmdir (sub_dir) == 0);
|
||||
fail_unless (g_rmdir (tmp_dir) == 0);
|
||||
g_free (sub_sub_dir);
|
||||
g_free (sub_dir);
|
||||
g_free (tmp_dir);
|
||||
}
|
||||
GST_END_TEST;
|
||||
|
||||
GST_START_TEST (test_missing_path)
|
||||
{
|
||||
GstElement *sink;
|
||||
GstCaps *caps;
|
||||
const gchar *location= "file:///missing/path/";
|
||||
gchar *file_name = g_strdup_printf ("curlfilesink_%d", g_random_int ());
|
||||
const gchar *file_content = "line 1\r\n";
|
||||
gchar *res_location = NULL;
|
||||
gchar *res_file_name = NULL;
|
||||
|
||||
sink = setup_curlfilesink ();
|
||||
|
||||
g_object_set (G_OBJECT (sink), "location", location, NULL);
|
||||
g_object_set (G_OBJECT (sink), "file-name", file_name, NULL);
|
||||
|
||||
g_object_get (sink,
|
||||
"location", &res_location,
|
||||
"file-name", &res_file_name,
|
||||
NULL);
|
||||
|
||||
fail_unless (strncmp (res_location, location, strlen (location))
|
||||
== 0);
|
||||
fail_unless (strncmp (res_file_name, file_name, strlen (file_name))
|
||||
== 0);
|
||||
|
||||
g_free (res_location);
|
||||
g_free (res_file_name);
|
||||
|
||||
/* start playing */
|
||||
ASSERT_SET_STATE (sink, GST_STATE_PLAYING, GST_STATE_CHANGE_ASYNC);
|
||||
caps = gst_caps_from_string ("application/x-gst-check");
|
||||
fail_unless (gst_pad_set_caps (srcpad, caps));
|
||||
|
||||
/* setup & play buffer which should fail due to the missing path */
|
||||
test_set_and_fail_to_play_buffer (file_content);
|
||||
|
||||
/* eos */
|
||||
fail_unless (gst_pad_push_event (srcpad, gst_event_new_eos ()));
|
||||
ASSERT_SET_STATE (sink, GST_STATE_NULL, GST_STATE_CHANGE_SUCCESS);
|
||||
|
||||
gst_caps_unref (caps);
|
||||
cleanup_curlfilesink (sink);
|
||||
}
|
||||
GST_END_TEST;
|
||||
|
||||
static Suite *
|
||||
curlsink_suite (void)
|
||||
{
|
||||
Suite *s = suite_create ("curlfilesink");
|
||||
TCase *tc_chain = tcase_create ("general");
|
||||
|
||||
suite_add_tcase (s, tc_chain);
|
||||
tcase_set_timeout (tc_chain, 20);
|
||||
tcase_add_test (tc_chain, test_properties);
|
||||
tcase_add_test (tc_chain, test_one_file);
|
||||
tcase_add_test (tc_chain, test_one_big_file);
|
||||
tcase_add_test (tc_chain, test_two_files);
|
||||
tcase_add_test (tc_chain, test_missing_path);
|
||||
tcase_add_test (tc_chain, test_create_dirs);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
GST_CHECK_MAIN (curlsink);
|
Loading…
Reference in a new issue