format_ebml.c 31.9 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 129 130 131 132
typedef struct ebml_client_data_st ebml_client_data_t;

struct ebml_client_data_st {

    refbuf_t *header;
133
    size_t header_pos;
134 135 136 137 138

};

struct ebml_st {

139
    ebml_read_mode output_state;
Joseph Wallace's avatar
Joseph Wallace committed
140 141
    ebml_parsing_state parse_state;
    unsigned long long copy_len;
142

143
    ssize_t cluster_start;
144
    ebml_keyframe_status cluster_starts_with_keyframe;
145
    int flush_cluster;
146

147
    size_t position;
148
    unsigned char *buffer;
149

150
    size_t input_position;
151
    unsigned char *input_buffer;
152

153 154 155
    size_t header_size;
    size_t header_position;
    size_t header_read_position;
156
    unsigned char *header;
157

158 159 160
    unsigned long long keyframe_track_number;
    unsigned long long parsing_track_number;
    int parsing_track_is_video;
161 162
};

163 164 165 166 167 168
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);
169 170 171

static ebml_t *ebml_create();
static void ebml_destroy(ebml_t *ebml);
172 173 174 175 176
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,
177
                              unsigned char      *buffer_end,
178 179 180 181 182 183 184 185 186
                              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);
187
static inline void ebml_check_track(ebml_t *ebml);
188

189
int format_ebml_get_plugin(source_t *source)
190 191 192 193 194 195 196 197 198 199 200 201 202
{

    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;

203
    plugin->contenttype = httpp_getvar(source->parser, "content-type");
204 205

    plugin->_state = ebml_source_state;
206
    vorbis_comment_init(&plugin->vc);
207 208 209
    source->format = plugin;

    ebml_source_state->ebml = ebml_create();
210

211 212 213
    return 0;
}

214
static void ebml_free_plugin(format_plugin_t *plugin)
215 216 217 218
{

    ebml_source_state_t *ebml_source_state = plugin->_state;

219
    refbuf_release(ebml_source_state->header);
220
    ebml_destroy(ebml_source_state->ebml);
221
    free(ebml_source_state);
222
    vorbis_comment_clear(&plugin->vc);
223
    free(plugin);
224 225
}

226 227
/* Write to a client from the header buffer.
 */
228
static int send_ebml_header(client_t *client)
229 230 231
{

    ebml_client_data_t *ebml_client_data = client->format_data;
232
    size_t len = EBML_SLICE_SIZE;
233 234
    int ret;

235
    if (ebml_client_data->header->len - ebml_client_data->header_pos < len)
236 237 238
    {
        len = ebml_client_data->header->len - ebml_client_data->header_pos;
    }
239
    ret = client_send_bytes (client,
240 241 242 243 244 245 246 247 248 249 250 251
                             ebml_client_data->header->data + ebml_client_data->header_pos,
                             len);

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

    return ret;

}

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

}

273 274
/* Return a refbuf to add to the queue.
 */
275
static refbuf_t *ebml_get_buffer(source_t *source)
276 277 278 279
{

    ebml_source_state_t *ebml_source_state = source->format->_state;
    format_plugin_t *format = source->format;
280
    unsigned char *write_buffer = NULL;
281 282
    size_t read_bytes = 0;
    size_t write_bytes = 0;
283
    ebml_chunk_type chunk_type;
284
    refbuf_t *refbuf;
285
    size_t ret;
286 287 288

    while (1)
    {
289 290
        read_bytes = ebml_read_space(ebml_source_state->ebml);
        if (read_bytes > 0) {
291
            /* A chunk is available for reading */
292 293
            refbuf = refbuf_new(read_bytes);
            ebml_read(ebml_source_state->ebml, refbuf->data, read_bytes, &chunk_type);
294 295 296

            if (ebml_source_state->header == NULL)
            {
297
                /* Capture header before adding clusters to the queue */
298 299 300 301
                ebml_source_state->header = refbuf;
                continue;
            }

302
/*            ICECAST_LOG_DEBUG("EBML: generated refbuf, size %i : %hhi %hhi %hhi",
303
 *                            read_bytes, refbuf->data[0], refbuf->data[1], refbuf->data[2]);
304
 */
305

306
            if (chunk_type == EBML_CHUNK_CLUSTER_START)
307 308
            {
                refbuf->sync_point = 1;
309
/*                ICECAST_LOG_DEBUG("EBML: ^ was sync point"); */
310 311 312
            }
            return refbuf;

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

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

343 344
    if (!ebml_source_state->header)
        return -1;
345

346 347 348
    ebml_client_data = calloc(1, sizeof(ebml_client_data_t));
    if (!ebml_client_data)
        return -1;
349

350 351 352 353 354
    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;
355 356 357 358 359 360 361 362 363 364 365 366 367 368
}

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)
{
369
    ICECAST_LOG_WARN("Write to dump file failed, disabling");
370 371 372 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;

    if (ebml_source_state->file_headers_written == 0)
    {
        if (fwrite (ebml_source_state->header->data, 1,
382
                    ebml_source_state->header->len,
383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412
                    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));

413 414
    ebml->output_state = EBML_STATE_READING_HEADER;

415
    ebml->header = calloc(1, EBML_HEADER_MAX_SIZE);
Joseph Wallace's avatar
Joseph Wallace committed
416
    ebml->buffer = calloc(1, EBML_SLICE_SIZE);
417 418
    ebml->input_buffer = calloc(1, EBML_SLICE_SIZE);

419
    ebml->cluster_start = -1;
420

421 422 423
    ebml->keyframe_track_number = EBML_UNKNOWN;
    ebml->parsing_track_number = EBML_UNKNOWN;
    ebml->parsing_track_is_video = 0;
424 425 426 427 428

    return ebml;

}

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

435
    size_t read_space;
436

437 438
    switch (ebml->output_state) {
        case EBML_STATE_READING_HEADER:
439

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

449
        case EBML_STATE_READING_CLUSTERS:
450

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

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

461 462
                    ebml->flush_cluster = 1;
                }
463

464 465 466 467 468 469 470 471 472
                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;
                }
473
            }
474

475
            return read_space;
476
    }
477

478 479
    ICECAST_LOG_ERROR("EBML: Invalid parser read state");
    return 0;
480 481
}

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

492 493
    size_t read_space;
    size_t to_read;
494

495
    *chunk_type = EBML_CHUNK_HEADER;
496

497
    if (len < 1) {
498
        return 0;
499
    }
500

501 502
    switch (ebml->output_state) {
        case EBML_STATE_READING_HEADER:
503

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

509 510 511 512 513
                if (read_space >= len) {
                    to_read = len;
                } else {
                    to_read = read_space;
                }
514

515 516
                memcpy(buffer, ebml->header, to_read);
                ebml->header_read_position += to_read;
517

518
                *chunk_type = EBML_CHUNK_HEADER;
519

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

528
            break;
529

530
        case EBML_STATE_READING_CLUSTERS:
531

532 533
            *chunk_type = EBML_CHUNK_CLUSTER_CONTINUE;
            read_space = ebml->position;
534

535 536
            if (ebml->cluster_start == 0) {
                /* new cluster is starting now */
537

538 539 540 541 542 543 544
                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.
                     */
545 546
                    *chunk_type = EBML_CHUNK_CLUSTER_START;
                }
547

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

555 556 557
            if (read_space < 1) {
                return 0;
            }
558

559
            if (read_space >= len ) {
560
                to_read = len;
561
            } else {
562
                to_read = read_space;
563
            }
564

565
            memcpy(buffer, ebml->buffer, to_read);
566

567 568 569
            /* 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;
570

571 572
            if (ebml->cluster_start > 0) {
                ebml->cluster_start -= to_read;
573
            }
574

575
            break;
576 577 578 579 580 581
    }

    return to_read;

}

582 583 584 585 586
/* 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.
 */
587
static unsigned char *ebml_get_write_buffer(ebml_t *ebml, size_t *bytes)
588
{
589 590
    *bytes = EBML_SLICE_SIZE - ebml->input_position;
    return ebml->input_buffer + ebml->input_position;
591 592
}

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

602 603 604
    ssize_t tag_length;
    ssize_t value_length;
    ssize_t track_number_length;
Joseph Wallace's avatar
Joseph Wallace committed
605
    unsigned long long payload_length;
606
    unsigned long long data_value;
607 608
    unsigned long long track_number;
    unsigned char flags;
609
    ebml_parsing_state copy_state;
610

Joseph Wallace's avatar
Joseph Wallace committed
611 612
    ebml->input_position += len;
    end_of_buffer = ebml->input_buffer + ebml->input_position;
613

Joseph Wallace's avatar
Joseph Wallace committed
614
    while (processing) {
615

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

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

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

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

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

Joseph Wallace's avatar
Joseph Wallace committed
632
                if (tag_length > 0) {
633

Joseph Wallace's avatar
Joseph Wallace committed
634 635 636 637
                    if (payload_length == EBML_UNKNOWN) {
                        /* Parse all children for tags we can't skip */
                        payload_length = 0;
                    }
638

639
                    /* Recognize tags of interest */
640 641
                    if (tag_length > UNCOMMON_MAGIC_LEN) {
                        if (!memcmp(ebml->input_buffer + cursor, CLUSTER_MAGIC, UNCOMMON_MAGIC_LEN)) {
642 643 644
                            /* Found a Cluster */
                            ebml->parse_state = EBML_STATE_START_CLUSTER;
                            break;
645
                        } else if (!memcmp(ebml->input_buffer + cursor, SEGMENT_MAGIC, UNCOMMON_MAGIC_LEN)) {
646 647
                            /* Parse all Segment children */
                            payload_length = 0;
648

649
                        } else if (!memcmp(ebml->input_buffer + cursor, TRACKS_MAGIC, UNCOMMON_MAGIC_LEN)) {
650 651
                            /* Parse all Tracks children */
                            payload_length = 0;
652

653
                        }
654

655
                    }
656

657 658
                    if (tag_length > COMMON_MAGIC_LEN) {
                        if (!memcmp(ebml->input_buffer + cursor, SIMPLE_BLOCK_MAGIC, COMMON_MAGIC_LEN)) {
659 660 661 662
                            /* 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);
663

664 665 666 667 668 669 670
                                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 */
671

672 673 674 675 676 677
                                    /* 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];
678

679 680 681 682 683 684 685 686 687
                                        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); */
                                        }
                                    }
688

689
                                }
690

691
                            }
692

693
                        } else if (!memcmp(ebml->input_buffer + cursor, TRACK_ENTRY_MAGIC, COMMON_MAGIC_LEN)) {
694 695 696 697
                            /* Parse all TrackEntry children; reset the state */
                            payload_length = 0;
                            ebml->parsing_track_number = EBML_UNKNOWN;
                            ebml->parsing_track_is_video = 0;
698

699
                        } else if (!memcmp(ebml->input_buffer + cursor, TRACK_NUMBER_MAGIC, COMMON_MAGIC_LEN)) {
700 701 702
                            /* Probe TrackNumber for value */
                            value_length = ebml_parse_sized_int(ebml->input_buffer + cursor + tag_length,
                                                                end_of_buffer, payload_length, 0, &data_value);
703

704 705 706 707 708 709 710 711 712
                            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);
                            }
