[xiph-cvs] cvs commit: libshout/src shout.c shout_private.h util.c util.h
Brendan
brendan at xiph.org
Sat Feb 22 13:08:11 PST 2003
brendan 03/02/22 16:08:11
Modified: include/shout shout.h
src shout.c shout_private.h util.c util.h
Log:
shout_(get|set)_bitrate REMOVED.
Instead of shout_set_bitrate(shout_t, int bitrate),
use
shout_set_audio_info(shout_t, SHOUT_AI_BITRATE, const char* bitrate)
For shout_get_bitrate,
use shout_get_audio_info(shout_t, SHOUT_AI_BITRATE).
Note the result is a const char*.
After some discussion with oddsock about YP, we decided it would be nice to be able
to send more information about the audio parameters of the stream. Currently
defined are SHOUT_AI_BITRATE, SHOUT_AI_SAMPLERATE, SHOUT_AI_CHANNELS, and
SHOUT_AI_QUALITY (vorbis quality). Adding more is easy, but the client can also
use its own arbitrary strings instead of the defined constants.
This is commit one, which makes no change to the wire protocol. In the second
commit, I'll change the ice-bitrate field to ice-audio-info.
Revision Changes Path
1.15 +9 -5 libshout/include/shout/shout.h
Index: shout.h
===================================================================
RCS file: /usr/local/cvsroot/libshout/include/shout/shout.h,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -r1.14 -r1.15
--- shout.h 20 Feb 2003 20:34:44 -0000 1.14
+++ shout.h 22 Feb 2003 21:08:10 -0000 1.15
@@ -1,6 +1,6 @@
/* shout.h
**
-** api for libshout, the streaming library for icecast
+** API for libshout, the streaming library for icecast
*/
#ifndef __LIBSHOUT_SHOUT_H__
#define __LIBSHOUT_SHOUT_H__
@@ -26,8 +26,13 @@
#define SHOUT_PROTOCOL_XAUDIOCAST (1)
#define SHOUT_PROTOCOL_ICY (2)
+#define SHOUT_AI_BITRATE "bitrate"
+#define SHOUT_AI_SAMPLERATE "samplerate"
+#define SHOUT_AI_CHANNELS "channels"
+#define SHOUT_AI_QUALITY "quality"
+
typedef struct shout shout_t;
-typedef struct shout_metadata shout_metadata_t;
+typedef struct _util_dict shout_metadata_t;
#ifdef __cplusplus
extern "C" {
@@ -91,9 +96,8 @@
int shout_set_dumpfile(shout_t *self, const char *dumpfile);
const char *shout_get_dumpfile(shout_t *self);
-/* bitrate is in kbps */
-int shout_set_bitrate(shout_t *self, unsigned int bitrate);
-unsigned int shout_get_bitrate(shout_t *self);
+int shout_set_audio_info(shout_t *self, const char *name, const char *value);
+const char *shout_get_audio_info(shout_t *self, const char *name);
int shout_set_public(shout_t *self, unsigned int public);
unsigned int shout_get_public(shout_t *self);
<p><p>1.24 +34 -56 libshout/src/shout.c
Index: shout.c
===================================================================
RCS file: /usr/local/cvsroot/libshout/src/shout.c,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -r1.23 -r1.24
--- shout.c 20 Feb 2003 20:34:44 -0000 1.23
+++ shout.c 22 Feb 2003 21:08:10 -0000 1.24
@@ -44,6 +44,11 @@
return NULL;
}
+ if (!(self->audio_info = util_dict_new())) {
+ shout_free(self);
+
+ return NULL;
+ }
self->port = LIBSHOUT_DEFAULT_PORT;
self->format = LIBSHOUT_DEFAULT_FORMAT;
@@ -65,6 +70,7 @@
if (self->description) free(self->description);
if (self->user) free(self->user);
if (self->useragent) free(self->useragent);
+ if (self->audio_info) util_dict_free (self->audio_info);
free(self);
}
@@ -204,13 +210,7 @@
shout_metadata_t *shout_metadata_new(void)
{
- shout_metadata_t *self;
-
- if (!(self = (shout_metadata_t *)calloc(1, sizeof(shout_metadata_t)))) {
- return NULL;
- }
-
- return self;
+ return util_dict_new();
}
void shout_metadata_free(shout_metadata_t *self)
@@ -218,7 +218,7 @@
if (!self)
return;
- free (self);
+ util_dict_free(self);
}
int shout_metadata_add(shout_metadata_t *self, const char *name, const char *value)
@@ -226,31 +226,7 @@
if (!self || !name)
return SHOUTERR_INSANE;
- while (self->next)
- self = self->next;
- /* If this is the first entry, name/value are null and available. Otherwise
- * create a new entry at the end. */
- if (self->name) {
- shout_metadata_t* tail;
-
- if (!(tail = shout_metadata_new()))
- return SHOUTERR_MALLOC;
-
- self->next = tail;
- self = self->next;
- }
-
- if (!(self->name = util_strdup(name)))
- return SHOUTERR_MALLOC;
-
- if (!(self->value = util_strdup(value))) {
- free (self->name);
- self->name = NULL;
-
- return SHOUTERR_MALLOC;
- };
-
- return SHOUTERR_SUCCESS;
+ return util_dict_set(self, name, value);
}
/* open second socket to server, send HTTP request to change metadata.
@@ -281,15 +257,15 @@
}
while (metadata) {
- if (metadata->name) {
- if (metadata->value) {
- if (!(encvalue = util_url_encode(metadata->value))) {
+ if (metadata->key) {
+ if (metadata->val) {
+ if (!(encvalue = util_url_encode(metadata->val))) {
rv = SHOUTERR_MALLOC;
break;
}
- rv = sock_write(socket, "&%s=%s", metadata->name, encvalue);
+ rv = sock_write(socket, "&%s=%s", metadata->key, encvalue);
} else
- rv = sock_write(socket, "&%s", metadata->name);
+ rv = sock_write(socket, "&%s", metadata->key);
free (encvalue);
@@ -659,25 +635,14 @@
return self->dumpfile;
}
-int shout_set_bitrate(shout_t *self, unsigned int bitrate)
+int shout_set_audio_info(shout_t *self, const char *name, const char *value)
{
- if (!self)
- return SHOUTERR_INSANE;
-
- if (self->connected)
- return self->error = SHOUTERR_CONNECTED;
-
- self->bitrate = bitrate;
-
- return self->error = SHOUTERR_SUCCESS;
+ return self->error = util_dict_set(self->audio_info, name, value);
}
-unsigned int shout_get_bitrate(shout_t *self)
+const char *shout_get_audio_info(shout_t *self, const char *name)
{
- if (!self)
- return 0;
-
- return self->bitrate;
+ return util_dict_get(self->audio_info, name);
}
int shout_set_public(shout_t *self, unsigned int public)
@@ -756,6 +721,9 @@
static int send_http_request(shout_t *self, char *username, char *password)
{
char *auth;
+ const char *bitrate;
+
+ bitrate = shout_get_audio_info(self, SHOUT_AI_BITRATE);
if (!sock_write(self->socket, "SOURCE %s HTTP/1.0\r\n", self->mount))
return SHOUTERR_SOCKET;
@@ -778,7 +746,7 @@
if (!sock_write(self->socket, "ice-genre: %s\r\n", self->genre))
return SHOUTERR_SOCKET;
}
- if (self->bitrate && !sock_write(self->socket, "ice-bitrate: %d\r\n", self->bitrate))
+ if (bitrate && !sock_write(self->socket, "ice-bitrate: %s\r\n", bitrate))
return SHOUTERR_SOCKET;
if (!sock_write(self->socket, "ice-public: %d\r\n", self->public))
return SHOUTERR_SOCKET;
@@ -913,6 +881,11 @@
static int login_xaudiocast(shout_t *self)
{
char response[4096];
+ const char *bitrate;
+
+ bitrate = shout_get_audio_info(self, SHOUT_AI_BITRATE);
+ if (!bitrate)
+ bitrate = "0";
if (!sock_write(self->socket, "SOURCE %s %s\n", self->password, self->mount))
return SHOUTERR_SOCKET;
@@ -922,7 +895,7 @@
return SHOUTERR_SOCKET;
if (!sock_write(self->socket, "x-audiocast-genre: %s\n", self->genre != NULL ? self->genre : "icecast"))
return SHOUTERR_SOCKET;
- if (!sock_write(self->socket, "x-audiocast-bitrate: %i\n", self->bitrate))
+ if (!sock_write(self->socket, "x-audiocast-bitrate: %s\n", bitrate))
return SHOUTERR_SOCKET;
if (!sock_write(self->socket, "x-audiocast-public: %i\n", self->public))
return SHOUTERR_SOCKET;
@@ -946,6 +919,11 @@
int login_icy(shout_t *self)
{
char response[4096];
+ const char *bitrate;
+
+ bitrate = shout_get_audio_info(self, SHOUT_AI_BITRATE);
+ if (!bitrate)
+ bitrate = "0";
if (!sock_write(self->socket, "%s\n", self->password))
return SHOUTERR_SOCKET;
@@ -968,7 +946,7 @@
if (!sock_write(self->socket, "icy-genre:%s\n", self->genre != NULL ? self->genre : "icecast"))
return SHOUTERR_SOCKET;
- if (!sock_write(self->socket, "icy-br:%i\n", self->bitrate))
+ if (!sock_write(self->socket, "icy-br:%s\n", bitrate))
return SHOUTERR_SOCKET;
if (!sock_write(self->socket, "\n"))
<p><p>1.9 +3 -8 libshout/src/shout_private.h
Index: shout_private.h
===================================================================
RCS file: /usr/local/cvsroot/libshout/src/shout_private.h,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- shout_private.h 20 Feb 2003 20:34:44 -0000 1.8
+++ shout_private.h 22 Feb 2003 21:08:11 -0000 1.9
@@ -4,6 +4,7 @@
#define __LIBSHOUT_SHOUT_PRIVATE_H__
#include "shout.h"
+#include "util.h"
#include "sock.h"
#include "timing.h"
@@ -49,6 +50,8 @@
unsigned int protocol;
/* type of data being sent */
unsigned int format;
+ /* audio encoding parameters */
+ util_dict *audio_info;
/* user-agent to use when doing HTTP login */
char *useragent;
@@ -66,8 +69,6 @@
char *dumpfile;
/* username to use for HTTP auth. */
char *user;
- /* bitrate of this stream */
- int bitrate;
/* is this stream private? */
int public;
@@ -86,12 +87,6 @@
uint64_t senttime;
int error;
-};
-
-struct shout_metadata {
- char *name;
- char *value;
- shout_metadata_t *next;
};
int shout_open_vorbis(shout_t *self);
<p><p>1.5 +70 -0 libshout/src/util.c
Index: util.c
===================================================================
RCS file: /usr/local/cvsroot/libshout/src/util.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- util.c 13 Jan 2003 04:31:38 -0000 1.4
+++ util.c 22 Feb 2003 21:08:11 -0000 1.5
@@ -7,6 +7,7 @@
#include <sys/types.h>
#include <sys/socket.h>
+#include "shout.h"
#include "util.h"
char *util_strdup(const char *s)
@@ -124,4 +125,73 @@
*q = '\0';
return dest;
+}
+
+util_dict *util_dict_new(void)
+{
+ return (util_dict *)calloc(1, sizeof(util_dict));
+}
+
+void util_dict_free(util_dict *dict)
+{
+ util_dict *cur;
+
+ do {
+ cur = dict->next;
+ if (dict->key)
+ free (dict->key);
+ if (dict->val)
+ free (dict->val);
+ free (dict);
+ } while (cur);
+}
+
+const char *util_dict_get(util_dict *dict, const char *key)
+{
+ while (dict) {
+ if (!strcmp(key, dict->key))
+ return dict->val;
+ dict = dict->next;
+ }
+}
+
+int util_dict_set(util_dict *dict, const char *key, const char *val)
+{
+ util_dict *prev;
+
+ if (!dict || !key)
+ return SHOUTERR_INSANE;
+
+ prev = NULL;
+ while (dict) {
+ if (!dict->key || !strcmp(dict->key, key))
+ break;
+ prev = dict;
+ dict = dict->next;
+ }
+
+ if (!dict) {
+ dict = util_dict_new();
+ if (!dict)
+ return SHOUTERR_MALLOC;
+ if (prev)
+ prev->next = dict;
+ }
+
+ if (dict->key)
+ free (dict->val);
+ else if (!(dict->key = strdup(key))) {
+ if (prev)
+ prev->next = NULL;
+ util_dict_free (dict);
+
+ return SHOUTERR_MALLOC;
+ }
+
+ dict->val = strdup(val);
+ if (!dict->val) {
+ return SHOUTERR_MALLOC;
+ }
+
+ return SHOUTERR_SUCCESS;
}
<p><p>1.4 +15 -0 libshout/src/util.h
Index: util.h
===================================================================
RCS file: /usr/local/cvsroot/libshout/src/util.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- util.h 13 Jan 2003 04:31:38 -0000 1.3
+++ util.h 22 Feb 2003 21:08:11 -0000 1.4
@@ -3,7 +3,22 @@
#ifndef __LIBSHOUT_UTIL_H__
#define __LIBSHOUT_UTIL_H__
+/* String dictionary type, without support for NULL keys, or multiple
+ * instances of the same key */
+typedef struct _util_dict {
+ char *key;
+ char *val;
+ struct _util_dict *next;
+} util_dict;
+
char *util_strdup(const char *s);
+
+util_dict *util_dict_new(void);
+void util_dict_free(util_dict *dict);
+/* dict, key must not be NULL. */
+int util_dict_set(util_dict *dict, const char *key, const char *val);
+const char *util_dict_get(util_dict *dict, const char *key);
+
char *util_base64_encode(char *data);
char *util_url_encode(const char *data);
int util_read_header(int sock, char *buff, unsigned long len);
<p><p>--- >8 ----
List archives: http://www.xiph.org/archives/
Ogg project homepage: http://www.xiph.org/ogg/
To unsubscribe from this list, send a message to 'cvs-request at xiph.org'
containing only the word 'unsubscribe' in the body. No subject is needed.
Unsubscribe messages sent to the list will be ignored/filtered.
More information about the commits
mailing list