Skip to content

Commit

Permalink
Merge pull request #7 from play/add-tags-support
Browse files Browse the repository at this point in the history
Add tags command
  • Loading branch information
Paul Betts committed Oct 11, 2012
2 parents e780972 + ed9d7c5 commit 4791bbb
Show file tree
Hide file tree
Showing 8 changed files with 230 additions and 3 deletions.
1 change: 1 addition & 0 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ bin_PROGRAMS=gst_playd

gst_playd_SOURCES= \
gst_playd.c \
gst-util.c \
parser.c \
pubsub.c \
operations.c \
Expand Down
70 changes: 70 additions & 0 deletions src/gst-util.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
gst-util.c - GStreamer helper functions
Copyright (C) 2012 Paul Betts
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/

#include <glib.h>
#include <gst/gst.h>
#include <string.h>

#include "gst-util.h"

static void tag_to_hash_table(const GstTagList * list, const gchar * tag, gpointer user_data)
{
char* value;
int num = gst_tag_list_get_tag_size (list, tag);
GHashTable* ret = (GHashTable*)user_data;

for (int i = 0; i < num; ++i) {
const GValue *val = gst_tag_list_get_value_index (list, tag, i);

if (G_VALUE_HOLDS_STRING (val)) {
value = strdup(g_value_get_string(val));
} else if (G_VALUE_HOLDS_UINT (val)) {
value = g_strdup_printf("%u", g_value_get_uint(val));
} else if (G_VALUE_HOLDS_UINT64(val)) {
value = g_strdup_printf("%lu64", g_value_get_uint64(val));
} else if (G_VALUE_HOLDS_DOUBLE (val)) {
value = g_strdup_printf("%f", g_value_get_double(val));
} else if (G_VALUE_HOLDS_BOOLEAN (val)) {
value = strdup(g_value_get_boolean (val) ? "true" : "false");
} else if (GST_VALUE_HOLDS_BUFFER (val)) {
GstBuffer* buf = gst_value_get_buffer(val);
value = g_new0 (char, GST_BUFFER_SIZE(buf) + 1);
memcpy(value, GST_BUFFER_DATA(buf), sizeof(char) * GST_BUFFER_SIZE(buf));
} else if (GST_VALUE_HOLDS_DATE (val)) {
value = g_new0(char, sizeof(char) * 128);
g_date_strftime(value, 50, "%F", gst_value_get_date (val));
/*} else if (GST_VALUE_HOLDS_DATE_TIME (val)) {
value = gst_date_time_to_iso8601_string((GstDateTime*)val); */
} else {
value = g_strdup_printf ("tag of type ’%s’", G_VALUE_TYPE_NAME (val));
}

g_warning("Found tag: %s => %s", tag, value);
g_hash_table_insert(ret, g_strdup_printf("%s_%d", tag, i), value);
}
}

GHashTable* gsu_tags_to_hash_table(const GstTagList* tags)
{
GHashTable* ret = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
gst_tag_list_foreach(tags, tag_to_hash_table, ret);

return ret;
}
30 changes: 30 additions & 0 deletions src/gst-util.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
gst-util.h - GStreamer helper functions
Copyright (C) 2012 Paul Betts
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/


#ifndef _GST_UTIL_H
#define _GST_UTIL_H

#include <glib.h>
#include <gst/gst.h>

GHashTable* gsu_tags_to_hash_table(const GstTagList* tags);

