format_ebml.c 31.8 KB
Newer Older
1 2
/* Icecast
 *
3
 * This program is distributed under the GNU General Public License,
4 5 6
 * version 2. A copy of this license is included with this source.
 * At your option, this specific source file can also be distributed
 * under the GNU GPL version 3.
7
 *
8
 * Copyright 2012,      David Richards, Mozilla Foundation,
9
 *                      and others (see AUTHORS for details).
10
 * Copyright 2014,      Philipp "ph3-der-loewe" Schafft <lion@lion.leolix.org>.
11 12 13 14
 */

/* format_ebml.c
 *
giles's avatar
giles committed
15
 * format plugin for WebM/EBML
16 17 18 19 20 21 22
 *
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

23
#include <stdbool.h>
24
#include <stdint.h>
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "refbuf.h"
#include "source.h"
#include "client.h"

#include "stats.h"
#include "format.h"
#include "format_ebml.h"

#define CATMODULE "format-ebml"

#include "logging.h"

41 42 43
/* The size of the header buffer; should be large enough to contain
 * everything before the first Cluster in a reasonable stream
 */
44
#define EBML_HEADER_MAX_SIZE 131072
45 46 47 48 49 50 51

/* The size of the input/staging buffers; this much of a cluster
 * will be buffered before being returned. Should be large enough
 * that the first video block will be encountered before it is full,
 * to allow probing for the keyframe flag while we still have the
 * option to mark the cluster as a sync point.
 */
52 53
#define EBML_SLICE_SIZE 4096

54
/* A value that no EBML var-int is allowed to take. */
55
#define EBML_UNKNOWN ((uint_least64_t) -1)
56

57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
/* The magic numbers for each element we are interested in.
 * Defined here:
 * http://www.matroska.org/technical/specs/index.html
 * http://www.webmproject.org/docs/container/
 *
 * Some of the higher-level elements have 4-byte identifiers;
 * The lower-level elements have 1-byte identifiers.
 */
#define UNCOMMON_MAGIC_LEN 4

#define SEGMENT_MAGIC "\x18\x53\x80\x67"
#define CLUSTER_MAGIC "\x1F\x43\xB6\x75"
#define TRACKS_MAGIC "\x16\x54\xAE\x6B"

#define COMMON_MAGIC_LEN 1

#define TRACK_ENTRY_MAGIC "\xAE"
#define TRACK_NUMBER_MAGIC "\xD7"
#define TRACK_TYPE_MAGIC "\x83"
#define SIMPLE_BLOCK_MAGIC "\xA3"

78 79 80 81
/* If support for Tags gets added, it may make sense
 * to convert this into a pair of flags signaling
 * "new headers" and "new tags"
 */
82
typedef enum ebml_read_mode {
83
    /* The header buffer has not been extracted yet */
84
    EBML_STATE_READING_HEADER = 0,
85
    /* The header buffer has been read, begin normal operation */
86 87
    EBML_STATE_READING_CLUSTERS
} ebml_read_mode;
88

Joseph Wallace's avatar
Joseph Wallace committed
89
typedef enum ebml_parsing_state {
90
    /* Examine EBML elements, output to header buffer */
Joseph Wallace's avatar
Joseph Wallace committed
91
    EBML_STATE_PARSING_HEADER = 0,
92 93

    /* Blindly copy a specified number of bytes to the header buffer */
Joseph Wallace's avatar
Joseph Wallace committed
94
    EBML_STATE_COPYING_TO_HEADER,
95 96

    /* Finalize header buffer and wait for previous cluster to flush (as necessary) */
Joseph Wallace's avatar
Joseph Wallace committed
97
    EBML_STATE_START_CLUSTER,
98 99

    /* Examine EBML elements, output to data buffer */
Joseph Wallace's avatar
Joseph Wallace committed
100
    EBML_STATE_PARSING_CLUSTERS,
101 102

    /* Blindly copy a specified number of bytes to the data buffer */
Joseph Wallace's avatar
Joseph Wallace committed
103 104 105
    EBML_STATE_COPYING_TO_DATA
} ebml_parsing_state;

106
typedef enum ebml_chunk_type {
107
    /* This chunk is the header buffer */
108
    EBML_CHUNK_HEADER = 0,
109 110

    /* This chunk starts a cluster that works as a sync point */
111
    EBML_CHUNK_CLUSTER_START,
112 113 114 115

    /* This chunk continues the previous cluster, or
     * else starts a non-sync-point cluster
     */
116 117 118
    EBML_CHUNK_CLUSTER_CONTINUE
} ebml_chunk_type;

