Make afcsrc take a URI so it can be used with uridecodebin
This commit is contained in:
parent
cc1728ddf0
commit
809ac54bef
|
@ -14,13 +14,10 @@
|
|||
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "gstafcsrc.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <gst/gst.h>
|
||||
|
||||
|
||||
|
@ -32,10 +29,11 @@ enum {
|
|||
// Properties
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_UUID,
|
||||
PROP_PATH,
|
||||
PROP_LOCATION,
|
||||
};
|
||||
|
||||
GST_DEBUG_CATEGORY_STATIC(gst_afc_src_debug);
|
||||
#define GST_CAT_DEFAULT gst_afc_src_debug
|
||||
|
||||
static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
|
||||
GST_PAD_SRC,
|
||||
|
@ -43,8 +41,8 @@ static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
|
|||
GST_STATIC_CAPS ("ANY")
|
||||
);
|
||||
|
||||
GST_BOILERPLATE (GstAfcSrc, gst_afc_src, GstBaseSrc, GST_TYPE_BASE_SRC);
|
||||
|
||||
static void gst_afc_src_interface_init(GType type);
|
||||
static void gst_afc_src_uri_handler_init(gpointer iface, gpointer data);
|
||||
static void gst_afc_src_set_property(GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec);
|
||||
static void gst_afc_src_get_property(GObject * object, guint prop_id, GValue * value, GParamSpec * pspec);
|
||||
static void gst_afc_src_finalize(GObject* object);
|
||||
|
@ -54,8 +52,21 @@ static GstFlowReturn gst_afc_src_create(GstBaseSrc* src, guint64 offset, guint l
|
|||
static gboolean gst_afc_src_is_seekable(GstBaseSrc* src);
|
||||
static gboolean gst_afc_src_get_size(GstBaseSrc* src, guint64* size);
|
||||
|
||||
GST_BOILERPLATE_FULL(GstAfcSrc, gst_afc_src, GstBaseSrc, GST_TYPE_BASE_SRC, gst_afc_src_interface_init);
|
||||
|
||||
|
||||
static void gst_afc_src_interface_init(GType type) {
|
||||
static const GInterfaceInfo urihandler_info = {
|
||||
gst_afc_src_uri_handler_init,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
GST_DEBUG_CATEGORY_INIT (gst_afc_src_debug, "afcsrc", 0, "iPod/iPhone Source");
|
||||
|
||||
g_type_add_interface_static(type, GST_TYPE_URI_HANDLER, &urihandler_info);
|
||||
}
|
||||
|
||||
static void gst_afc_src_base_init(gpointer gclass) {
|
||||
GstElementClass *element_class = GST_ELEMENT_CLASS (gclass);
|
||||
|
||||
|
@ -77,15 +88,10 @@ static void gst_afc_src_class_init (GstAfcSrcClass* klass) {
|
|||
gobject_class->get_property = gst_afc_src_get_property;
|
||||
gobject_class->finalize = gst_afc_src_finalize;
|
||||
|
||||
g_object_class_install_property(gobject_class, PROP_UUID,
|
||||
g_object_class_install_property(gobject_class, PROP_LOCATION,
|
||||
g_param_spec_string(
|
||||
"uuid", "AFC Device UUID",
|
||||
"The UUID of the device to connect to", NULL,
|
||||
GParamFlags(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_MUTABLE_READY)));
|
||||
g_object_class_install_property(gobject_class, PROP_PATH,
|
||||
g_param_spec_string(
|
||||
"path", "File path",
|
||||
"The absolute path of the file on the device", NULL,
|
||||
"location", "URI",
|
||||
"The URI of the file to read, must be of the form afc://uuid/filename", NULL,
|
||||
GParamFlags(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_MUTABLE_READY)));
|
||||
|
||||
gstbasesrc_class->start = gst_afc_src_start;
|
||||
|
@ -95,7 +101,38 @@ static void gst_afc_src_class_init (GstAfcSrcClass* klass) {
|
|||
gstbasesrc_class->get_size = gst_afc_src_get_size;
|
||||
}
|
||||
|
||||
static GstURIType gst_afc_src_uri_get_type() {
|
||||
return GST_URI_SRC;
|
||||
}
|
||||
|
||||
static gchar** gst_afc_src_uri_get_protocols() {
|
||||
static const gchar* protocols[] = { "afc", NULL };
|
||||
return (char**) protocols;
|
||||
}
|
||||
|
||||
static const gchar* gst_afc_src_uri_get_uri(GstURIHandler* handler) {
|
||||
GstAfcSrc* self = GST_AFCSRC(handler);
|
||||
return self->location_;
|
||||
}
|
||||
|
||||
static gboolean gst_afc_src_uri_set_uri(GstURIHandler* handler, const gchar* uri) {
|
||||
GstAfcSrc* self = GST_AFCSRC(handler);
|
||||
self->location_ = g_strdup(uri);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void gst_afc_src_uri_handler_init(gpointer g_iface, gpointer) {
|
||||
GstURIHandlerInterface* iface = (GstURIHandlerInterface*) g_iface;
|
||||
|
||||
iface->get_type = gst_afc_src_uri_get_type;
|
||||
iface->get_protocols = gst_afc_src_uri_get_protocols;
|
||||
iface->set_uri = gst_afc_src_uri_set_uri;
|
||||
iface->get_uri = gst_afc_src_uri_get_uri;
|
||||
}
|
||||
|
||||
|
||||
static void gst_afc_src_init(GstAfcSrc* element, GstAfcSrcClass* gclass) {
|
||||
element->location_ = NULL;
|
||||
element->uuid_ = NULL;
|
||||
element->path_ = NULL;
|
||||
element->afc_ = NULL;
|
||||
|
@ -107,6 +144,7 @@ static void gst_afc_src_init(GstAfcSrc* element, GstAfcSrcClass* gclass) {
|
|||
|
||||
static void gst_afc_src_finalize(GObject* object) {
|
||||
GstAfcSrc* src = GST_AFCSRC(object);
|
||||
free(src->location_);
|
||||
free(src->uuid_);
|
||||
free(src->path_);
|
||||
|
||||
|
@ -118,12 +156,8 @@ static void gst_afc_src_set_property(
|
|||
GstAfcSrc* self = GST_AFCSRC(object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_UUID:
|
||||
self->uuid_ = g_strdup(g_value_get_string(value));
|
||||
break;
|
||||
|
||||
case PROP_PATH:
|
||||
self->path_ = g_strdup(g_value_get_string(value));
|
||||
case PROP_LOCATION:
|
||||
self->location_ = g_strdup(g_value_get_string(value));
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -137,12 +171,8 @@ static void gst_afc_src_get_property(
|
|||
GstAfcSrc* self = GST_AFCSRC(object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_UUID:
|
||||
g_value_set_string(value, self->uuid_);
|
||||
break;
|
||||
|
||||
case PROP_PATH:
|
||||
g_value_set_string(value, self->path_);
|
||||
case PROP_LOCATION:
|
||||
g_value_set_string(value, self->location_);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -154,16 +184,24 @@ static void gst_afc_src_get_property(
|
|||
static gboolean gst_afc_src_start(GstBaseSrc* src) {
|
||||
GstAfcSrc* self = GST_AFCSRC(src);
|
||||
|
||||
// Check that a UUID and path have been passed
|
||||
if (!self->uuid_ || self->uuid_[0] == '\0') {
|
||||
GST_ELEMENT_ERROR(src, RESOURCE, NOT_FOUND, ("No UUID specified"), (NULL));
|
||||
return false;
|
||||
}
|
||||
if (!self->path_ || self->path_[0] == '\0') {
|
||||
GST_ELEMENT_ERROR(src, RESOURCE, NOT_FOUND, ("No path specified"), (NULL));
|
||||
// Check that a URI has been passed
|
||||
if (!self->location_ || self->location_[0] == '\0') {
|
||||
GST_ELEMENT_ERROR(src, RESOURCE, NOT_FOUND, ("No URI specified"), (NULL));
|
||||
return false;
|
||||
}
|
||||
|
||||
// Parse the URI
|
||||
// HERE BE DRAGONS
|
||||
gchar* location = gst_uri_get_location(self->location_);
|
||||
char* path_pos = strstr(location, "/");
|
||||
|
||||
self->uuid_ = (char*) malloc(path_pos - location + 1);
|
||||
memcpy(self->uuid_, location, path_pos - location);
|
||||
self->uuid_[path_pos - location] = '\0';
|
||||
self->path_ = g_strdup(path_pos);
|
||||
|
||||
g_free(location);
|
||||
|
||||
// Open the device
|
||||
idevice_error_t err = idevice_new(&self->device_, self->uuid_);
|
||||
if (err != IDEVICE_E_SUCCESS) {
|
||||
|
@ -190,7 +228,6 @@ static gboolean gst_afc_src_start(GstBaseSrc* src) {
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Try opening the file
|
||||
afc_err = afc_file_open(self->afc_, self->path_, AFC_FOPEN_RDONLY, &self->file_handle_);
|
||||
if (afc_err != 0) {
|
||||
|
|
|
@ -43,6 +43,7 @@ typedef struct _GstAfcSrcClass GstAfcSrcClass;
|
|||
struct _GstAfcSrc {
|
||||
GstBaseSrc element;
|
||||
|
||||
char* location_;
|
||||
char* uuid_;
|
||||
char* path_;
|
||||
|
||||
|
|
|
@ -18,17 +18,13 @@
|
|||
|
||||
#include <gst/gst.h>
|
||||
|
||||
GST_DEBUG_CATEGORY_STATIC(gst_afc_src_debug);
|
||||
#define GST_CAT_DEFAULT gst_afc_src_debug
|
||||
#define PACKAGE "Clementine"
|
||||
|
||||
|
||||
static gboolean afcsrc_init(GstPlugin* afcsrc) {
|
||||
GST_DEBUG_CATEGORY_INIT (gst_afc_src_debug, "afcsrc", 0, "iPod/iPhone Source");
|
||||
|
||||
return gst_element_register(afcsrc, "afcsrc", GST_RANK_NONE, GST_TYPE_AFCSRC);
|
||||
return gst_element_register(afcsrc, "afcsrc", GST_RANK_PRIMARY, GST_TYPE_AFCSRC);
|
||||
}
|
||||
|
||||
#define PACKAGE "Clementine"
|
||||
|
||||
GST_PLUGIN_DEFINE(
|
||||
GST_VERSION_MAJOR,
|
||||
GST_VERSION_MINOR,
|
||||
|
|
Loading…
Reference in New Issue