format_ebml.c 32 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 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
 *
 */

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

#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"

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

/* 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.
 */
50 51
#define EBML_SLICE_SIZE 4096

52 53 54
/* A value that no EBML var-int is allowed to take. */
#define EBML_UNKNOWN ((unsigned long long) -1)

55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
/* 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"

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

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

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

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

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

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

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

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

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

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

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

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

128
typedef struct ebml_st {
129

130
    ebml_read_mode output_state;
Joseph Wallace's avatar
Joseph Wallace committed
131 132
    ebml_parsing_state parse_state;
    unsigned long long copy_len;
133

134
    ssize_t cluster_start;
135
    ebml_keyframe_status cluster_starts_with_keyframe;
136
    int flush_cluster;
137

138
    size_t position;
139
    unsigned char *buffer;
140

141
    size_t input_position;
142
    unsigned char *input_buffer;
143

144 145 146
    size_t header_size;
    size_t header_position;
    size_t header_read_position;
147
    unsigned char *header;
148

149 150 151
    unsigned long long keyframe_track_number;
    unsigned long long parsing_track_number;
    int parsing_track_is_video;
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
} ebml_t;

typedef struct ebml_source_state_st {

    ebml_t *ebml;
    refbuf_t *header;
    int file_headers_written;

} ebml_source_state_t;

typedef struct ebml_client_data_st {

    refbuf_t *header;
    size_t header_pos;

} ebml_client_data_t;
168

169 170 171 172 173 174
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);
175 176 177

static ebml_t *ebml_create();
static void ebml_destroy(ebml_t *ebml);
178 179 180 181 182
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,
183
                              unsigned char      *buffer_end,
184 185 186 187 188 189 190 191 192
                              unsigned long long *payload_length);
static ssize_t ebml_parse_var_int(unsigned char      *buffer,
                                  unsigned char      *buffer_end,
                                  unsigned long long *out_value);
static ssize_t ebml_parse_sized_int(unsigned char      *buffer,
                                    unsigned char      *buffer_end,
                                    size_t             len,
                                    int                is_signed,
                                    unsigned long long *out_value);
193
static inline void ebml_check_track(ebml_t *ebml);
194

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

    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;

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

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

    ebml_source_state->ebml = ebml_create();
216

217 218 219
    return 0;
}

220
static void ebml_free_plugin(format_plugin_t *plugin)
221 222 223 224
{

    ebml_source_state_t *ebml_source_state = plugin->_state;

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

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

    ebml_client_data_t *ebml_client_data = client->format_data;
238
    size_t len = EBML_SLICE_SIZE;
239 240
    int ret;

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

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

    return ret;

}

258 259
/* Initial write-to-client function.
 */
260 261 262 263 264 265 266 267 268 269 270
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
    {
271 272
        /* Now that the header's sent, short-circuit to the generic
         * write-refbufs function. */
273 274 275 276 277 278
        client->write_to_client = format_generic_write_to_client;
        return client->write_to_client(client);
    }

}

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

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

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

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

308
/*            ICECAST_LOG_DEBUG("EBML: generated refbuf, size %i : %hhi %hhi %hhi",
309
 *                            read_bytes, refbuf->data[0], refbuf->data[1], refbuf->data[2]);
310
 */
311

312
            if (chunk_type == EBML_CHUNK_CLUSTER_START)
313 314
            {
                refbuf->sync_point = 1;
315
/*                ICECAST_LOG_DEBUG("EBML: ^ was sync point"); */
316 317 318
            }
            return refbuf;

319
        } else if(read_bytes == 0) {
320
            /* Feed more bytes into the parser */
321 322 323
            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) {
324 325 326
                ebml_wrote (ebml_source_state->ebml, 0);
                return NULL;
            }
327 328 329
            format->read_bytes += read_bytes;
            ret = ebml_wrote (ebml_source_state->ebml, read_bytes);
            if (ret != read_bytes) {
330
                ICECAST_LOG_ERROR("Problem processing stream");
331 332 333
                source->running = 0;
                return NULL;
            }
334 335 336 337
        } else {
            ICECAST_LOG_ERROR("Problem processing stream");
            source->running = 0;
            return NULL;
338 339 340 341
        }
    }
}

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

349 350
    if (!ebml_source_state->header)
        return -1;
351

352 353 354
    ebml_client_data = calloc(1, sizeof(ebml_client_data_t));
    if (!ebml_client_data)
        return -1;
355

356 357 358 359 360
    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;
361 362 363 364 365 366 367 368 369 370 371 372 373 374
}

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)
{
375
    ICECAST_LOG_WARN("Write to dump file failed, disabling");
376 377 378 379 380 381 382 383 384 385 386 387
    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;

    if (ebml_source_state->file_headers_written == 0)
    {
        if (fwrite (ebml_source_state->header->data, 1,
388
                    ebml_source_state->header->len,
389 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 416 417 418
                    source->dumpfile) != ebml_source_state->header->len)
            ebml_write_buf_to_file_fail(source);
        else
            ebml_source_state->file_headers_written = 1;
    }

    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));

419 420
    ebml->output_state = EBML_STATE_READING_HEADER;

421
    ebml->header = calloc(1, EBML_HEADER_MAX_SIZE);
Joseph Wallace's avatar
Joseph Wallace committed
422
    ebml->buffer = calloc(1, EBML_SLICE_SIZE);
423 424
    ebml->input_buffer = calloc(1, EBML_SLICE_SIZE);

425
    ebml->cluster_start = -1;
426

427 428 429
    ebml->keyframe_track_number = EBML_UNKNOWN;
    ebml->parsing_track_number = EBML_UNKNOWN;
    ebml->parsing_track_is_video = 0;
430 431 432 433 434

    return ebml;

}

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

441
    size_t read_space;
442

443 444
    switch (ebml->output_state) {
        case EBML_STATE_READING_HEADER:
445

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

455
        case EBML_STATE_READING_CLUSTERS:
456

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

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

467 468
                    ebml->flush_cluster = 1;
                }
469

470 471 472 473 474 475 476 477 478
                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;
                }
479
            }
480

481
            return read_space;
482
    }
483

484 485
    ICECAST_LOG_ERROR("EBML: Invalid parser read state");
    return 0;
486 487
}

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

498 499
    size_t read_space;
    size_t to_read;
500

501
    *chunk_type = EBML_CHUNK_HEADER;
502

503
    if (len < 1) {
504
        return 0;
505
    }
506

507 508
    switch (ebml->output_state) {
        case EBML_STATE_READING_HEADER:
509

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

515 516 517 518 519
                if (read_space >= len) {
                    to_read = len;
                } else {
                    to_read = read_space;
                }
520

521 522
                memcpy(buffer, ebml->header, to_read);
                ebml->header_read_position += to_read;
523

524
                *chunk_type = EBML_CHUNK_HEADER;
525

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

534
            break;
535

536
        case EBML_STATE_READING_CLUSTERS:
537

538 539
            *chunk_type = EBML_CHUNK_CLUSTER_CONTINUE;
            read_space = ebml->position;
540

541 542
            if (ebml->cluster_start == 0) {
                /* new cluster is starting now */
543

544 545 546 547 548 549 550
                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.
                     */
551 552
                    *chunk_type = EBML_CHUNK_CLUSTER_START;
                }
553

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

561 562 563
            if (read_space < 1) {
                return 0;
            }
564

565
            if (read_space >= len ) {
566
                to_read = len;
567
            } else {
568
                to_read = read_space;
569
            }
570

571
            memcpy(buffer, ebml->buffer, to_read);
572

573 574 575
            /* 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;
576

577 578
            if (ebml->cluster_start > 0) {
                ebml->cluster_start -= to_read;
579
            }
580

581
            break;
582 583 584 585 586 587
    }

    return to_read;

}

588 589 590 591 592
/* 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.
 */
593
static unsigned char *ebml_get_write_buffer(ebml_t *ebml, size_t *bytes)
594
{
595 596
    *bytes = EBML_SLICE_SIZE - ebml->input_position;
    return ebml->input_buffer + ebml->input_position;
597 598
}

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

608 609 610
    ssize_t tag_length;
    ssize_t value_length;
    ssize_t track_number_length;
Joseph Wallace's avatar
Joseph Wallace committed
611
    unsigned long long payload_length;
612
    unsigned long long data_value;
613 614
    unsigned long long track_number;
    unsigned char flags;
615
    ebml_parsing_state copy_state;
616

Joseph Wallace's avatar
Joseph Wallace committed
617 618
    ebml->input_position += len;
    end_of_buffer = ebml->input_buffer + ebml->input_position;
619

Joseph Wallace's avatar
Joseph Wallace committed
620
    while (processing) {
621

Joseph Wallace's avatar
Joseph Wallace committed
622
        /*ICECAST_LOG_DEBUG("Parse State: %i", ebml->parse_state);*/
623

Joseph Wallace's avatar
Joseph Wallace committed
624
        switch (ebml->parse_state) {
625

Joseph Wallace's avatar
Joseph Wallace committed
626 627
            case EBML_STATE_PARSING_HEADER:
            case EBML_STATE_PARSING_CLUSTERS:
628

Joseph Wallace's avatar
Joseph Wallace committed
629 630 631 632 633
                if (ebml->parse_state == EBML_STATE_PARSING_HEADER) {
                    copy_state = EBML_STATE_COPYING_TO_HEADER;
                } else {
                    copy_state = EBML_STATE_COPYING_TO_DATA;
                }
634

Joseph Wallace's avatar
Joseph Wallace committed
635 636
                tag_length = ebml_parse_tag(ebml->input_buffer + cursor,
                                            end_of_buffer, &payload_length);
637

Joseph Wallace's avatar
Joseph Wallace committed
638
                if (tag_length > 0) {
639

Joseph Wallace's avatar
Joseph Wallace committed
640 641 642 643
                    if (payload_length == EBML_UNKNOWN) {
                        /* Parse all children for tags we can't skip */
                        payload_length = 0;
                    }
644

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

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

659
                        }
660

661
                    }
662

663 664
                    if (tag_length > COMMON_MAGIC_LEN) {
                        if (!memcmp(ebml->input_buffer + cursor, SIMPLE_BLOCK_MAGIC, COMMON_MAGIC_LEN)) {
665 666 667 668
                            /* 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);
669

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

678 679 680 681 682 683
                                    /* 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 */
                                        processing = 0;
                                    } else {
                                        flags = ebml->input_buffer[cursor + tag_length + track_number_length + 2];
684

685 686 687 688 689 690 691 692 693
                                        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); */
                                        }
                                    }
694

695
                                }