119
typedef enum ebml_keyframe_status {
120
    /* Have not found a video track block yet */
121
    EBML_KEYFRAME_UNKNOWN = -1,
122 123

    /* Found the first video track block, it was not a keyframe */
124
    EBML_KEYFRAME_DOES_NOT_START_CLUSTER = 0,
125 126

    /* Found the first video track block, it was a keyframe */
127 128 129
    EBML_KEYFRAME_STARTS_CLUSTER = 1
} ebml_keyframe_status;

130
typedef struct ebml_st {
131

132
    ebml_read_mode output_state;
Joseph Wallace's avatar
Joseph Wallace committed
133
    ebml_parsing_state parse_state;
134
    uint_least64_t copy_len;
135

136
    ssize_t cluster_start;
137
    ebml_keyframe_status cluster_starts_with_keyframe;
138
    bool flush_cluster;
139

140
    size_t position;
141
    unsigned char *buffer;
142

143
    size_t input_position;
144
    unsigned char *input_buffer;
145

146 147 148
    size_t header_size;
    size_t header_position;
    size_t header_read_position;
149
    unsigned char *header;
150

151 152
    uint_least64_t keyframe_track_number;
    uint_least64_t parsing_track_number;
153
    bool parsing_track_is_video;
154 155 156 157 158 159
} ebml_t;

typedef struct ebml_source_state_st {

    ebml_t *ebml;
    refbuf_t *header;
160
    bool file_headers_written;
161 162 163 164 165 166 167 168 169

} ebml_source_state_t;

typedef struct ebml_client_data_st {

    refbuf_t *header;
    size_t header_pos;

} ebml_client_data_t;
170

171 172 173 174 175 176
static void ebml_free_plugin(format_plugin_t *plugin);
static refbuf_t *ebml_get_buffer(source_t *source);
static int ebml_write_buf_to_client(client_t *client);
static void ebml_write_buf_to_file(source_t *source, refbuf_t *refbuf);
static int ebml_create_client_data(source_t *source, client_t *client);
static void ebml_free_client_data(client_t *client);
177 178 179

static ebml_t *ebml_create();
static void ebml_destroy(ebml_t *ebml);
180 181 182 183 184
static size_t ebml_read_space(ebml_t *ebml);
static size_t ebml_read(ebml_t *ebml, char *buffer, size_t len, ebml_chunk_type *chunk_type);
static unsigned char *ebml_get_write_buffer(ebml_t *ebml, size_t *bytes);
static ssize_t ebml_wrote(ebml_t *ebml, size_t len);
static ssize_t ebml_parse_tag(unsigned char      *buffer,
185
                              unsigned char      *buffer_end,
186
                              uint_least64_t *payload_length);
187 188
static ssize_t ebml_parse_var_int(unsigned char      *buffer,
                                  unsigned char      *buffer_end,
189
                                  uint_least64_t *out_value);
190 191 192
static ssize_t ebml_parse_sized_int(unsigned char      *buffer,
                                    unsigned char      *buffer_end,
                                    size_t             len,
193
                                    bool                is_signed,
194
                                    uint_least64_t *out_value);
195
static inline void ebml_check_track(ebml_t *ebml);
196

197
int format_ebml_get_plugin(source_t *source)
198 199 200 201 202 203 204 205 206 207 208 209 210
{

    ebml_source_state_t *ebml_source_state = calloc(1, sizeof(ebml_source_state_t));
    format_plugin_t *plugin = calloc(1, sizeof(format_plugin_t));

    plugin->get_buffer = ebml_get_buffer;
    plugin->write_buf_to_client = ebml_write_buf_to_client;
    plugin->create_client_data = ebml_create_client_data;
    plugin->free_plugin = ebml_free_plugin;
    plugin->write_buf_to_file = ebml_write_buf_to_file;
    plugin->set_tag = NULL;
    plugin->apply_settings = NULL;

211
    plugin->contenttype = httpp_getvar(source->parser, "content-type");
212 213

    plugin->_state = ebml_source_state;
214
    vorbis_comment_init(&plugin->vc);
215 216 217
    source->format = plugin;

    ebml_source_state->ebml = ebml_create();
218

219 220 221
    return 0;
}

222
static void ebml_free_plugin(format_plugin_t *plugin)
223 224 225 226
{

    ebml_source_state_t *ebml_source_state = plugin->_state;

227
    refbuf_release(ebml_source_state->header);
228
    ebml_destroy(ebml_source_state->ebml);
229
    free(ebml_source_state);
230
    vorbis_comment_clear(&plugin->vc);
231
    free(plugin);
232 233
}

234 235
/* Write to a client from the header buffer.
 */
