comparison matroskadec.c @ 3633:7a44217312bb libavformat

matroskadec: use generic ebml parser to parse ebml header
author aurel
date Tue, 05 Aug 2008 00:40:02 +0000
parents a43869dda583
children f206f746ff61
comparison
equal deleted inserted replaced
3632:a43869dda583 3633:7a44217312bb
78 int size; 78 int size;
79 uint8_t *data; 79 uint8_t *data;
80 int64_t pos; 80 int64_t pos;
81 } EbmlBin; 81 } EbmlBin;
82 82
83 typedef struct {
84 uint64_t version;
85 uint64_t max_size;
86 uint64_t id_length;
87 char *doctype;
88 uint64_t doctype_version;
89 } Ebml;
90
83 typedef struct Track { 91 typedef struct Track {
84 MatroskaTrackType type; 92 MatroskaTrackType type;
85 93
86 /* Unique track number and track ID. stream_index is the index that 94 /* Unique track number and track ID. stream_index is the index that
87 * the calling app uses for this track. */ 95 * the calling app uses for this track. */
201 AVStream *skip_to_stream; 209 AVStream *skip_to_stream;
202 } MatroskaDemuxContext; 210 } MatroskaDemuxContext;
203 211
204 #define ARRAY_SIZE(x) (sizeof(x)/sizeof(*x)) 212 #define ARRAY_SIZE(x) (sizeof(x)/sizeof(*x))
205 213
214 static EbmlSyntax ebml_header[] = {
215 { EBML_ID_EBMLREADVERSION, EBML_UINT, 0, offsetof(Ebml,version), {.u=EBML_VERSION} },
216 { EBML_ID_EBMLMAXSIZELENGTH, EBML_UINT, 0, offsetof(Ebml,max_size), {.u=8} },
217 { EBML_ID_EBMLMAXIDLENGTH, EBML_UINT, 0, offsetof(Ebml,id_length), {.u=4} },
218 { EBML_ID_DOCTYPE, EBML_STR, 0, offsetof(Ebml,doctype), {.s="(none)"} },
219 { EBML_ID_DOCTYPEREADVERSION, EBML_UINT, 0, offsetof(Ebml,doctype_version), {.u=1} },
220 { EBML_ID_EBMLVERSION, EBML_NONE },
221 { EBML_ID_DOCTYPEVERSION, EBML_NONE },
222 { EBML_ID_VOID, EBML_NONE },
223 { 0 }
224 };
225
226 static EbmlSyntax ebml_syntax[] = {
227 { EBML_ID_HEADER, EBML_NEST, 0, 0, {.n=ebml_header} },
228 { 0 }
229 };
230
206 /* 231 /*
207 * The first few functions handle EBML file parsing. The rest 232 * The first few functions handle EBML file parsing. The rest
208 * is the document interpretation. Matroska really just is a 233 * is the document interpretation. Matroska really just is a
209 * EBML file. 234 * EBML file.
210 */ 235 */
690 *num = INT64_MAX; 715 *num = INT64_MAX;
691 else 716 else
692 *num = unum - ((1LL << ((7 * res) - 1)) - 1); 717 *num = unum - ((1LL << ((7 * res) - 1)) - 1);
693 718
694 return res; 719 return res;
695 }
696
697 /*
698 * Read an EBML header.
699 * 0 is success, < 0 is failure.
700 */
701
702 static int
703 ebml_read_header (MatroskaDemuxContext *matroska,
704 char **doctype,
705 int *version)
706 {
707 uint32_t id;
708 int level_up, res = 0;
709
710 /* default init */
711 if (doctype)
712 *doctype = NULL;
713 if (version)
714 *version = 1;
715
716 if (!(id = ebml_peek_id(matroska, &level_up)) ||
717 level_up != 0 || id != EBML_ID_HEADER) {
718 av_log(matroska->ctx, AV_LOG_ERROR,
719 "This is not an EBML file (id=0x%x/0x%x)\n", id, EBML_ID_HEADER);
720 return AVERROR_INVALIDDATA;
721 }
722 if ((res = ebml_read_master(matroska, &id)) < 0)
723 return res;
724
725 while (res == 0) {
726 if (!(id = ebml_peek_id(matroska, &level_up)))
727 return AVERROR(EIO);
728
729 /* end-of-header */
730 if (level_up)
731 break;
732
733 switch (id) {
734 /* is our read version uptodate? */
735 case EBML_ID_EBMLREADVERSION: {
736 uint64_t num;
737
738 if ((res = ebml_read_uint(matroska, &id, &num)) < 0)
739 return res;
740 if (num > EBML_VERSION) {
741 av_log(matroska->ctx, AV_LOG_ERROR,
742 "EBML version %"PRIu64" (> %d) is not supported\n",
743 num, EBML_VERSION);
744 return AVERROR_INVALIDDATA;
745 }
746 break;
747 }
748
749 /* we only handle 8 byte lengths at max */
750 case EBML_ID_EBMLMAXSIZELENGTH: {
751 uint64_t num;
752
753 if ((res = ebml_read_uint(matroska, &id, &num)) < 0)
754 return res;
755 if (num > sizeof(uint64_t)) {
756 av_log(matroska->ctx, AV_LOG_ERROR,
757 "Integers of size %"PRIu64" (> %zd) not supported\n",
758 num, sizeof(uint64_t));
759 return AVERROR_INVALIDDATA;
760 }
761 break;
762 }
763
764 /* we handle 4 byte IDs at max */
765 case EBML_ID_EBMLMAXIDLENGTH: {
766 uint64_t num;
767
768 if ((res = ebml_read_uint(matroska, &id, &num)) < 0)
769 return res;
770 if (num > sizeof(uint32_t)) {
771 av_log(matroska->ctx, AV_LOG_ERROR,
772 "IDs of size %"PRIu64" (> %zu) not supported\n",
773 num, sizeof(uint32_t));
774 return AVERROR_INVALIDDATA;
775 }
776 break;
777 }
778
779 case EBML_ID_DOCTYPE: {
780 char *text;
781
782 if ((res = ebml_read_ascii(matroska, &id, &text)) < 0)
783 return res;
784 if (doctype) {
785 if (*doctype)
786 av_free(*doctype);
787 *doctype = text;
788 } else
789 av_free(text);
790 break;
791 }
792
793 case EBML_ID_DOCTYPEREADVERSION: {
794 uint64_t num;
795
796 if ((res = ebml_read_uint(matroska, &id, &num)) < 0)
797 return res;
798 if (version)
799 *version = num;
800 break;
801 }
802
803 default:
804 av_log(matroska->ctx, AV_LOG_INFO,
805 "Unknown data type 0x%x in EBML header", id);
806 /* pass-through */
807
808 case EBML_ID_VOID:
809 /* we ignore these two, as they don't tell us anything we
810 * care about */
811 case EBML_ID_EBMLVERSION:
812 case EBML_ID_DOCTYPEVERSION:
813 res = ebml_read_skip (matroska);
814 break;
815 }
816 }
817
818 return 0;
819 } 720 }
820 721
821 722
822 static int 723 static int
823 matroska_find_track_by_num (MatroskaDemuxContext *matroska, 724 matroska_find_track_by_num (MatroskaDemuxContext *matroska,
2498 static int 2399 static int
2499 matroska_read_header (AVFormatContext *s, 2400 matroska_read_header (AVFormatContext *s,
2500 AVFormatParameters *ap) 2401 AVFormatParameters *ap)
2501 { 2402 {
2502 MatroskaDemuxContext *matroska = s->priv_data; 2403 MatroskaDemuxContext *matroska = s->priv_data;
2503 char *doctype; 2404 int last_level, res = 0;
2504 int version, last_level, res = 0; 2405 Ebml ebml = { 0 };
2505 uint32_t id; 2406 uint32_t id;
2506 2407
2507 matroska->ctx = s; 2408 matroska->ctx = s;
2508 2409
2509 /* First read the EBML header. */ 2410 /* First read the EBML header. */
2510 doctype = NULL; 2411 if (ebml_parse(matroska, ebml_syntax, &ebml, 0, 1)
2511 if ((res = ebml_read_header(matroska, &doctype, &version)) < 0) 2412 || ebml.version > EBML_VERSION || ebml.max_size > sizeof(uint64_t)
2512 return res; 2413 || ebml.id_length > sizeof(uint32_t) || strcmp(ebml.doctype, "matroska")
2513 if ((doctype == NULL) || strcmp(doctype, "matroska")) { 2414 || ebml.doctype_version > 2) {
2514 av_log(matroska->ctx, AV_LOG_ERROR, 2415 av_log(matroska->ctx, AV_LOG_ERROR,
2515 "Wrong EBML doctype ('%s' != 'matroska').\n", 2416 "EBML header using unsupported features\n"
2516 doctype ? doctype : "(none)"); 2417 "(EBML version %"PRIu64", doctype %s, doc version %"PRIu64")\n",
2517 if (doctype) 2418 ebml.version, ebml.doctype, ebml.doctype_version);
2518 av_free(doctype);
2519 return AVERROR_NOFMT; 2419 return AVERROR_NOFMT;
2520 } 2420 }
2521 av_free(doctype); 2421 ebml_free(ebml_syntax, &ebml);
2522 if (version > 2) {
2523 av_log(matroska->ctx, AV_LOG_ERROR,
2524 "Matroska demuxer version 2 too old for file version %d\n",
2525 version);
2526 return AVERROR_NOFMT;
2527 }
2528 2422
2529 /* The next thing is a segment. */ 2423 /* The next thing is a segment. */
2530 while (1) { 2424 while (1) {
2531 if (!(id = ebml_peek_id(matroska, &last_level))) 2425 if (!(id = ebml_peek_id(matroska, &last_level)))
2532 return AVERROR(EIO); 2426 return AVERROR(EIO);