1
0
mirror of https://gitlab.xiph.org/xiph/icecast-server.git synced 2024-09-29 04:25:55 -04: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_STATE_READING_CLUSTERS
} ebml_read_mode; } 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; typedef struct ebml_client_data_st ebml_client_data_t;
struct ebml_client_data_st { struct ebml_client_data_st {
@ -81,8 +88,7 @@ static void ebml_free_client_data(client_t *client);
static ebml_t *ebml_create(); static ebml_t *ebml_create();
static void ebml_destroy(ebml_t *ebml); static void ebml_destroy(ebml_t *ebml);
static int ebml_read_space(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_read(ebml_t *ebml, char *buffer, int len, ebml_chunk_type *chunk_type);
static int ebml_last_was_sync(ebml_t *ebml);
static char *ebml_write_buffer(ebml_t *ebml, int len); static char *ebml_write_buffer(ebml_t *ebml, int len);
static int ebml_wrote(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; format_plugin_t *format = source->format;
char *data = NULL; char *data = NULL;
int bytes = 0; int bytes = 0;
ebml_chunk_type chunk_type;
refbuf_t *refbuf; refbuf_t *refbuf;
int ret; int ret;
@ -189,7 +196,7 @@ static refbuf_t *ebml_get_buffer(source_t *source)
{ {
/* A chunk is available for reading */ /* A chunk is available for reading */
refbuf = refbuf_new(bytes); 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) if (ebml_source_state->header == NULL)
{ {
@ -198,9 +205,14 @@ static refbuf_t *ebml_get_buffer(source_t *source)
continue; 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; refbuf->sync_point = 1;
/* ICECAST_LOG_DEBUG("EBML: ^ was sync point"); */
} }
return refbuf; return refbuf;
@ -315,7 +327,7 @@ static ebml_t *ebml_create()
ebml->cluster_id = "\x1F\x43\xB6\x75"; ebml->cluster_id = "\x1F\x43\xB6\x75";
ebml->cluster_start = -2; ebml->cluster_start = -1;
return ebml; return ebml;
@ -347,10 +359,8 @@ static int ebml_read_space(ebml_t *ebml)
/* return up until just before a new cluster starts */ /* return up until just before a new cluster starts */
read_space = ebml->cluster_start; read_space = ebml->cluster_start;
} else { } else {
/* return most of what we have, but leave enough unread /* return what we have */
* to detect the next cluster. read_space = ebml->position;
*/
read_space = ebml->position - 4;
} }
return read_space; return read_space;
@ -363,13 +373,18 @@ static int ebml_read_space(ebml_t *ebml)
/* Return a chunk of the EBML/MKV/WebM stream. /* Return a chunk of the EBML/MKV/WebM stream.
* The header will be buffered until it can be returned as one chunk. * 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. * 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 read_space;
int to_read; int to_read;
*chunk_type = EBML_CHUNK_HEADER;
if (len < 1) { if (len < 1) {
return 0; return 0;
} }
@ -391,6 +406,8 @@ static int ebml_read(ebml_t *ebml, char *buffer, int len)
memcpy(buffer, ebml->header, to_read); memcpy(buffer, ebml->header, to_read);
ebml->header_read_position += to_read; ebml->header_read_position += to_read;
*chunk_type = EBML_CHUNK_HEADER;
if (ebml->header_read_position == ebml->header_size) { if (ebml->header_read_position == ebml->header_size) {
ebml->output_state = EBML_STATE_READING_CLUSTERS; 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: 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 */ /* return up until just before a new cluster starts */
read_space = ebml->cluster_start; read_space = ebml->cluster_start;
} else {
read_space = ebml->position - 4;
} }
if (read_space < 1) { 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) 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); 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. /* Scan for cluster start marker.
* False positives are possible, but unlikely, and only * 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; ebml->position = len - b;
/* Mark the start of the data as the first sync point */ /* Mark the start of the data as the first sync point */
ebml->cluster_start = -1; ebml->cluster_start = 0;
return len; return len;
} else { } else {
/* We've located a sync point in the data stream */ /* We've located a sync point in the data stream */