236
static int send_ebml_header(client_t *client)
237 238 239
{

    ebml_client_data_t *ebml_client_data = client->format_data;
240
    size_t len = EBML_SLICE_SIZE;
241 242
    int ret;

243
    if (ebml_client_data->header->len - ebml_client_data->header_pos < len)
244 245 246
    {
        len = ebml_client_data->header->len - ebml_client_data->header_pos;
    }
247
    ret = client_send_bytes (client,
248 249 250 251 252 253 254 255 256 257 258 259
                             ebml_client_data->header->data + ebml_client_data->header_pos,
                             len);

    if (ret > 0)
    {
        ebml_client_data->header_pos += ret;
    }

    return ret;

}

260 261
/* Initial write-to-client function.
 */
262 263 264 265 266 267 268 269 270 271 272
static int ebml_write_buf_to_client (client_t *client)
{

    ebml_client_data_t *ebml_client_data = client->format_data;

    if (ebml_client_data->header_pos != ebml_client_data->header->len)
    {
        return send_ebml_header (client);
    }
    else
    {
273 274
        /* Now that the header's sent, short-circuit to the generic
         * write-refbufs function. */
275 276 277 278 279 280
        client->write_to_client = format_generic_write_to_client;
        return client->write_to_client(client);
    }

}

281 282
/* Return a refbuf to add to the queue.
 */
283
static refbuf_t *ebml_get_buffer(source_t *source)
284 285 286 287
{

    ebml_source_state_t *ebml_source_state = source->format->_state;
    format_plugin_t *format = source->format;
288
    unsigned char *write_buffer = NULL;
289
    ssize_t read_bytes = 0;
290
    size_t write_bytes = 0;
291
    ebml_chunk_type chunk_type;
292
    refbuf_t *refbuf;
293
    ssize_t ret;
294 295 296

    while (1)
    {
297 298
        read_bytes = ebml_read_space(ebml_source_state->ebml);
        if (read_bytes > 0) {
299
            /* A chunk is available for reading */
300 301
            refbuf = refbuf_new(read_bytes);
            ebml_read(ebml_source_state->ebml, refbuf->data, read_bytes, &chunk_type);
302 303 304

            if (ebml_source_state->header == NULL)
            {
305
                /* Capture header before adding clusters to the queue */
306 307 308 309
                ebml_source_state->header = refbuf;
                continue;
            }

310
            if (chunk_type == EBML_CHUNK_CLUSTER_START)
311 312 313 314 315
            {
                refbuf->sync_point = 1;
            }
            return refbuf;

316
        } else if(read_bytes == 0) {
317
            /* Feed more bytes into the parser */
318 319 320
            write_buffer = ebml_get_write_buffer(ebml_source_state->ebml, &write_bytes);
            read_bytes = client_read_bytes (source->client, write_buffer, write_bytes);
            if (read_bytes <= 0) {
321 322 323
                ebml_wrote (ebml_source_state->ebml, 0);
                return NULL;
            }
324 325 326
            format->read_bytes += read_bytes;
            ret = ebml_wrote (ebml_source_state->ebml, read_bytes);
            if (ret != read_bytes) {
327
                ICECAST_LOG_ERROR("Problem processing stream");
328 329 330
                source->running = 0;
                return NULL;
            }
331 332 333 334
        } else {
            ICECAST_LOG_ERROR("Problem processing stream");
            source->running = 0;
            return NULL;
335 336 337 338
        }
    }
}

339 340
/* Initialize client state.
 */
341
static int ebml_create_client_data(source_t *source, client_t *client)
342
{
343
    ebml_client_data_t *ebml_client_data;
344 345
    ebml_source_state_t *ebml_source_state = source->format->_state;

346 347
    if (!ebml_source_state->header)
        return -1;
348

349 350 351
    ebml_client_data = calloc(1, sizeof(ebml_client_data_t));
    if (!ebml_client_data)
        return -1;
352

353 354 355 356 357
    ebml_client_data->header = ebml_source_state->header;
    refbuf_addref(ebml_client_data->header);
    client->format_data = ebml_client_data;
    client->free_client_data = ebml_free_client_data;
    return 0;
358 359 360 361 362 363 364 365 366 367 368 369 370 371
}

static void ebml_free_client_data (client_t *client)
{

    ebml_client_data_t *ebml_client_data = client->format_data;

    refbuf_release (ebml_client_data->header);
    free (client->format_data);
    client->format_data = NULL;
}

static void ebml_write_buf_to_file_fail (source_t *source)
{
372
    ICECAST_LOG_WARN("Write to dump file failed, disabling");
373 374 375 376 377 378 379 380 381
    fclose (source->dumpfile);
    source->dumpfile = NULL;
}

