Commit 40444f41 authored by Michael Smith's avatar Michael Smith

mp3 metadata work (incomplete)

svn path=/trunk/icecast/; revision=4177
parent 5890aa4f
......@@ -6,6 +6,8 @@
#ifndef __CLIENT_H__
#define __CLIENT_H__
#include "connection.h"
typedef struct _client_tag
{
/* the clients connection */
......
......@@ -31,12 +31,11 @@
#include "refbuf.h"
#include "client.h"
#include "stats.h"
#include "format.h"
#include "logging.h"
#include "xslt.h"
#include "fserve.h"
#include "source.h"
#include "format.h"
#define CATMODULE "connection"
......@@ -482,8 +481,6 @@ static void _handle_get_request(connection_t *con,
{
char *fullpath;
client_t *client;
avl_node *node;
http_var_t *var;
int bytes;
struct stat statbuf;
source_t *source;
......@@ -636,26 +633,10 @@ static void _handle_get_request(connection_t *con,
global.clients++;
global_unlock();
client->respcode = 200;
bytes = sock_write(client->con->sock,
"HTTP/1.0 200 OK\r\n"
"Content-Type: %s\r\n",
format_get_mimetype(source->format->type));
if(bytes > 0) client->con->sent_bytes += bytes;
/* iterate through source http headers and send to client */
avl_tree_rlock(source->parser->vars);
node = avl_get_first(source->parser->vars);
while (node) {
var = (http_var_t *)node->key;
if (strcasecmp(var->name, "ice-password") &&
!strncasecmp("ice-", var->name, 4)) {
bytes = sock_write(client->con->sock,
"%s: %s\r\n", var->name, var->value);
if(bytes > 0) client->con->sent_bytes += bytes;
}
node = avl_get_next(node);
}
avl_tree_unlock(source->parser->vars);
client->format_data = source->format->create_client_data(
source->format, source, client);
source->format->client_send_headers(source->format, source, client);
bytes = sock_write(client->con->sock, "\r\n");
if(bytes > 0) client->con->sent_bytes += bytes;
......
......@@ -11,6 +11,7 @@
#include "connection.h"
#include "refbuf.h"
#include "source.h"
#include "format.h"
#include "format_vorbis.h"
......@@ -84,3 +85,27 @@ int format_generic_write_buf_to_client(format_plugin_t *format,
return ret;
}
void format_send_general_headers(format_plugin_t *format,
source_t *source, client_t *client)
{
http_var_t *var;
avl_node *node;
int bytes;
/* iterate through source http headers and send to client */
avl_tree_rlock(source->parser->vars);
node = avl_get_first(source->parser->vars);
while (node) {
var = (http_var_t *)node->key;
if (strcasecmp(var->name, "ice-password") &&
(!strncasecmp("ice-", var->name, 4) ||
!strncasecmp("icy-", var->name, 4))) {
bytes = sock_write(client->con->sock,
"%s: %s\r\n", var->name, var->value);
if(bytes > 0) client->con->sent_bytes += bytes;
}
node = avl_get_next(node);
}
avl_tree_unlock(source->parser->vars);
}
......@@ -9,6 +9,8 @@
#include "client.h"
#include "refbuf.h"
struct source_tag;
typedef enum _format_type_tag
{
FORMAT_TYPE_VORBIS,
......@@ -34,7 +36,10 @@ typedef struct _format_plugin_tag
refbuf_queue_t *(*get_predata)(struct _format_plugin_tag *self);
int (*write_buf_to_client)(struct _format_plugin_tag *format,
client_t *client, unsigned char *buf, int len);
void *(*create_client_data)(struct _format_plugin_tag *format);
void *(*create_client_data)(struct _format_plugin_tag *format,
struct source_tag *source, client_t *client);
void (*client_send_headers)(struct _format_plugin_tag *format,
struct source_tag *source, client_t *client);
void (*free_plugin)(struct _format_plugin_tag *self);
......@@ -48,6 +53,8 @@ format_plugin_t *format_get_plugin(format_type_t type, char *mount);
int format_generic_write_buf_to_client(format_plugin_t *format,
client_t *client, unsigned char *buf, int len);
void format_send_general_headers(format_plugin_t *format,
struct source_tag *source, client_t *client);
#endif /* __FORMAT_H__ */
......
/* format_mp3.c
**
** format plugin for mp3 (no metadata)
** format plugin for mp3
**
*/
......@@ -9,15 +9,38 @@
#include <string.h>
#include "refbuf.h"
#include "source.h"
#include "client.h"
#include "stats.h"
#include "format.h"
#include "httpp/httpp.h"
#include "log.h"
#include "logging.h"
#include "format_mp3.h"
#define CATMODULE "format-mp3"
#define ICY_METADATA_INTERVAL 16000
static void format_mp3_free_plugin(format_plugin_t *self);
static int format_mp3_get_buffer(format_plugin_t *self, char *data,
unsigned long len, refbuf_t **buffer);
static refbuf_queue_t *format_mp3_get_predata(format_plugin_t *self);
static void *format_mp3_create_client_data(format_plugin_t *self);
static void *format_mp3_create_client_data(format_plugin_t *self,
source_t *source, client_t *client);
static int format_mp3_write_buf_to_client(format_plugin_t *self,
client_t *client, unsigned char *buf, int len);
static void format_mp3_send_headers(format_plugin_t *self,
source_t *source, client_t *client);
typedef struct {
int interval;
int offset;
int metadata;
} mp3_client_data;
format_plugin_t *format_mp3_get_plugin(void)
{
......@@ -29,23 +52,44 @@ format_plugin_t *format_mp3_get_plugin(void)
plugin->has_predata = 0;
plugin->get_buffer = format_mp3_get_buffer;
plugin->get_predata = format_mp3_get_predata;
plugin->write_buf_to_client = format_generic_write_buf_to_client;
plugin->write_buf_to_client = format_mp3_write_buf_to_client;
plugin->create_client_data = format_mp3_create_client_data;
plugin->client_send_headers = format_mp3_send_headers;
plugin->free_plugin = format_mp3_free_plugin;
plugin->format_description = "MP3 audio";
plugin->_state = NULL;
plugin->_state = calloc(1, sizeof(mp3_state));
return plugin;
}
void format_mp3_free_plugin(format_plugin_t *self)
static int format_mp3_write_buf_to_client(format_plugin_t *self,
client_t *client, unsigned char *buf, int len)
{
int ret;
ret = sock_write_bytes(client->con->sock, buf, len);
if(ret < 0) {
if(sock_recoverable(ret)) {
DEBUG1("Client had recoverable error %ld", ret);
ret = 0;
}
}
else
client->con->sent_bytes += ret;
return ret;
}
static void format_mp3_free_plugin(format_plugin_t *self)
{
/* free the plugin instance */
free(self);
}
int format_mp3_get_buffer(format_plugin_t *self, char *data, unsigned long len, refbuf_t **buffer)
static int format_mp3_get_buffer(format_plugin_t *self, char *data,
unsigned long len, refbuf_t **buffer)
{
refbuf_t *refbuf;
if(!data) {
......@@ -60,13 +104,50 @@ int format_mp3_get_buffer(format_plugin_t *self, char *data, unsigned long len,
return 0;
}
refbuf_queue_t *format_mp3_get_predata(format_plugin_t *self)
static refbuf_queue_t *format_mp3_get_predata(format_plugin_t *self)
{
return NULL;
}
static void *format_mp3_create_client_data(format_plugin_t *self) {
return NULL;
static void *format_mp3_create_client_data(format_plugin_t *self,
source_t *source, client_t *client)
{
mp3_client_data *data = calloc(1,sizeof(mp3_client_data));
char *metadata;
data->interval = ICY_METADATA_INTERVAL;
data->offset = 0;
metadata = httpp_getvar(source->parser, "icy-metadata");
if(metadata)
data->metadata = atoi(metadata)>0?1:0;
return data;
}
static void format_mp3_send_headers(format_plugin_t *self,
source_t *source, client_t *client)
{
int bytes;
client->respcode = 200;
bytes = sock_write(client->con->sock,
"HTTP/1.0 200 OK\r\n"
"Content-Type: %s\r\n",
format_get_mimetype(source->format->type));
if(bytes > 0) client->con->sent_bytes += bytes;
format_send_general_headers(self, source, client);
if(0 && ((mp3_client_data *)(client->format_data))->metadata) {
int bytes = sock_write(client->con->sock, "icy-metaint: %d\r\n",
ICY_METADATA_INTERVAL);
if(bytes > 0)
client->con->sent_bytes += bytes;
}
}
......@@ -6,6 +6,11 @@
#ifndef __FORMAT_MP3_H__
#define __FORMAT_MP3_H__
typedef struct {
char *metadata;
int metadata_age;
} mp3_state;
format_plugin_t *format_mp3_get_plugin(void);
#endif /* __FORMAT_MP3_H__ */
......@@ -12,6 +12,8 @@
#include <vorbis/codec.h>
#include "refbuf.h"
#include "source.h"
#include "client.h"
#include "stats.h"
#include "format.h"
......@@ -40,7 +42,10 @@ static void format_vorbis_free_plugin(format_plugin_t *self);
static int format_vorbis_get_buffer(format_plugin_t *self, char *data,
unsigned long len, refbuf_t **buffer);
static refbuf_queue_t *format_vorbis_get_predata(format_plugin_t *self);
static void *format_vorbis_create_client_data(format_plugin_t *self);
static void *format_vorbis_create_client_data(format_plugin_t *self,
source_t *source, client_t *client);
static void format_vorbis_send_headers(format_plugin_t *self,
source_t *source, client_t *client);
format_plugin_t *format_vorbis_get_plugin(void)
{
......@@ -55,6 +60,7 @@ format_plugin_t *format_vorbis_get_plugin(void)
plugin->get_predata = format_vorbis_get_predata;
plugin->write_buf_to_client = format_generic_write_buf_to_client;
plugin->create_client_data = format_vorbis_create_client_data;
plugin->client_send_headers = format_vorbis_send_headers;
plugin->free_plugin = format_vorbis_free_plugin;
plugin->format_description = "Ogg Vorbis";
......@@ -218,8 +224,26 @@ refbuf_queue_t *format_vorbis_get_predata(format_plugin_t *self)
return queue;
}
static void *format_vorbis_create_client_data(format_plugin_t *self) {
static void *format_vorbis_create_client_data(format_plugin_t *self,
source_t *source, client_t *client)
{
return NULL;
}
static void format_vorbis_send_headers(format_plugin_t *self,
source_t *source, client_t *client)
{
int bytes;
client->respcode = 200;
bytes = sock_write(client->con->sock,
"HTTP/1.0 200 OK\r\n"
"Content-Type: %s\r\n",
format_get_mimetype(source->format->type));
if(bytes > 0) client->con->sent_bytes += bytes;
format_send_general_headers(self, source, client);
}
......@@ -4,9 +4,9 @@
#include "httpp.h"
#include "connection.h"
#include "refbuf.h"
#include "format.h"
#include "client.h"
#include "source.h"
#include "format.h"
#include "global.h"
......
......@@ -37,10 +37,9 @@
#include "refbuf.h"
#include "client.h"
#include "stats.h"
#include "format.h"
#include "logging.h"
#include "source.h"
#include "format.h"
#define CATMODULE "slave"
......
......@@ -23,13 +23,12 @@
#include "refbuf.h"
#include "client.h"
#include "stats.h"
#include "format.h"
#include "log.h"
#include "logging.h"
#include "config.h"
#include "util.h"
#include "source.h"
#include "format.h"
#undef CATMODULE
#define CATMODULE "source"
......@@ -325,8 +324,6 @@ void *source_main(void *arg)
*/
if (source->format->has_predata) {
client = (client_t *)client_node->key;
client->format_data = source->format->create_client_data(
source->format);
client->queue = source->format->get_predata(source->format);
}
......
#ifndef __SOURCE_H__
#define __SOURCE_H__
#include "format.h"
typedef struct source_tag
{
client_t *client;
......@@ -8,7 +10,7 @@ typedef struct source_tag
http_parser_t *parser;
char *mount;
format_plugin_t *format;
struct _format_plugin_tag *format;
avl_tree *client_tree;
avl_tree *pending_tree;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment