matroskadec.c
来自「君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图」· C语言 代码 · 共 2,000 行 · 第 1/5 页
C
2,000 行
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 && idx.time != (uint64_t) -1 && idx.track != (uint16_t) -1) { if (matroska->num_indexes % 32 == 0) { /* re-allocate bigger index */ matroska->index = av_realloc(matroska->index, (matroska->num_indexes + 32) * sizeof(MatroskaDemuxIndex)); } matroska->index[matroska->num_indexes] = idx; matroska->num_indexes++; } break; default: av_log(matroska->ctx, AV_LOG_INFO, "Unknown entry 0x%x in cues 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 intmatroska_parse_metadata (MatroskaDemuxContext *matroska){ int res = 0; uint32_t id; 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) { /* Hm, this is unsupported... */ default: av_log(matroska->ctx, AV_LOG_INFO, "Unknown entry 0x%x in metadata 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 intmatroska_parse_seekhead (MatroskaDemuxContext *matroska){ int res = 0; uint32_t id; av_log(matroska->ctx, AV_LOG_DEBUG, "parsing seekhead...\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) { case MATROSKA_ID_SEEKENTRY: { uint32_t seek_id = 0, peek_id_cache = 0; uint64_t seek_pos = (uint64_t) -1, t; int dummy_level = 0; 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) { case MATROSKA_ID_SEEKID: res = ebml_read_uint(matroska, &id, &t); seek_id = t; break; case MATROSKA_ID_SEEKPOSITION: res = ebml_read_uint(matroska, &id, &seek_pos); break; default: av_log(matroska->ctx, AV_LOG_INFO, "Unknown seekhead ID 0x%x\n", id); /* fall-through */ case EBML_ID_VOID: res = ebml_read_skip(matroska); break; } if (matroska->level_up) { matroska->level_up--; break; } } if (!seek_id || seek_pos == (uint64_t) -1) { av_log(matroska->ctx, AV_LOG_INFO, "Incomplete seekhead entry (0x%x/%"PRIu64")\n", seek_id, seek_pos); break; } switch (seek_id) { case MATROSKA_ID_CUES: case MATROSKA_ID_TAGS: { uint32_t level_up = matroska->level_up; offset_t before_pos; uint64_t length; MatroskaLevel level; /* remember the peeked ID and the current position */ peek_id_cache = matroska->peek_id; before_pos = url_ftell(matroska->ctx->pb); /* seek */ if ((res = ebml_read_seek(matroska, seek_pos + matroska->segment_start)) < 0) goto finish; /* we don't want to lose our seekhead level, so we add * a dummy. This is a crude hack. */ if (matroska->num_levels == EBML_MAX_DEPTH) { av_log(matroska->ctx, AV_LOG_INFO, "Max EBML element depth (%d) reached, " "cannot parse further.\n", EBML_MAX_DEPTH); return AVERROR_UNKNOWN; } level.start = 0; level.length = (uint64_t)-1; matroska->levels[matroska->num_levels] = level; matroska->num_levels++; dummy_level = 1; /* check ID */ if (!(id = ebml_peek_id (matroska, &matroska->level_up))) goto finish; if (id != seek_id) { av_log(matroska->ctx, AV_LOG_INFO, "We looked for ID=0x%x but got " "ID=0x%x (pos=%"PRIu64")", seek_id, id, seek_pos + matroska->segment_start); goto finish; } /* read master + parse */ if ((res = ebml_read_master(matroska, &id)) < 0) goto finish; switch (id) { case MATROSKA_ID_CUES: if (!(res = matroska_parse_index(matroska)) || url_feof(matroska->ctx->pb)) { matroska->index_parsed = 1; res = 0; } break; case MATROSKA_ID_TAGS: if (!(res = matroska_parse_metadata(matroska)) || url_feof(matroska->ctx->pb)) { matroska->metadata_parsed = 1; res = 0; } break; } finish: /* remove dummy level */ if (dummy_level) while (matroska->num_levels) { matroska->num_levels--; length = matroska->levels[matroska->num_levels].length; if (length == (uint64_t)-1) break; } /* seek back */ if ((res = ebml_read_seek(matroska, before_pos)) < 0) return res; matroska->peek_id = peek_id_cache; matroska->level_up = level_up; break; } default: av_log(matroska->ctx, AV_LOG_INFO, "Ignoring seekhead entry for ID=0x%x\n", seek_id); break; } break; } default: av_log(matroska->ctx, AV_LOG_INFO, "Unknown seekhead ID 0x%x\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 intmatroska_parse_attachments(AVFormatContext *s){ MatroskaDemuxContext *matroska = s->priv_data; int res = 0; uint32_t id; av_log(matroska->ctx, AV_LOG_DEBUG, "parsing attachments...\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) { case MATROSKA_ID_ATTACHEDFILE: { char* name = NULL; char* mime = NULL; uint8_t* data = NULL; int i, data_size = 0; AVStream *st; 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 (
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?