static void ebml_write_buf_to_file (source_t *source, refbuf_t *refbuf)
{

    ebml_source_state_t *ebml_source_state = source->format->_state;

382
    if ( ! ebml_source_state->file_headers_written)
383 384
    {
        if (fwrite (ebml_source_state->header->data, 1,
385
                    ebml_source_state->header->len,
386 387 388
                    source->dumpfile) != ebml_source_state->header->len)
            ebml_write_buf_to_file_fail(source);
        else
389
            ebml_source_state->file_headers_written = true;
390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415
    }

    if (fwrite (refbuf->data, 1, refbuf->len, source->dumpfile) != refbuf->len)
    {
        ebml_write_buf_to_file_fail(source);
    }

}

/* internal ebml parsing */

static void ebml_destroy(ebml_t *ebml)
{

    free(ebml->header);
    free(ebml->input_buffer);
    free(ebml->buffer);
    free(ebml);

}

static ebml_t *ebml_create()
{

    ebml_t *ebml = calloc(1, sizeof(ebml_t));

416 417
    ebml->output_state = EBML_STATE_READING_HEADER;

418
    ebml->header = calloc(1, EBML_HEADER_MAX_SIZE);
Joseph Wallace's avatar
Joseph Wallace committed
419
    ebml->buffer = calloc(1, EBML_SLICE_SIZE);
420 421
    ebml->input_buffer = calloc(1, EBML_SLICE_SIZE);

422
    ebml->cluster_start = -1;
423

424 425
    ebml->keyframe_track_number = EBML_UNKNOWN;
    ebml->parsing_track_number = EBML_UNKNOWN;
426
    ebml->parsing_track_is_video = false;
427 428 429 430 431

    return ebml;

}

432 433 434
/* Return the size of a buffer needed to store the next
 * chunk that ebml_read can yield.
 */
435
static size_t ebml_read_space(ebml_t *ebml)
436 437
{

438
    size_t read_space;
439

440 441
    switch (ebml->output_state) {
        case EBML_STATE_READING_HEADER:
442

443 444 445 446 447 448 449 450
            if (ebml->header_size != 0) {
                /* The header can be read */
                return ebml->header_size;
            } else {
                /* The header's not ready yet */
                return 0;
            }
            break;
451

452
        case EBML_STATE_READING_CLUSTERS:
453

454 455 456 457
            if (ebml->cluster_start > 0) {
                /* return up until just before a new cluster starts */
                read_space = ebml->cluster_start;
            } else {
458

459 460 461 462
                if (ebml->position == EBML_SLICE_SIZE) {
                    /* The current cluster fills the buffer,
                     * we have no choice but to start flushing it.
                     */
463

464
                    ebml->flush_cluster = true;
465
                }
466

467 468 469 470 471 472 473 474 475
                if (ebml->flush_cluster) {
                    /* return what we have */
                    read_space = ebml->position;
                } else {
                    /* wait until we've read more, so the parser has
                     * time to gather metadata
                     */
                    read_space = 0;
                }
476
            }
477

478
            return read_space;
479
    }
480

481 482
    ICECAST_LOG_ERROR("EBML: Invalid parser read state");
    return 0;
483 484
}

485
/* Return a chunk of the EBML/MKV/WebM stream.
486
 * The header will be buffered until it can be returned as one chunk.
487
 * A cluster element's opening tag will always start a new chunk.
488 489 490
 * 
 * chunk_type will be set to indicate if the chunk is the header,
 * the start of a cluster, or continuing the current cluster.
491
 */
492
static size_t ebml_read(ebml_t *ebml, char *buffer, size_t len, ebml_chunk_type *chunk_type)
493 494
{

495 496
    size_t read_space;
    size_t to_read;
497

498
    *chunk_type = EBML_CHUNK_HEADER;
499

500
    if (len < 1) {
501
        return 0;
502
    }
503

504 505
    switch (ebml->output_state) {
        case EBML_STATE_READING_HEADER:
506

507 508 509 510
            if (ebml->header_size != 0)
            {
                /* Can read a chunk of the header */
                read_space = ebml->header_size - ebml->header_read_position;
511

512 513 514 515 516
                if (read_space >= len) {
                    to_read = len;
                } else {
                    to_read = read_space;
                }
517

518 519
                memcpy(buffer, ebml->header, to_read);
                ebml->header_read_position += to_read;
520

521
                *chunk_type = EBML_CHUNK_HEADER;
522

523 524 525 526 527 528 529
                if (ebml->header_read_position == ebml->header_size) {
                    ebml->output_state = EBML_STATE_READING_CLUSTERS;
                }
            } else {
                /* The header's not ready yet */
                return 0;
            }
530

531
            break;
532

533
        case EBML_STATE_READING_CLUSTERS:
534

535 536
            *chunk_type = EBML_CHUNK_CLUSTER_CONTINUE;
            read_space = ebml->position;
537

538 539
            if (ebml->cluster_start == 0) {
                /* new cluster is starting now */
540

541 542 543 544 545 546 547
                if (ebml->cluster_starts_with_keyframe != EBML_KEYFRAME_DOES_NOT_START_CLUSTER) {
                    /* If we positively identified the first video frame as a non-keyframe,
                     * don't use this cluster as a sync point. Since some files lack
                     * video tracks completely, or we may have failed to probe
                     * the first video frame, it's better to be pass through
                     * ambiguous cases to avoid blocking the stream forever.
                     */
548 549
                    *chunk_type = EBML_CHUNK_CLUSTER_START;
                }
550

551 552 553
                /* mark end of cluster */
                ebml->cluster_start = -1;
            } else if (ebml->cluster_start > 0) {
554 555 556
                /* return up until just before a new cluster starts */
                read_space = ebml->cluster_start;
            }
557

558 559 560
            if (read_space < 1) {
                return 0;
            }
561

562
            if (read_space >= len ) {
563
                to_read = len;
564
            } else {
565
                to_read = read_space;
566
            }
567

568
            memcpy(buffer, ebml->buffer, to_read);
569

570 571 572
            /* Shift unread data down to the start of the buffer */
            memmove(ebml->buffer, ebml->buffer + to_read, ebml->position - to_read);
            ebml->position -= to_read;
573

574 575
            if (ebml->cluster_start > 0) {
                ebml->cluster_start -= to_read;
576
            }
577

578
            break;
579 580 581 582 583 584
    }

    return to_read;

}

585 586 587 588 589
/* Get pointer & length of the buffer able to accept input.
 * 
 * Returns the start of the writable space;
 * Sets bytes to the amount of space available.
 */
590
static unsigned char *ebml_get_write_buffer(ebml_t *ebml, size_t *bytes)
591
{
592 593
    *bytes = EBML_SLICE_SIZE - ebml->input_position;
    return ebml->input_buffer + ebml->input_position;
594 595
}

596 597
/* Process data that has been written to the EBML parser's input buffer.
 */