696

697
                            }
698

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

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

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

720
                        } else if (!memcmp(ebml->input_buffer + cursor, TRACK_TYPE_MAGIC, COMMON_MAGIC_LEN)) {
721 722 723
                            /* 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);
724

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

738 739
                        }
                    }
740

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

                } else if (tag_length == 0) {
                    /* Wait for more data */
                    /* ICECAST_LOG_DEBUG("Wait"); */
                    processing = 0;
                } else if (tag_length < 0) {
                    /* Parse error */
                    /* ICECAST_LOG_DEBUG("Stop"); */
                    return -1;
                }
                break;
757

Joseph Wallace's avatar
Joseph Wallace committed
758 759 760 761 762 763 764
            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) {
765 766
                    /* Allow the cluster in the read buffer to flush. */
                    ebml->flush_cluster = 1;
Joseph Wallace's avatar
Joseph Wallace committed
767 768
                    processing = 0;
                } else {
769

Joseph Wallace's avatar
Joseph Wallace committed
770 771
                    tag_length = ebml_parse_tag(ebml->input_buffer + cursor,
                                                end_of_buffer, &payload_length);
772

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

776
                    /* Mark this potential sync point, prepare probe */
Joseph Wallace's avatar
Joseph Wallace committed
777
                    ebml->cluster_start = ebml->position;
778
                    ebml->cluster_starts_with_keyframe = EBML_KEYFRAME_UNKNOWN;
779

780 781
                    /* Buffer data to give us time to probe for keyframes, etc. */
                    ebml->flush_cluster = 0;
782

Joseph Wallace's avatar
Joseph Wallace committed
783 784 785 786 787
                    /* Copy cluster tag to read buffer */
                    ebml->copy_len = tag_length;
                    ebml->parse_state = EBML_STATE_COPYING_TO_DATA;
                }
                break;
788

Joseph Wallace's avatar
Joseph Wallace committed
789 790 791 792 793 794
            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;
                }
795

Joseph Wallace's avatar
Joseph Wallace committed
796 797 798 799 800
                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;
                    }
801

Joseph Wallace's avatar
Joseph Wallace committed
802 803
                    memcpy(ebml->header + ebml->header_position, ebml->input_buffer + cursor, to_copy);
                    ebml->header_position += to_copy;
804

Joseph Wallace's avatar
Joseph Wallace committed
805 806 807 808
                } 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;
                    }
809

