~ubuntu-branches/ubuntu/vivid/mpv/vivid

« back to all changes in this revision

Viewing changes to demux/ebml.c

  • Committer: Package Import Robot
  • Author(s): Alessandro Ghedini
  • Date: 2013-12-29 20:04:26 UTC
  • mfrom: (1.1.9)
  • Revision ID: package-import@ubuntu.com-20131229200426-w0qsj8clnui1pxaw
Tags: 0.3.0-1
* New upstream release
  - Fix --vf=expand example in manpage (Closes: #732271)
* Add 03_waf.patch to provide uncompressed waf scripts and modules
* Switch to waf build script
* Drop libmng-dev Build-Depends (not used anymore)
* Bump Standards-Version to 3.9.5 (no changes needed)
* Enable support for dvdnav
* Install more docs

Show diffs side-by-side

added added

removed removed

Lines of Context:
35
35
#include "ebml.h"
36
36
#include "stream/stream.h"
37
37
#include "compat/mpbswap.h"
38
 
#include "mpvcore/mp_msg.h"
 
38
#include "common/msg.h"
39
39
 
40
40
#ifndef SIZE_MAX
41
41
#define SIZE_MAX ((size_t)-1)
272
272
/*
273
273
 * Skip to (probable) next cluster (MATROSKA_ID_CLUSTER) element start position.
274
274
 */
275
 
int ebml_resync_cluster(stream_t *s)
 
275
int ebml_resync_cluster(struct mp_log *log, stream_t *s)
276
276
{
277
277
    int64_t pos = stream_tell(s);
278
278
    uint32_t last_4_bytes = 0;
279
 
    mp_msg(MSGT_DEMUX, MSGL_ERR, "[mkv] Corrupt file detected. "
 
279
    mp_err(log, "Corrupt file detected. "
280
280
           "Trying to resync starting from position %"PRId64"...\n", pos);
281
281
    while (!s->eof) {
282
282
        // Assumes MATROSKA_ID_CLUSTER is 4 bytes, with no 0 bytes.
283
283
        if (last_4_bytes == MATROSKA_ID_CLUSTER) {
284
 
            mp_msg(MSGT_DEMUX, MSGL_ERR,
285
 
                   "[mkv] Cluster found at %"PRId64".\n", pos - 4);
 
284
            mp_err(log, "Cluster found at %"PRId64".\n", pos - 4);
286
285
            stream_seek(s, pos - 4);
287
286
            return 0;
288
287
        }
295
294
/*
296
295
 * Skip the current element, or on error, call ebml_resync_cluster().
297
296
 */
298
 
int ebml_read_skip_or_resync_cluster(stream_t *s, uint64_t *length)
 
297
int ebml_read_skip_or_resync_cluster(struct mp_log *log, stream_t *s,
 
298
                                     uint64_t *length)
299
299
{
300
300
    uint64_t len;
301
301
    int l;
319
319
    return 0;
320
320
 
321
321
resync:
322
 
    return ebml_resync_cluster(s) < 0 ? -1 : 1;
 
322
    return ebml_resync_cluster(log, s) < 0 ? -1 : 1;
323
323
}
324
324
 
325
325
/*
455
455
{
456
456
    assert(type->type == EBML_TYPE_SUBELEMENTS);
457
457
    assert(level < 8);
458
 
    mp_msg(MSGT_DEMUX, MSGL_DBG2, "%.*s[mkv] Parsing element %s\n",
459
 
           level, "       ", type->name);
 
458
    MP_DBG(ctx, "%.*sParsing element %s\n", level, "       ", type->name);
460
459
 
461
460
    char *s = target;
462
461
    uint8_t *end = data + size;
469
468
        if (len > end - p)
470
469
            goto past_end_error;
471
470
        if (len < 0) {
472
 
            mp_msg(MSGT_DEMUX, MSGL_DBG2, "[mkv] Error parsing subelement "
473
 
                   "id\n");
 
471
            MP_DBG(ctx, "Error parsing subelement id\n");
474
472
            goto other_error;
475
473
        }
476
474
        p += len;
478
476
        if (len > end - p)
479
477
            goto past_end_error;
480
478
        if (len < 0) {
481
 
            mp_msg(MSGT_DEMUX, MSGL_DBG2, "[mkv] Error parsing subelement "
482
 
                   "length\n");
 
479
            MP_DBG(ctx, "Error parsing subelement length\n");
483
480
            goto other_error;
484
481
        }
485
482
        p += len;
495
492
        if (length > end - p) {
496
493
            if (field_idx >= 0 && type->fields[field_idx].desc->type
497
494
                != EBML_TYPE_SUBELEMENTS) {
498
 
                mp_msg(MSGT_DEMUX, MSGL_DBG2, "[mkv] Subelement content goes "
 
495
                MP_DBG(ctx, "Subelement content goes "
499
496
                       "past end of containing element\n");
500
497
                goto other_error;
501
498
            }
508
505
        continue;
509
506
 
510
507
    past_end_error:
511
 
        mp_msg(MSGT_DEMUX, MSGL_DBG2, "[mkv] Subelement headers go "
 
508
        MP_DBG(ctx, "Subelement headers go "
512
509
               "past end of containing element\n");
513
510
    other_error:
514
511
        ctx->has_errors = true;
564
561
        if (length > end - data) {
565
562
            // Try to parse what is possible from inside this partial element
566
563
            length = end - data;
567
 
            mp_msg(MSGT_DEMUX, MSGL_DBG2, "[mkv] Next subelement content goes "
 
564
            MP_DBG(ctx, "Next subelement content goes "
568
565
                   "past end of containing element, will be truncated\n");
569
566
        }
570
567
        int field_idx = -1;
575
572
            }
576
573
        if (field_idx < 0) {
577
574
            if (id == 0xec)
578
 
                mp_msg(MSGT_DEMUX, MSGL_DBG2, "%.*s[mkv] Ignoring Void element "
 
575
                MP_DBG(ctx, "%.*sIgnoring Void element "
579
576
                       "size: %"PRIu64"\n", level+1, "        ", length);
580
577
            else if (id == 0xbf)
581
 
                mp_msg(MSGT_DEMUX, MSGL_DBG2, "%.*s[mkv] Ignoring CRC-32 "
 
578
                MP_DBG(ctx, "%.*sIgnoring CRC-32 "
582
579
                       "element size: %"PRIu64"\n", level+1, "        ",
583
580
                       length);
584
581
            else
585
 
                mp_msg(MSGT_DEMUX, MSGL_DBG2, "[mkv] Ignoring unrecognized "
 
582
                MP_DBG(ctx, "Ignoring unrecognized "
586
583
                       "subelement. ID: %x size: %"PRIu64"\n", id, length);
587
584
            data += length;
588
585
            continue;
593
590
        int *countptr = (int *) (s + fd->count_offset);
594
591
        if (*countptr >= num_elems[field_idx]) {
595
592
            // Shouldn't happen with on any sane file without bugs
596
 
            mp_msg(MSGT_DEMUX, MSGL_ERR, "[mkv] Too many subelems?\n");
 
593
            MP_ERR(ctx, "Too many subelems?\n");
597
594
            ctx->has_errors = true;
598
595
            data += length;
599
596
            continue;
600
597
        }
601
598
        if (*countptr > 0 && !multiple) {
602
 
            mp_msg(MSGT_DEMUX, MSGL_DBG2, "[mkv] Another subelement of type "
 
599
            MP_DBG(ctx, "Another subelement of type "
603
600
                   "%x %s (size: %"PRIu64"). Only one allowed. Ignoring.\n",
604
601
                   id, ed->name, length);
605
602
            ctx->has_errors = true;
606
603
            data += length;
607
604
            continue;
608
605
        }
609
 
        mp_msg(MSGT_DEMUX, MSGL_DBG2, "%.*s[mkv] Parsing %x %s size: %"PRIu64
 
606
        MP_DBG(ctx, "%.*sParsing %x %s size: %"PRIu64
610
607
               " value: ", level+1, "        ", id, ed->name, length);
611
608
 
612
609
        char *fieldptr = s + fd->offset;
613
610
        switch (ed->type) {
614
611
        case EBML_TYPE_SUBELEMENTS:
615
 
            mp_msg(MSGT_DEMUX, MSGL_DBG2, "subelements\n");
 
612
            MP_DBG(ctx, "subelements\n");
616
613
            char *subelptr;
617
614
            if (multiple) {
618
615
                char *array_start = (char *) *(generic_struct **) fieldptr;
631
628
                subelptr = (fieldtype *) fieldptr
632
629
            GETPTR(uintptr, uint64_t);
633
630
            if (length < 1 || length > 8) {
634
 
                mp_msg(MSGT_DEMUX, MSGL_DBG2, "uint invalid length %"PRIu64
 
631
                MP_DBG(ctx, "uint invalid length %"PRIu64
635
632
                       "\n", length);
636
633
                goto error;
637
634
            }
638
635
            *uintptr = ebml_parse_uint(data, length);
639
 
            mp_msg(MSGT_DEMUX, MSGL_DBG2, "uint %"PRIu64"\n", *uintptr);
 
636
            MP_DBG(ctx, "uint %"PRIu64"\n", *uintptr);
640
637
            break;
641
638
 
642
639
        case EBML_TYPE_SINT:;
643
640
            int64_t *sintptr;
644
641
            GETPTR(sintptr, int64_t);
645
642
            if (length < 1 || length > 8) {
646
 
                mp_msg(MSGT_DEMUX, MSGL_DBG2, "sint invalid length %"PRIu64
 
643
                MP_DBG(ctx, "sint invalid length %"PRIu64
647
644
                       "\n", length);
648
645
                goto error;
649
646
            }
650
647
            *sintptr = ebml_parse_sint(data, length);
651
 
            mp_msg(MSGT_DEMUX, MSGL_DBG2, "sint %"PRId64"\n", *sintptr);
 
648
            MP_DBG(ctx, "sint %"PRId64"\n", *sintptr);
652
649
            break;
653
650
 
654
651
        case EBML_TYPE_FLOAT:;
655
652
            double *floatptr;
656
653
            GETPTR(floatptr, double);
657
654
            if (length != 4 && length != 8) {
658
 
                mp_msg(MSGT_DEMUX, MSGL_DBG2, "float invalid length %"PRIu64
 
655
                MP_DBG(ctx, "float invalid length %"PRIu64
659
656
                       "\n", length);
660
657
                goto error;
661
658
            }
662
659
            *floatptr = ebml_parse_float(data, length);
663
 
            mp_msg(MSGT_DEMUX, MSGL_DBG2, "float %f\n", *floatptr);
 
660
            MP_DBG(ctx, "float %f\n", *floatptr);
664
661
            break;
665
662
 
666
663
        case EBML_TYPE_STR:
670
667
            strptr->start = data;
671
668
            strptr->len = length;
672
669
            if (ed->type == EBML_TYPE_STR)
673
 
                mp_msg(MSGT_DEMUX, MSGL_DBG2, "string \"%.*s\"\n",
 
670
                MP_DBG(ctx, "string \"%.*s\"\n",
674
671
                       BSTR_P(*strptr));
675
672
            else
676
 
                mp_msg(MSGT_DEMUX, MSGL_DBG2, "binary %zd bytes\n",
 
673
                MP_DBG(ctx, "binary %zd bytes\n",
677
674
                       strptr->len);
678
675
            break;
679
676
 
682
679
            GETPTR(idptr, uint32_t);
683
680
            *idptr = ebml_parse_id(data, &len);
684
681
            if (len != length) {
685
 
                mp_msg(MSGT_DEMUX, MSGL_DBG2, "ebml_id broken value\n");
 
682
                MP_DBG(ctx, "ebml_id broken value\n");
686
683
                goto error;
687
684
            }
688
 
            mp_msg(MSGT_DEMUX, MSGL_DBG2, "ebml_id %x\n", (unsigned)*idptr);
 
685
            MP_DBG(ctx, "ebml_id %x\n", (unsigned)*idptr);
689
686
            break;
690
687
        default:
691
688
            abort();
701
698
                      void *target, const struct ebml_elem_desc *desc)
702
699
{
703
700
    ctx->has_errors = false;
704
 
    int msglevel = ctx->no_error_messages ? MSGL_DBG2 : MSGL_WARN;
 
701
    int msglevel = ctx->no_error_messages ? MSGL_DEBUG : MSGL_WARN;
705
702
    uint64_t length = ebml_read_length(s, &ctx->bytes_read);
706
703
    if (s->eof) {
707
 
        mp_msg(MSGT_DEMUX, msglevel, "[mkv] Unexpected end of file "
 
704
        MP_MSG(ctx, msglevel, "Unexpected end of file "
708
705
                   "- partial or corrupt file?\n");
709
706
        return -1;
710
707
    }
711
708
    if (length > 1000000000) {
712
 
        mp_msg(MSGT_DEMUX, msglevel, "[mkv] Refusing to read element over "
713
 
               "100 MB in size\n");
 
709
        MP_MSG(ctx, msglevel, "Refusing to read element over 100 MB in size\n");
714
710
        return -1;
715
711
    }
716
712
    ctx->talloc_ctx = talloc_size(NULL, length + 8);
717
713
    int read_len = stream_read(s, ctx->talloc_ctx, length);
718
714
    ctx->bytes_read += read_len;
719
715
    if (read_len < length)
720
 
        mp_msg(MSGT_DEMUX, msglevel, "[mkv] Unexpected end of file "
721
 
               "- partial or corrupt file?\n");
 
716
        MP_MSG(ctx, msglevel, "Unexpected end of file - partial or corrupt file?\n");
722
717
    ebml_parse_element(ctx, target, ctx->talloc_ctx, read_len, desc, 0);
723
718
    if (ctx->has_errors)
724
 
        mp_msg(MSGT_DEMUX, msglevel, "[mkv] Error parsing element %s\n",
725
 
               desc->name);
 
719
        MP_MSG(ctx, msglevel, "Error parsing element %s\n", desc->name);
726
720
    return 0;
727
721
}