598
static ssize_t ebml_wrote(ebml_t *ebml, size_t len)
599
{
600
    bool processing = true;
601 602
    size_t cursor = 0;
    size_t to_copy;
Joseph Wallace's avatar
Joseph Wallace committed
603
    unsigned char *end_of_buffer;
604

605 606 607
    ssize_t tag_length;
    ssize_t value_length;
    ssize_t track_number_length;
608 609 610
    uint_least64_t payload_length;
    uint_least64_t data_value;
    uint_least64_t track_number;
611
    unsigned char flags;
612
    ebml_parsing_state copy_state;
613

Joseph Wallace's avatar
Joseph Wallace committed
614 615
    ebml->input_position += len;
    end_of_buffer = ebml->input_buffer + ebml->input_position;
616

Joseph Wallace's avatar
Joseph Wallace committed
617
    while (processing) {
618

Joseph Wallace's avatar
Joseph Wallace committed
619
        switch (ebml->parse_state) {
620

Joseph Wallace's avatar
Joseph Wallace committed
621 622
            case EBML_STATE_PARSING_HEADER:
            case EBML_STATE_PARSING_CLUSTERS:
623

Joseph Wallace's avatar
Joseph Wallace committed
624 625 626 627 628
                if (ebml->parse_state == EBML_STATE_PARSING_HEADER) {
                    copy_state = EBML_STATE_COPYING_TO_HEADER;
                } else {
                    copy_state = EBML_STATE_COPYING_TO_DATA;
                }
629

Joseph Wallace's avatar
Joseph Wallace committed
630 631
                tag_length = ebml_parse_tag(ebml->input_buffer + cursor,
                                            end_of_buffer, &payload_length);
632

633 634 635 636 637 638 639 640
                if (tag_length == 0) {
                    /* Wait for more data */
                    processing = false;
                    break;
                } else if (tag_length < 0) {
                    /* Parse error */
                    return -1;
                }
641

642 643 644 645
                if (payload_length == EBML_UNKNOWN) {
                    /* Parse all children for tags we can't skip */
                    payload_length = 0;
                }
646

647
                    /* Recognize tags of interest */
648 649
                    if (tag_length > UNCOMMON_MAGIC_LEN) {
                        if (!memcmp(ebml->input_buffer + cursor, CLUSTER_MAGIC, UNCOMMON_MAGIC_LEN)) {
650 651 652
                            /* Found a Cluster */
                            ebml->parse_state = EBML_STATE_START_CLUSTER;
                            break;
653
                        } else if (!memcmp(ebml->input_buffer + cursor, SEGMENT_MAGIC, UNCOMMON_MAGIC_LEN)) {
654 655
                            /* Parse all Segment children */
                            payload_length = 0;
656

657
                        } else if (!memcmp(ebml->input_buffer + cursor, TRACKS_MAGIC, UNCOMMON_MAGIC_LEN)) {
658 659
                            /* Parse all Tracks children */
                            payload_length = 0;
660

661
                        }
662

663
                    }
664

665 666
                    if (tag_length > COMMON_MAGIC_LEN) {
                        if (!memcmp(ebml->input_buffer + cursor, SIMPLE_BLOCK_MAGIC, COMMON_MAGIC_LEN)) {
667 668 669 670
                            /* Probe SimpleBlock header for the keyframe status */
                            if (ebml->cluster_starts_with_keyframe == EBML_KEYFRAME_UNKNOWN) {
                                track_number_length = ebml_parse_var_int(ebml->input_buffer + cursor + tag_length,
                                                                  end_of_buffer, &track_number);
671

672 673
                                if (track_number_length == 0) {
                                    /* Wait for more data */
674
                                    processing = false;
675 676 677 678
                                } else if (track_number_length < 0) {
                                    return -1;
                                } else if (track_number == ebml->keyframe_track_number) {
                                    /* this block belongs to the video track */
679

680 681 682
                                    /* skip the 16-bit timecode for now, read the flags byte */
                                    if (cursor + tag_length + track_number_length + 2 >= ebml->input_position) {
                                        /* Wait for more data */
683
                                        processing = false;
684 685
                                    } else {
                                        flags = ebml->input_buffer[cursor + tag_length + track_number_length + 2];
686

687 688 689 690 691 692 693 694 695
                                        if (flags & 0x80) {
                                            /* "keyframe" flag is set */
                                            ebml->cluster_starts_with_keyframe = EBML_KEYFRAME_STARTS_CLUSTER;
                                            /* ICECAST_LOG_DEBUG("Found keyframe in track %hhu", track_number); */
                                        } else {
                                            ebml->cluster_starts_with_keyframe = EBML_KEYFRAME_DOES_NOT_START_CLUSTER;
                                            /* ICECAST_LOG_DEBUG("Found non-keyframe in track %hhu", track_number); */
                                        }
                                    }
696

697
                                }
698

699
                            }
700

701
                        } else if (!memcmp(ebml->input_buffer + cursor, TRACK_ENTRY_MAGIC, COMMON_MAGIC_LEN)) {
702 703 704
                            /* Parse all TrackEntry children; reset the state */
                            payload_length = 0;
                            ebml->parsing_track_number = EBML_UNKNOWN;
705
                            ebml->parsing_track_is_video = false;
706

707
                        } else if (!memcmp(ebml->input_buffer + cursor, TRACK_NUMBER_MAGIC, COMMON_MAGIC_LEN)) {
708 709 710
                            /* Probe TrackNumber for value */
                            value_length = ebml_parse_sized_int(ebml->input_buffer + cursor + tag_length,
                                                                end_of_buffer, payload_length, 0, &data_value);
711

712 713
                            if (value_length == 0) {
                                /* Wait for more data */
714
                                processing = false;
715 716 717 718 719 720
                            } else if (value_length < 0) {
                                return -1;
                            } else {
                                ebml->parsing_track_number = data_value;
                                ebml_check_track(ebml);
                            }
721

722
                        } else if (!memcmp(ebml->input_buffer + cursor, TRACK_TYPE_MAGIC, COMMON_MAGIC_LEN)) {
723 724 725
                            /* Probe TrackType for a video flag */
                            value_length = ebml_parse_sized_int(ebml->input_buffer + cursor + tag_length,
                                                                end_of_buffer, payload_length, 0, &data_value);
726

727 728
                            if (value_length == 0) {
                                /* Wait for more data */
729
                                processing = false;
730 731 732 733 734
                            } else if (value_length < 0) {
                                return -1;
                            } else {
                                if (data_value & 0x01) {
                                    /* This is a video track (0x01 flag = video) */
735
                                    ebml->parsing_track_is_video = true;
736 737 738
                                    ebml_check_track(ebml);
                                }
                            }
739

740 741
                        }
                    }
742

743
                    if (processing) {
744
                        /* Moving to next element, copy current to buffer */
Joseph Wallace's avatar
Joseph Wallace committed
745 746 747 748 749
                        ebml->copy_len = tag_length + payload_length;
                        ebml->parse_state = copy_state;
                    }

                break;
750

Joseph Wallace's avatar
Joseph Wallace committed
751 752 753 754 755 756 757
            case EBML_STATE_START_CLUSTER:
                /* found a cluster; wait to process it until
                 * any previous cluster tag has been flushed
                 * from the read buffer, so as to not lose the
                 * sync point.
                 */
                if (ebml->cluster_start >= 0) {
758
                    /* Allow the cluster in the read buffer to flush. */
759 760
                    ebml->flush_cluster = true;
                    processing = false;
Joseph Wallace's avatar
Joseph Wallace committed
761
                } else {
762

Joseph Wallace's avatar
Joseph Wallace committed
763 764
                    tag_length = ebml_parse_tag(ebml->input_buffer + cursor,
                                                end_of_buffer, &payload_length);
765

Joseph Wallace's avatar
Joseph Wallace committed
766 767
                    /* The header has been fully read by now, publish its size. */
                    ebml->header_size = ebml->header_position;
768

769
                    /* Mark this potential sync point, prepare probe */
Joseph Wallace's avatar
Joseph Wallace committed
770
                    ebml->cluster_start = ebml->position;
771
                    ebml->cluster_starts_with_keyframe = EBML_KEYFRAME_UNKNOWN;
772

773
                    /* Buffer data to give us time to probe for keyframes, etc. */
774
                    ebml->flush_cluster = false;
775

Joseph Wallace's avatar
Joseph Wallace committed
776 777 778 779 780
                    /* Copy cluster tag to read buffer */
                    ebml->copy_len = tag_length;
                    ebml->parse_state = EBML_STATE_COPYING_TO_DATA;
                }
                break;
781

Joseph Wallace's avatar
Joseph Wallace committed
782 783 784 785 786 787
            case EBML_STATE_COPYING_TO_HEADER:
            case EBML_STATE_COPYING_TO_DATA:
                to_copy = ebml->input_position - cursor;
                if (to_copy > ebml->copy_len) {
                    to_copy = ebml->copy_len;
                }
788

Joseph Wallace's avatar
Joseph Wallace committed
789 790 791 792 793
                if (ebml->parse_state == EBML_STATE_COPYING_TO_HEADER) {
                    if ((ebml->header_position + to_copy) > EBML_HEADER_MAX_SIZE) {
                        ICECAST_LOG_ERROR("EBML Header too large, failing");
                        return -1;
                    }
794

Joseph Wallace's avatar
Joseph Wallace committed
795 796
                    memcpy(ebml->header + ebml->header_position, ebml->input_buffer + cursor, to_copy);
                    ebml->header_position += to_copy;
797

Joseph Wallace's avatar
Joseph Wallace committed
798 799 800 801
                } else if (ebml->parse_state == EBML_STATE_COPYING_TO_DATA) {
                    if ((ebml->position + to_copy) > EBML_SLICE_SIZE) {
                        to_copy = EBML_SLICE_SIZE - ebml->position;
                    }
802

Joseph Wallace's avatar
Joseph Wallace committed
803 804 805
                    memcpy(ebml->buffer + ebml->position, ebml->input_buffer + cursor, to_copy);
                    ebml->position += to_copy;
                }
806

Joseph Wallace's avatar
Joseph Wallace committed
807 808
                cursor += to_copy;
                ebml->copy_len -= to_copy;
809

Joseph Wallace's avatar
Joseph Wallace committed
810 811 812 813 814 815 816 817 818
                if (ebml->copy_len == 0) {
                    /* resume parsing */
                    if (ebml->parse_state == EBML_STATE_COPYING_TO_HEADER) {
                        ebml->parse_state = EBML_STATE_PARSING_HEADER;
                    } else {
                        ebml->parse_state = EBML_STATE_PARSING_CLUSTERS;
                    }
                } else {
                    /* wait for more data */
819
                    processing = false;
Joseph Wallace's avatar
Joseph Wallace committed
820
                }
821

Joseph Wallace's avatar
Joseph Wallace committed
822
                break;
823

Joseph Wallace's avatar
Joseph Wallace committed
824
            default:
825
                processing = false;
826

827
        }
828

829
    }
830

Joseph Wallace's avatar
Joseph Wallace committed
831 832 833
    /* Shift unprocessed data down to the start of the buffer */
    memmove(ebml->input_buffer, ebml->input_buffer + cursor, ebml->input_position - cursor);
    ebml->input_position -= cursor;
834

835
    return len;
836

837
}
838