Joseph Wallace's avatar
Joseph Wallace committed
810 811 812 813
                    memcpy(ebml->buffer + ebml->position, ebml->input_buffer + cursor, to_copy);
                    ebml->position += to_copy;
                }
                /* ICECAST_LOG_DEBUG("Copied %i of %hhu", to_copy, ebml->copy_len); */
814

Joseph Wallace's avatar
Joseph Wallace committed
815 816
                cursor += to_copy;
                ebml->copy_len -= to_copy;
817

Joseph Wallace's avatar
Joseph Wallace committed
818 819 820 821 822 823 824 825 826 827 828
                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 */
                    processing = 0;
                }
829

Joseph Wallace's avatar
Joseph Wallace committed
830
                break;
831

Joseph Wallace's avatar
Joseph Wallace committed
832 833
            default:
                processing = 0;
834

835
        }
836

837
    }
838

Joseph Wallace's avatar
Joseph Wallace committed
839 840 841
    /* 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;
842

843
    return len;
844

845
}
846

847 848 849 850 851
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) {
852

853 854 855 856 857
        ebml->keyframe_track_number = ebml->parsing_track_number;
        ICECAST_LOG_DEBUG("Identified track #%ffu as the video track", ebml->keyframe_track_number);
    }
}

858 859 860 861 862 863 864 865 866 867 868 869
/* 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.
 */

870 871 872
static ssize_t ebml_parse_tag(unsigned char *buffer,
                             unsigned char *buffer_end,
                             unsigned long long *payload_length)
873
{
874 875
    size_t type_length;
    size_t size_length;
876
    unsigned long long value;
877

878
    *payload_length = 0;
879

880 881
    /* read past the type tag */
    type_length = ebml_parse_var_int(buffer, buffer_end, &value);
882

883 884 885
    if (type_length <= 0) {
        return type_length;
    }
886

887 888
    /* read the length tag */
    size_length = ebml_parse_var_int(buffer + type_length, buffer_end, payload_length);
889

890 891 892
    if (size_length <= 0) {
        return size_length;
    }
893

894 895 896 897 898 899 900 901 902
    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.
 */
903 904 905
static ssize_t ebml_parse_var_int(unsigned char *buffer,
                                 unsigned char *buffer_end,
                                 unsigned long long *out_value)
906
{
907 908
    size_t size = 1;
    size_t i;
909 910 911
    unsigned char mask = 0x80;
    unsigned long long value;
    unsigned long long unknown_marker;
912

913 914 915
    if (buffer >= buffer_end) {
        return 0;
    }
916

917 918
    /* find the length marker bit in the first byte */
    value = buffer[0];
919

920 921 922 923 924 925 926 927 928
    while (mask) {
        if (value & mask) {
            value = value & ~mask;
            unknown_marker = mask - 1;
            break;
        }
        size++;
        mask = mask >> 1;
    }
929

930 931 932 933 934
    /* catch malformed number (no prefix) */
    if (mask == 0) {
        ICECAST_LOG_DEBUG("Corrupt var-int");
        return -1;
    }
935

936 937 938 939
    /* catch number bigger than parsing buffer */
    if (buffer + size - 1 >= buffer_end) {
        return 0;
    }
940

941 942 943 944 945
    /* read remaining bytes of (big-endian) number */
    for (i = 1; i < size; i++) {
        value = (value << 8) + buffer[i];
        unknown_marker = (unknown_marker << 8) + 0xFF;
    }
946

947
    /* catch special "unknown" length */
948

949 950 951 952 953 954 955 956 957
    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);
*/
958

959 960
    return size;
}
961 962 963 964 965 966 967

/* Parse a normal int that may be from 1-8 bytes long.
 * 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.
 */
968 969 970 971 972
static ssize_t ebml_parse_sized_int(unsigned char       *buffer,
                                   unsigned char       *buffer_end,
                                   size_t              len,
                                   int                 is_signed,
                                   unsigned long long  *out_value)
973 974
{
    long long value;
975
    size_t i;
976

977 978 979 980
    if (len < 1 || len > 8) {
        ICECAST_LOG_DEBUG("Sized int of %i bytes", len);
        return -1;
    }
981

982 983 984
    if (buffer + len >= buffer_end) {
        return 0;
    }
985

986 987 988 989 990
    if (is_signed && ((signed char) buffer[0]) < 0) {
        value = -1;
    } else {
        value = 0;
    }
991

992 993 994
    for (i = 0; i < len; i++) {
        value = (value << 8) + ((unsigned char) buffer[i]);
    }
995

996
    *out_value = value;
997

998 999
    return len;
}