1
0
mirror of https://gitlab.xiph.org/xiph/icecast-server.git synced 2024-06-23 06:25:24 +00:00

Yield sync point status from ebml_read directly.

This simplifies some fragile "was the last chunk a sync point?" logic.
This commit is contained in:
Joseph Wallace 2015-11-21 03:16:07 -05:00
parent 744b66c40e
commit 13dc880d29

View File

@ -44,6 +44,13 @@ typedef enum ebml_read_mode {
EBML_STATE_READING_CLUSTERS
} ebml_read_mode;
typedef enum ebml_chunk_type {
EBML_CHUNK_HEADER = 0,
EBML_CHUNK_CLUSTER_START,
EBML_CHUNK_CLUSTER_CONTINUE
} ebml_chunk_type;
typedef struct ebml_client_data_st ebml_client_data_t;
struct ebml_client_data_st {
@ -81,8 +88,7 @@ static void ebml_free_client_data(client_t *client);
static ebml_t *ebml_create();
static void ebml_destroy(ebml_t *ebml);
static int ebml_read_space(ebml_t *ebml);
static int ebml_read(ebml_t *ebml, char *buffer, int len);
static int ebml_last_was_sync(ebml_t *ebml);
static int ebml_read(ebml_t *ebml, char *buffer, int len, ebml_chunk_type *chunk_type);
static char *ebml_write_buffer(ebml_t *ebml, int len);
static int ebml_wrote(ebml_t *ebml, int len);
@ -179,6 +185,7 @@ static refbuf_t *ebml_get_buffer(source_t *source)
format_plugin_t *format = source->format;
char *data = NULL;
int bytes = 0;
ebml_chunk_type chunk_type;
refbuf_t *refbuf;
int ret;
@ -189,7 +196,7 @@ static refbuf_t *ebml_get_buffer(source_t *source)
{
/* A chunk is available for reading */
refbuf = refbuf_new(bytes);
ebml_read(ebml_source_state->ebml, refbuf->data, bytes);
ebml_read(ebml_source_state->ebml, refbuf->data, bytes, &chunk_type);
if (ebml_source_state->header == NULL)
{
@ -198,9 +205,14 @@ static refbuf_t *ebml_get_buffer(source_t *source)
continue;
}
if (ebml_last_was_sync(ebml_source_state->ebml))
/* ICECAST_LOG_DEBUG("EBML: generated refbuf, size %i : %hhi %hhi %hhi",
* bytes, refbuf->data[0], refbuf->data[1], refbuf->data[2]);
*/
if (chunk_type == EBML_CHUNK_CLUSTER_START)
{
refbuf->sync_point = 1;
/* ICECAST_LOG_DEBUG("EBML: ^ was sync point"); */
}
return refbuf;
@ -315,7 +327,7 @@ static ebml_t *ebml_create()
ebml->cluster_id = "\x1F\x43\xB6\x75";
ebml->cluster_start = -2;
ebml->cluster_start = -1;
return ebml;
@ -347,10 +359,8 @@ static int ebml_read_space(ebml_t *ebml)
/* return up until just before a new cluster starts */
read_space = ebml->cluster_start;
} else {
/* return most of what we have, but leave enough unread
* to detect the next cluster.
*/
read_space = ebml->position - 4;
/* return what we have */
read_space = ebml->position;
}
return read_space;
@ -363,12 +373,17 @@ static int ebml_read_space(ebml_t *ebml)
/* Return a chunk of the EBML/MKV/WebM stream.
* The header will be buffered until it can be returned as one chunk.
* A cluster element's opening tag will always start a new chunk.
*
* chunk_type will be set to indicate if the chunk is the header,
* the start of a cluster, or continuing the current cluster.
*/
static int ebml_read(ebml_t *ebml, char *buffer, int len)
static int ebml_read(ebml_t *ebml, char *buffer, int len, ebml_chunk_type *chunk_type)
{
int read_space;
int to_read;
*chunk_type = EBML_CHUNK_HEADER;
if (len < 1) {
return 0;
@ -390,7 +405,9 @@ static int ebml_read(ebml_t *ebml, char *buffer, int len)
memcpy(buffer, ebml->header, to_read);
ebml->header_read_position += to_read;
*chunk_type = EBML_CHUNK_HEADER;
if (ebml->header_read_position == ebml->header_size) {
ebml->output_state = EBML_STATE_READING_CLUSTERS;
}
@ -403,11 +420,18 @@ static int ebml_read(ebml_t *ebml, char *buffer, int len)
case EBML_STATE_READING_CLUSTERS:
if (ebml->cluster_start > 0) {
*chunk_type = EBML_CHUNK_CLUSTER_CONTINUE;
read_space = ebml->position;
if (ebml->cluster_start == 0) {
/* new cluster is starting now */
*chunk_type = EBML_CHUNK_CLUSTER_START;
/* mark end of cluster */
ebml->cluster_start = -1;
} else if (ebml->cluster_start > 0) {
/* return up until just before a new cluster starts */
read_space = ebml->cluster_start;
} else {
read_space = ebml->position - 4;
}
if (read_space < 1) {
@ -437,32 +461,6 @@ static int ebml_read(ebml_t *ebml, char *buffer, int len)
}
/* Return nonzero if the chunk last returned by ebml_read was
* a sync point.
*/
static int ebml_last_was_sync(ebml_t *ebml)
{
if (ebml->cluster_start == 0) {
/* The data buffer now starts with a cluster, so the chunk
* just removed from it was (probably) not a cluster's start.
*/
ebml->cluster_start -= 1;
return 0;
}
if (ebml->cluster_start == -1) {
/* Above logic triggered for the previous chunk, therefore the
* chunk just removed was a cluster's start.
*/
ebml->cluster_start -= 1;
return 1;
}
return 0;
}
static char *ebml_write_buffer(ebml_t *ebml, int len)
{
@ -496,7 +494,7 @@ static int ebml_wrote(ebml_t *ebml, int len)
memcpy(ebml->buffer + ebml->position, ebml->input_buffer, len);
}
for (b = 0; b < len - 4; b++)
for (b = 0; b <= len - 4; b++)
{
/* Scan for cluster start marker.
* False positives are possible, but unlikely, and only
@ -520,7 +518,7 @@ static int ebml_wrote(ebml_t *ebml, int len)
ebml->position = len - b;
/* Mark the start of the data as the first sync point */
ebml->cluster_start = -1;
ebml->cluster_start = 0;
return len;
} else {
/* We've located a sync point in the data stream */