comparison matroskadec.c @ 6029:7e9deb9f0234 libavformat

matroskadec: Support webm doctype Patch by James Zern <jzern at google>
author conrad
date Sat, 22 May 2010 01:41:32 +0000
parents b36bdd7213ea
children fd82ce3c4e65
comparison
equal deleted inserted replaced
6028:d920f5eb9d10 6029:7e9deb9f0234
503 { MATROSKA_ID_TAGS, EBML_NONE }, 503 { MATROSKA_ID_TAGS, EBML_NONE },
504 { MATROSKA_ID_SEEKHEAD, EBML_NONE }, 504 { MATROSKA_ID_SEEKHEAD, EBML_NONE },
505 { 0 } 505 { 0 }
506 }; 506 };
507 507
508 static const char *matroska_doctypes[] = { "matroska", "webm" };
509
508 /* 510 /*
509 * Return: Whether we reached the end of a level in the hierarchy or not. 511 * Return: Whether we reached the end of a level in the hierarchy or not.
510 */ 512 */
511 static int ebml_level_end(MatroskaDemuxContext *matroska) 513 static int ebml_level_end(MatroskaDemuxContext *matroska)
512 { 514 {
823 * Autodetecting... 825 * Autodetecting...
824 */ 826 */
825 static int matroska_probe(AVProbeData *p) 827 static int matroska_probe(AVProbeData *p)
826 { 828 {
827 uint64_t total = 0; 829 uint64_t total = 0;
828 int len_mask = 0x80, size = 1, n = 1; 830 int len_mask = 0x80, size = 1, n = 1, i;
829 static const char probe_data[] = "matroska";
830 831
831 /* EBML header? */ 832 /* EBML header? */
832 if (AV_RB32(p->buf) != EBML_ID_HEADER) 833 if (AV_RB32(p->buf) != EBML_ID_HEADER)
833 return 0; 834 return 0;
834 835
846 847
847 /* Does the probe data contain the whole header? */ 848 /* Does the probe data contain the whole header? */
848 if (p->buf_size < 4 + size + total) 849 if (p->buf_size < 4 + size + total)
849 return 0; 850 return 0;
850 851
851 /* The header must contain the document type 'matroska'. For now, 852 /* The header should contain a known document type. For now,
852 * we don't parse the whole header but simply check for the 853 * we don't parse the whole header but simply check for the
853 * availability of that array of characters inside the header. 854 * availability of that array of characters inside the header.
854 * Not fully fool-proof, but good enough. */ 855 * Not fully fool-proof, but good enough. */
855 for (n = 4+size; n <= 4+size+total-(sizeof(probe_data)-1); n++) 856 for (i = 0; i < FF_ARRAY_ELEMS(matroska_doctypes); i++) {
856 if (!memcmp(p->buf+n, probe_data, sizeof(probe_data)-1)) 857 int probelen = strlen(matroska_doctypes[i]);
857 return AVPROBE_SCORE_MAX; 858 for (n = 4+size; n <= 4+size+total-probelen; n++)
859 if (!memcmp(p->buf+n, matroska_doctypes[i], probelen))
860 return AVPROBE_SCORE_MAX;
861 }
858 862
859 return 0; 863 return 0;
860 } 864 }
861 865
862 static MatroskaTrack *matroska_find_track_by_num(MatroskaDemuxContext *matroska, 866 static MatroskaTrack *matroska_find_track_by_num(MatroskaDemuxContext *matroska,
1139 matroska->ctx = s; 1143 matroska->ctx = s;
1140 1144
1141 /* First read the EBML header. */ 1145 /* First read the EBML header. */
1142 if (ebml_parse(matroska, ebml_syntax, &ebml) 1146 if (ebml_parse(matroska, ebml_syntax, &ebml)
1143 || ebml.version > EBML_VERSION || ebml.max_size > sizeof(uint64_t) 1147 || ebml.version > EBML_VERSION || ebml.max_size > sizeof(uint64_t)
1144 || ebml.id_length > sizeof(uint32_t) || strcmp(ebml.doctype, "matroska") 1148 || ebml.id_length > sizeof(uint32_t) || ebml.doctype_version > 2) {
1145 || ebml.doctype_version > 2) {
1146 av_log(matroska->ctx, AV_LOG_ERROR, 1149 av_log(matroska->ctx, AV_LOG_ERROR,
1147 "EBML header using unsupported features\n" 1150 "EBML header using unsupported features\n"
1148 "(EBML version %"PRIu64", doctype %s, doc version %"PRIu64")\n", 1151 "(EBML version %"PRIu64", doctype %s, doc version %"PRIu64")\n",
1149 ebml.version, ebml.doctype, ebml.doctype_version); 1152 ebml.version, ebml.doctype, ebml.doctype_version);
1153 ebml_free(ebml_syntax, &ebml);
1150 return AVERROR_PATCHWELCOME; 1154 return AVERROR_PATCHWELCOME;
1151 } 1155 }
1156 for (i = 0; i < FF_ARRAY_ELEMS(matroska_doctypes); i++)
1157 if (!strcmp(ebml.doctype, matroska_doctypes[i]))
1158 break;
1159 if (i >= FF_ARRAY_ELEMS(matroska_doctypes)) {
1160 av_log(s, AV_LOG_ERROR, "Unknown EBML doctype '%s'\n", ebml.doctype);
1161 ebml_free(ebml_syntax, &ebml);
1162 return AVERROR_PATCHWELCOME;
1163 }
1164 av_metadata_set2(&s->metadata, "doctype", ebml.doctype, 0);
1152 ebml_free(ebml_syntax, &ebml); 1165 ebml_free(ebml_syntax, &ebml);
1153 1166
1154 /* The next thing is a segment. */ 1167 /* The next thing is a segment. */
1155 if (ebml_parse(matroska, matroska_segments, matroska) < 0) 1168 if (ebml_parse(matroska, matroska_segments, matroska) < 0)
1156 return -1; 1169 return -1;