mirror of
https://gitlab.xiph.org/xiph/icecast-server.git
synced 2025-02-02 15:07:36 -05:00
Merge mp3 packing. mp3 (and other pass-through streams) can bre received in
very small blocks and go out in those same small blocks increasing the protocol overhead used by the provided. Generally occurs when using a low bitrate stream and many listeners. With this patch we pack out a refbuf before queuing. Add missing include for vorbis build that shows on some platforms svn path=/icecast/trunk/icecast/; revision=9718
This commit is contained in:
parent
c7e04b2852
commit
042ba3b8e2
@ -414,41 +414,78 @@ static void format_mp3_free_plugin(format_plugin_t *self)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* This does the actual reading, making sure the read data is packaged in
|
||||||
|
* blocks of 1400 bytes (near the common MTU size). This is because many
|
||||||
|
* incoming streams come in small packets which could waste a lot of
|
||||||
|
* bandwidth with many listeners due to headers and such like.
|
||||||
|
*/
|
||||||
|
static int complete_read (source_t *source)
|
||||||
|
{
|
||||||
|
int bytes;
|
||||||
|
format_plugin_t *format = source->format;
|
||||||
|
mp3_state *source_mp3 = format->_state;
|
||||||
|
char *buf;
|
||||||
|
refbuf_t *refbuf;
|
||||||
|
|
||||||
|
#define REFBUF_SIZE 1400
|
||||||
|
|
||||||
|
if (source_mp3->read_data == NULL)
|
||||||
|
{
|
||||||
|
source_mp3->read_data = refbuf_new (REFBUF_SIZE);
|
||||||
|
source_mp3->read_count = 0;
|
||||||
|
}
|
||||||
|
buf = source_mp3->read_data->data + source_mp3->read_count;
|
||||||
|
|
||||||
|
bytes = client_read_bytes (source->client, buf, REFBUF_SIZE-source_mp3->read_count);
|
||||||
|
if (bytes < 0)
|
||||||
|
{
|
||||||
|
if (source->client->con->error)
|
||||||
|
{
|
||||||
|
refbuf_release (source_mp3->read_data);
|
||||||
|
source_mp3->read_data = NULL;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
source_mp3->read_count += bytes;
|
||||||
|
refbuf = source_mp3->read_data;
|
||||||
|
refbuf->len = source_mp3->read_count;
|
||||||
|
format->read_bytes += bytes;
|
||||||
|
|
||||||
|
if (source_mp3->read_count < REFBUF_SIZE)
|
||||||
|
{
|
||||||
|
if (source_mp3->read_count == 0)
|
||||||
|
{
|
||||||
|
refbuf_release (source_mp3->read_data);
|
||||||
|
source_mp3->read_data = NULL;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* read an mp3 stream which does not have shoutcast style metadata */
|
/* read an mp3 stream which does not have shoutcast style metadata */
|
||||||
static refbuf_t *mp3_get_no_meta (source_t *source)
|
static refbuf_t *mp3_get_no_meta (source_t *source)
|
||||||
{
|
{
|
||||||
int bytes;
|
|
||||||
refbuf_t *refbuf;
|
refbuf_t *refbuf;
|
||||||
mp3_state *source_mp3 = source->format->_state;
|
mp3_state *source_mp3 = source->format->_state;
|
||||||
format_plugin_t *format = source->format;
|
|
||||||
|
|
||||||
if ((refbuf = refbuf_new (2048)) == NULL)
|
if (complete_read (source) == 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
bytes = client_read_bytes (source->client, refbuf->data, 2048);
|
refbuf = source_mp3->read_data;
|
||||||
if (bytes < 0)
|
source_mp3->read_data = NULL;
|
||||||
{
|
|
||||||
refbuf_release (refbuf);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
format->read_bytes += bytes;
|
|
||||||
if (source_mp3->update_metadata)
|
if (source_mp3->update_metadata)
|
||||||
{
|
{
|
||||||
mp3_set_title (source);
|
mp3_set_title (source);
|
||||||
source_mp3->update_metadata = 0;
|
source_mp3->update_metadata = 0;
|
||||||
}
|
}
|
||||||
if (bytes > 0)
|
|
||||||
{
|
|
||||||
refbuf->len = bytes;
|
|
||||||
refbuf->associated = source_mp3->metadata;
|
refbuf->associated = source_mp3->metadata;
|
||||||
refbuf_addref (source_mp3->metadata);
|
refbuf_addref (source_mp3->metadata);
|
||||||
refbuf->sync_point = 1;
|
refbuf->sync_point = 1;
|
||||||
return refbuf;
|
return refbuf;
|
||||||
}
|
}
|
||||||
refbuf_release (refbuf);
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* read mp3 data with inlined metadata from the source. Filter out the
|
/* read mp3 data with inlined metadata from the source. Filter out the
|
||||||
@ -460,28 +497,23 @@ static refbuf_t *mp3_get_filter_meta (source_t *source)
|
|||||||
refbuf_t *refbuf;
|
refbuf_t *refbuf;
|
||||||
format_plugin_t *plugin = source->format;
|
format_plugin_t *plugin = source->format;
|
||||||
mp3_state *source_mp3 = plugin->_state;
|
mp3_state *source_mp3 = plugin->_state;
|
||||||
format_plugin_t *format = source->format;
|
|
||||||
unsigned char *src;
|
unsigned char *src;
|
||||||
unsigned int bytes, mp3_block;
|
unsigned int bytes, mp3_block;
|
||||||
int ret;
|
|
||||||
|
|
||||||
refbuf = refbuf_new (2048);
|
if (complete_read (source) == 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
refbuf = source_mp3->read_data;
|
||||||
|
source_mp3->read_data = NULL;
|
||||||
src = refbuf->data;
|
src = refbuf->data;
|
||||||
|
|
||||||
ret = client_read_bytes (source->client, refbuf->data, 2048);
|
|
||||||
if (ret < 0)
|
|
||||||
{
|
|
||||||
refbuf_release (refbuf);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
format->read_bytes += ret;
|
|
||||||
if (source_mp3->update_metadata)
|
if (source_mp3->update_metadata)
|
||||||
{
|
{
|
||||||
mp3_set_title (source);
|
mp3_set_title (source);
|
||||||
source_mp3->update_metadata = 0;
|
source_mp3->update_metadata = 0;
|
||||||
}
|
}
|
||||||
/* fill the buffer with the read data */
|
/* fill the buffer with the read data */
|
||||||
bytes = (unsigned int)ret;
|
bytes = source_mp3->read_count;
|
||||||
refbuf->len = 0;
|
refbuf->len = 0;
|
||||||
while (bytes > 0)
|
while (bytes > 0)
|
||||||
{
|
{
|
||||||
@ -556,6 +588,7 @@ static refbuf_t *mp3_get_filter_meta (source_t *source)
|
|||||||
ERROR0 ("Incorrect metadata format, ending stream");
|
ERROR0 ("Incorrect metadata format, ending stream");
|
||||||
source->running = 0;
|
source->running = 0;
|
||||||
refbuf_release (refbuf);
|
refbuf_release (refbuf);
|
||||||
|
refbuf_release (meta);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,8 @@ typedef struct {
|
|||||||
int update_metadata;
|
int update_metadata;
|
||||||
|
|
||||||
refbuf_t *metadata;
|
refbuf_t *metadata;
|
||||||
|
refbuf_t *read_data;
|
||||||
|
unsigned int read_count;
|
||||||
mutex_t url_lock;
|
mutex_t url_lock;
|
||||||
|
|
||||||
unsigned build_metadata_len;
|
unsigned build_metadata_len;
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include <ogg/ogg.h>
|
#include <ogg/ogg.h>
|
||||||
#include <vorbis/codec.h>
|
#include <vorbis/codec.h>
|
||||||
#include <memory.h>
|
#include <memory.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "refbuf.h"
|
#include "refbuf.h"
|
||||||
#include "source.h"
|
#include "source.h"
|
||||||
|
Loading…
Reference in New Issue
Block a user