mirror of
https://gitlab.xiph.org/xiph/icecast-server.git
synced 2024-12-04 14:46:30 -05: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:
parent
744b66c40e
commit
13dc880d29
@ -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 */
|
||||||
|
Loading…
Reference in New Issue
Block a user