839 840 841 842 843
static inline void ebml_check_track(ebml_t *ebml)
{
    if (ebml->keyframe_track_number == EBML_UNKNOWN
        && ebml->parsing_track_is_video
        && ebml->parsing_track_number != EBML_UNKNOWN) {
844

845 846 847 848 849
        ebml->keyframe_track_number = ebml->parsing_track_number;
        ICECAST_LOG_DEBUG("Identified track #%ffu as the video track", ebml->keyframe_track_number);
    }
}

850 851 852 853 854 855 856 857 858 859 860 861
/* Try to parse an EBML tag at the given location, returning the
 * length of the tag & the length of the associated payload.
 * 
 * Returns the length of the tag on success, and writes the payload
 * size to *payload_length.
 * 
 * Return 0 if it would be necessary to read past the
 * given end-of-buffer address to read a complete tag.
 * 
 * Returns -1 if the tag is corrupt.
 */

862
static ssize_t ebml_parse_tag(unsigned char *buffer,
863 864
                              unsigned char *buffer_end,
                              uint_least64_t *payload_length)
865
{
866 867
    ssize_t type_length;
    ssize_t size_length;
868
    uint_least64_t value;
869

870
    *payload_length = 0;
871

872 873
    /* read past the type tag */
    type_length = ebml_parse_var_int(buffer, buffer_end, &value);
874

875 876 877
    if (type_length <= 0) {
        return type_length;
    }
878

879 880
    /* read the length tag */
    size_length = ebml_parse_var_int(buffer + type_length, buffer_end, payload_length);
881

882 883 884
    if (size_length <= 0) {
        return size_length;
    }
885

886 887 888 889 890 891 892 893 894
    return type_length + size_length;
}