713

714
                        } else if (!memcmp(ebml->input_buffer + cursor, TRACK_TYPE_MAGIC, COMMON_MAGIC_LEN)) {
715 716 717
                            /* 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);
718

719 720 721 722 723 724 725 726 727 728 729 730
                            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);
                                }
                            }
731

732 733
                        }
                    }
734

735
                    if (processing) {
736
                        /* Moving to next element, copy current to buffer */
Joseph Wallace's avatar
Joseph Wallace committed
737 738 739 740 741 742 743 744 745 746 747 748 749 750
                        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;
751

Joseph Wallace's avatar
Joseph Wallace committed
752 753 754 755 756 757 758
            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) {
759 760
                    /* Allow the cluster in the read buffer to flush. */
                    ebml->flush_cluster = 1;
Joseph Wallace's avatar
Joseph Wallace committed
761 762
                    processing = 0;
                } else {
763

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

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

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

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

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

Joseph Wallace's avatar
Joseph Wallace committed
783 784 785 786 787 788
            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;
                }
789

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

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

Joseph Wallace's avatar
Joseph Wallace committed
799 800 801 802
                } 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;
                    }
803

Joseph Wallace's avatar
Joseph Wallace committed
804 805 806 807
                    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); */
808

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

Joseph Wallace's avatar
Joseph Wallace committed
812 813 814 815 816 817 818 819 820 821 822
                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;
                }
823

Joseph Wallace's avatar
Joseph Wallace committed
824
                break;
825

Joseph Wallace's avatar
Joseph Wallace committed
826 827
            default:
                processing = 0;
828

829
        }
830

831
    }
832

Joseph Wallace's avatar
Joseph Wallace committed
833 834 835
    /* 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;
836

837
    return len;
838

839
}
840

841 842 843 844 845
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) {
846

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

852 853 854 855 856 857 858 859 860 861 862 863
/* 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.
 */

864 865 866
static ssize_t ebml_parse_tag(unsigned char *buffer,
                             unsigned char *buffer_end,
                             unsigned long long *payload_length)
867
{
868 869
    size_t type_length;
    size_t size_length;
870
    unsigned long long value;
871

872
    *payload_length = 0;
873

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

877 878 879
    if (type_length <= 0) {
        return type_length;
    }
880

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

884 885 886
    if (size_length <= 0) {
        return size_length;
    }
887

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

907 908 909
    if (buffer >= buffer_end) {
        return 0;
    }
910

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

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

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

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

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

941
    /* catch special "unknown" length */
942

943 944 945 946 947 948 949 950 951
    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);
*/
952

953 954
    return size;
}
955 956 957 958 959 960 961

/* 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.
 */
962 963 964 965 966
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)
967 968
{
    long long value;
969
    size_t i;
970

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

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

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

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

990
    *out_value = value;
991

992 993
    return len;
}