#endif
1 change: 1 addition & 0 deletions src/gst_playd.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ struct timer_closure {
static struct parser_plugin_entry parser_operations[] = {
{ "Ping", NULL, op_ping_new, op_ping_register, op_ping_free },
{ "Control", NULL, op_control_new, op_control_register, op_control_free },
{ "Playback", NULL, op_playback_new, op_playback_register, op_playback_free },
{ NULL },
};

Expand Down
97 changes: 94 additions & 3 deletions src/operations.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@

#include "parser.h"
#include "operations.h"
#include "utility.h"
#include "gst-util.h"
#include "op_services.h"

struct message_dispatch_entry ping_messages[] = {
Expand All @@ -35,14 +37,18 @@ struct message_dispatch_entry control_messages[] = {
{ NULL },
};

struct message_dispatch_entry playback_messages[] = {
{ "TAGS", op_tags_parse },
{ NULL },
};


/*
* Ping
*/

void* op_ping_new(void* services)
{
g_warning("op_services = 0x%p", services);
return services;
}

Expand All @@ -60,7 +66,6 @@ char* op_ping_parse(const char* param, void* ctx)
{
struct op_services* services = (struct op_services*)ctx;

g_warning("op_services = 0x%p", services);
if (!param) param = "(none)";
char* ret = g_strdup_printf("OK Message was %s", param);

Expand All @@ -75,7 +80,6 @@ char* op_ping_parse(const char* param, void* ctx)

void* op_control_new(void* op_services)
{
g_warning("services: 0x%p", op_services);
return op_services;
}

Expand All @@ -94,3 +98,90 @@ char* op_pubsub_parse(const char* param, void* ctx)
struct op_services* services = (struct op_services*)ctx;
return g_strdup_printf("OK %s", pubsub_get_address(services->pub_sub));
}


struct playback_ctx {
struct op_services* services;
};

/*
* Playback Messages
*/

void* op_playback_new(void* op_services)
{
return op_services;
}

gboolean op_playback_register(void* ctx, struct message_dispatch_entry** entries)
{
*entries = playback_messages;
return TRUE;
}

void op_playback_free(void* dontcare)
{
}

static void on_new_pad_tags(GstElement* dec, GstPad* pad, GstElement* fakesink)
{
GstPad *sinkpad;

sinkpad = gst_element_get_static_pad(fakesink, "sink");

if (!gst_pad_is_linked (sinkpad)) {
if (gst_pad_link(pad, sinkpad) != GST_PAD_LINK_OK) {
g_error("Failed to link pads!");
}
}

gst_object_unref (sinkpad);
}

char* op_tags_parse(const char* param, void* ctx)
{
GstElement* pipe;
GstElement* dec;
GstElement* sink;

GstMessage* msg;
char* ret;

pipe = gst_pipeline_new("pipeline");
dec = gst_element_factory_make("uridecodebin", NULL);

g_object_set(dec, "uri", param, NULL);

gst_bin_add (GST_BIN (pipe), dec);
sink = gst_element_factory_make("fakesink", NULL); gst_bin_add (GST_BIN (pipe), sink);
g_signal_connect(dec, "pad-added", G_CALLBACK (on_new_pad_tags), sink);

gst_element_set_state(pipe, GST_STATE_PAUSED);

GHashTable* tag_table = NULL;

while (TRUE) {
GstTagList *tags = NULL;

msg = gst_bus_timed_pop_filtered(GST_ELEMENT_BUS (pipe), GST_CLOCK_TIME_NONE,
GST_MESSAGE_ASYNC_DONE | GST_MESSAGE_TAG | GST_MESSAGE_ERROR);

/* error or async_done */
if (GST_MESSAGE_TYPE (msg) != GST_MESSAGE_TAG) {
break;
}

gst_message_parse_tag(msg, &tags);
tag_table = gsu_tags_to_hash_table(tags);

gst_tag_list_free(tags);
gst_message_unref(msg);
}

char* table_data = util_hash_table_as_string(tag_table);
ret = g_strdup_printf("OK\n%s", table_data);
g_free(table_data);

g_hash_table_destroy(tag_table);
return ret;
}
5 changes: 5 additions & 0 deletions src/operations.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,9 @@ char* op_pubsub_parse(const char* param, void*);
gboolean op_control_register(void* ctx, struct message_dispatch_entry** entries);
void op_control_free(void* ctx);

void* op_playback_new(void*);
char* op_tags_parse(const char* param, void*);
gboolean op_playback_register(void* ctx, struct message_dispatch_entry** entries);
void op_playback_free(void* ctx);

#endif
28 changes: 28 additions & 0 deletions src/utility.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,31 @@ char* util_send_reqrep_msg(void* zmq_context, const char* message, const char* a
util_close_socket(sock);
return ret;
}

static void hash_foreach_calc_length(gpointer key, gpointer value, gpointer user_data)
{
int* len = (int*)user_data;
*len = (*len) + strlen((char*)key) + strlen((char*)value) + 2; /*newlines*/
}

static void hash_foreach_create_message(gpointer key, gpointer value, gpointer user_data)
{
/* XXX: I hate this code and it makes me want to die */
char** data = (char**)user_data;
*data += sprintf(*data, "%s\n%s\n", (char*)key, (char*)value);
}

char* util_hash_table_as_string(GHashTable* table)
{
char* ret;
int bufsize = 4;

g_hash_table_foreach(table, hash_foreach_calc_length, &bufsize);

ret = g_new0(char, bufsize);

char* iter = ret;
g_hash_table_foreach(table, hash_foreach_create_message, &iter);

return ret;
}
1 change: 1 addition & 0 deletions src/utility.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,6 @@
gboolean util_close_socket(void* sock);
char* util_send_reqrep_msg(void* zmq_context, const char* message, const char* address);
void util_zmq_glib_free(void* to_free, void* hint);
char* util_hash_table_as_string(GHashTable* table);

#endif

0 comments on commit 4791bbb

Please sign in to comment.