/* Try to parse an EBML variable-length integer.
 * Returns 0 if there's not enough space to read the number;
 * Returns -1 if the number is malformed.
 * Else, returns the length of the number in bytes and writes the
 * value to *out_value.
 */
895 896
static ssize_t ebml_parse_var_int(unsigned char *buffer,
                                 unsigned char *buffer_end,
897
                                 uint_least64_t *out_value)
898
{
899 900
    ssize_t size = 1;
    ssize_t i;
901
    unsigned char mask = 0x80;
902 903
    uint_least64_t value;
    uint_least64_t unknown_marker;
904

905 906 907
    if (buffer >= buffer_end) {
        return 0;
    }
908

909 910
    /* find the length marker bit in the first byte */
    value = buffer[0];
911

912 913 914 915 916 917 918 919 920
    while (mask) {
        if (value & mask) {
            value = value & ~mask;
            unknown_marker = mask - 1;
            break;
        }
        size++;
        mask = mask >> 1;
    }
921

922 923 924 925 926
    /* catch malformed number (no prefix) */
    if (mask == 0) {
        ICECAST_LOG_DEBUG("Corrupt var-int");
        return -1;
    }
927

928 929 930 931
    /* catch number bigger than parsing buffer */
    if (buffer + size - 1 >= buffer_end) {
        return 0;
    }
932

933 934 935 936 937
    /* read remaining bytes of (big-endian) number */
    for (i = 1; i < size; i++) {
        value = (value << 8) + buffer[i];
        unknown_marker = (unknown_marker << 8) + 0xFF;
    }
938

939
    /* catch special "unknown" length */
940

941 942 943 944 945 946 947 948 949
    if (value == unknown_marker) {
        *out_value = EBML_UNKNOWN;
    } else {
        *out_value = value;
    }

/*
    ICECAST_LOG_DEBUG("Varint: value %lli, unknown %llu, mask %hhu, size %i", value, unknown_marker, mask, size);
*/
950

951 952
    return size;
}
953

954
/* Parse a big-endian int that may be from 1-8 bytes long.
955 956 957 958
 * Returns 0 if there's not enough space to read the number;
 * Returns -1 if the number is mis-sized.
 * Else, returns the length of the number in bytes and writes the
 * value to *out_value.
959 960
 * If is_signed is true, then the int is assumed to be two's complement
 * signed, negative values will be correctly promoted, and the returned
961
 * unsigned number can be safely cast to a signed number on systems using
962
 * two's complement arithmatic.
963
 */
964
static ssize_t ebml_parse_sized_int(unsigned char       *buffer,
965 966
                                    unsigned char       *buffer_end,
                                    size_t              len,
967
                                    bool                 is_signed,
968
                                    uint_least64_t  *out_value)
969
{
970
    uint_least64_t value;
971
    size_t i;
972

973 974 975 976
    if (len < 1 || len > 8) {
        ICECAST_LOG_DEBUG("Sized int of %i bytes", len);
        return -1;
    }
977

978 979 980
    if (buffer + len >= buffer_end) {
        return 0;
    }
981

982 983 984 985 986
    if (is_signed && ((signed char) buffer[0]) < 0) {
        value = -1;
    } else {
        value = 0;
    }
987

988 989 990
    for (i = 0; i < len; i++) {
        value = (value << 8) + ((unsigned char) buffer[i]);
    }
991

992
    *out_value = value;
993

994 995
    return len;
}