📄 matroskadec.c
字号:
case MATROSKA_ID_VIDEOCOLOURSPACE: {
uint64_t num;
if ((res = ebml_read_uint(matroska, &id,
&num)) < 0)
break;
videotrack->fourcc = num;
break;
}
default:
av_log(matroska->ctx, AV_LOG_INFO,
"Unknown video track header entry "
"0x%x - ignoring\n", id);
/* pass-through */
case EBML_ID_VOID:
res = ebml_read_skip(matroska);
break;
}
if (matroska->level_up) {
matroska->level_up--;
break;
}
}
break;
}
/* tracktype specific stuff for audio */
case MATROSKA_ID_TRACKAUDIO: {
MatroskaAudioTrack *audiotrack;
if (!track->type)
track->type = MATROSKA_TRACK_TYPE_AUDIO;
if (track->type != MATROSKA_TRACK_TYPE_AUDIO) {
av_log(matroska->ctx, AV_LOG_INFO,
"audio data in non-audio track - ignoring\n");
res = AVERROR_INVALIDDATA;
break;
} else if ((res = ebml_read_master(matroska, &id)) < 0)
break;
audiotrack = (MatroskaAudioTrack *)track;
audiotrack->channels = 1;
audiotrack->samplerate = 8000;
while (res == 0) {
if (!(id = ebml_peek_id(matroska, &matroska->level_up))) {
res = AVERROR(EIO);
break;
} else if (matroska->level_up > 0) {
matroska->level_up--;
break;
}
switch (id) {
/* samplerate */
case MATROSKA_ID_AUDIOSAMPLINGFREQ: {
double num;
if ((res = ebml_read_float(matroska, &id,
&num)) < 0)
break;
audiotrack->internal_samplerate =
audiotrack->samplerate = num;
break;
}
case MATROSKA_ID_AUDIOOUTSAMPLINGFREQ: {
double num;
if ((res = ebml_read_float(matroska, &id,
&num)) < 0)
break;
audiotrack->samplerate = num;
break;
}
/* bitdepth */
case MATROSKA_ID_AUDIOBITDEPTH: {
uint64_t num;
if ((res = ebml_read_uint(matroska, &id,
&num)) < 0)
break;
audiotrack->bitdepth = num;
break;
}
/* channels */
case MATROSKA_ID_AUDIOCHANNELS: {
uint64_t num;
if ((res = ebml_read_uint(matroska, &id,
&num)) < 0)
break;
audiotrack->channels = num;
break;
}
default:
av_log(matroska->ctx, AV_LOG_INFO,
"Unknown audio track header entry "
"0x%x - ignoring\n", id);
/* pass-through */
case EBML_ID_VOID:
res = ebml_read_skip(matroska);
break;
}
if (matroska->level_up) {
matroska->level_up--;
break;
}
}
break;
}
/* codec identifier */
case MATROSKA_ID_CODECID: {
char *text;
if ((res = ebml_read_ascii(matroska, &id, &text)) < 0)
break;
track->codec_id = text;
break;
}
/* codec private data */
case MATROSKA_ID_CODECPRIVATE: {
uint8_t *data;
int size;
if ((res = ebml_read_binary(matroska, &id, &data, &size) < 0))
break;
track->codec_priv = data;
track->codec_priv_size = size;
break;
}
/* name of the codec */
case MATROSKA_ID_CODECNAME: {
char *text;
if ((res = ebml_read_utf8(matroska, &id, &text)) < 0)
break;
track->codec_name = text;
break;
}
/* name of this track */
case MATROSKA_ID_TRACKNAME: {
char *text;
if ((res = ebml_read_utf8(matroska, &id, &text)) < 0)
break;
track->name = text;
break;
}
/* language (matters for audio/subtitles, mostly) */
case MATROSKA_ID_TRACKLANGUAGE: {
char *text, *end;
if ((res = ebml_read_utf8(matroska, &id, &text)) < 0)
break;
if ((end = strchr(text, '-')))
*end = '\0';
if (strlen(text) == 3)
strcpy(track->language, text);
av_free(text);
break;
}
/* whether this is actually used */
case MATROSKA_ID_TRACKFLAGENABLED: {
uint64_t num;
if ((res = ebml_read_uint(matroska, &id, &num)) < 0)
break;
if (num)
track->flags |= MATROSKA_TRACK_ENABLED;
else
track->flags &= ~MATROSKA_TRACK_ENABLED;
break;
}
/* whether it's the default for this track type */
case MATROSKA_ID_TRACKFLAGDEFAULT: {
uint64_t num;
if ((res = ebml_read_uint(matroska, &id, &num)) < 0)
break;
if (num)
track->flags |= MATROSKA_TRACK_DEFAULT;
else
track->flags &= ~MATROSKA_TRACK_DEFAULT;
break;
}
/* lacing (like MPEG, where blocks don't end/start on frame
* boundaries) */
case MATROSKA_ID_TRACKFLAGLACING: {
uint64_t num;
if ((res = ebml_read_uint(matroska, &id, &num)) < 0)
break;
if (num)
track->flags |= MATROSKA_TRACK_LACING;
else
track->flags &= ~MATROSKA_TRACK_LACING;
break;
}
/* default length (in time) of one data block in this track */
case MATROSKA_ID_TRACKDEFAULTDURATION: {
uint64_t num;
if ((res = ebml_read_uint(matroska, &id, &num)) < 0)
break;
track->default_duration = num;
break;
}
default:
av_log(matroska->ctx, AV_LOG_INFO,
"Unknown track header entry 0x%x - ignoring\n", id);
/* pass-through */
case EBML_ID_VOID:
/* we ignore these because they're nothing useful. */
case MATROSKA_ID_CODECINFOURL:
case MATROSKA_ID_CODECDOWNLOADURL:
case MATROSKA_ID_TRACKMINCACHE:
case MATROSKA_ID_TRACKMAXCACHE:
res = ebml_read_skip(matroska);
break;
}
if (matroska->level_up) {
matroska->level_up--;
break;
}
}
return res;
}
static int
matroska_parse_tracks (MatroskaDemuxContext *matroska)
{
int res = 0;
uint32_t id;
av_log(matroska->ctx, AV_LOG_DEBUG, "parsing tracks...\n");
while (res == 0) {
if (!(id = ebml_peek_id(matroska, &matroska->level_up))) {
res = AVERROR(EIO);
break;
} else if (matroska->level_up) {
matroska->level_up--;
break;
}
switch (id) {
/* one track within the "all-tracks" header */
case MATROSKA_ID_TRACKENTRY:
res = matroska_add_stream(matroska);
break;
default:
av_log(matroska->ctx, AV_LOG_INFO,
"Unknown entry 0x%x in track header\n", id);
/* fall-through */
case EBML_ID_VOID:
res = ebml_read_skip(matroska);
break;
}
if (matroska->level_up) {
matroska->level_up--;
break;
}
}
return res;
}
static int
matroska_parse_index (MatroskaDemuxContext *matroska)
{
int res = 0;
uint32_t id;
MatroskaDemuxIndex idx;
av_log(matroska->ctx, AV_LOG_DEBUG, "parsing index...\n");
while (res == 0) {
if (!(id = ebml_peek_id(matroska, &matroska->level_up))) {
res = AVERROR(EIO);
break;
} else if (matroska->level_up) {
matroska->level_up--;
break;
}
switch (id) {
/* one single index entry ('point') */
case MATROSKA_ID_POINTENTRY:
if ((res = ebml_read_master(matroska, &id)) < 0)
break;
/* in the end, we hope to fill one entry with a
* timestamp, a file position and a tracknum */
idx.pos = (uint64_t) -1;
idx.time = (uint64_t) -1;
idx.track = (uint16_t) -1;
while (res == 0) {
if (!(id = ebml_peek_id(matroska, &matroska->level_up))) {
res = AVERROR(EIO);
break;
} else if (matroska->level_up) {
matroska->level_up--;
break;
}
switch (id) {
/* one single index entry ('point') */
case MATROSKA_ID_CUETIME: {
uint64_t time;
if ((res = ebml_read_uint(matroska, &id,
&time)) < 0)
break;
idx.time = time * matroska->time_scale;
break;
}
/* position in the file + track to which it
* belongs */
case MATROSKA_ID_CUETRACKPOSITION:
if ((res = ebml_read_master(matroska, &id)) < 0)
break;
while (res == 0) {
if (!(id = ebml_peek_id (matroska,
&matroska->level_up))) {
res = AVERROR(EIO);
break;
} else if (matroska->level_up) {
matroska->level_up--;
break;
}
switch (id) {
/* track number */
case MATROSKA_ID_CUETRACK: {
uint64_t num;
if ((res = ebml_read_uint(matroska,
&id, &num)) < 0)
break;
idx.track = num;
break;
}
/* position in file */
case MATROSKA_ID_CUECLUSTERPOSITION: {
uint64_t num;
if ((res = ebml_read_uint(matroska,
&id, &num)) < 0)
break;
idx.pos = num+matroska->segment_start;
break;
}
default:
av_log(matroska->ctx, AV_LOG_INFO,
"Unknown entry 0x%x in "
"CuesTrackPositions\n", id);
/* fall-through */
case EBML_ID_VOID:
res = ebml_read_skip(matroska);
break;
}
if (matroska->level_up) {
matroska->level_up--;
break;
}
}
break;
default:
av_log(matroska->ctx, AV_LOG_INFO,
"Unknown entry 0x%x in cuespoint "
"index\n", id);
/* fall-through */
case EBML_ID_VOID:
res = ebml_read_skip(matroska);
break;
}
if (matroska->level_up) {
matroska->level_up--;
break;
}
}
/* so let's see if we got what we wanted */
if (idx.pos != (uint64_t) -1 &&
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -