matroskadec.c
来自「君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图」· C语言 代码 · 共 2,060 行 · 第 1/5 页
C
2,060 行
} 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; 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) return res; /* 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++; /* 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 */ 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;}#define ARRAY_SIZE(x) (sizeof(x)/sizeof(*x))static intmatroska_aac_profile (char *codec_id){ static const char *aac_profiles[] = { "MAIN", "LC", "SSR" }; int profile; for (profile=0; profile<ARRAY_SIZE(aac_profiles); profile++) if (strstr(codec_id, aac_profiles[profile])) break; return profile + 1;}static intmatroska_aac_sri (int samplerate){ static const int aac_sample_rates[] = { 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, }; int sri; for (sri=0; sri<ARRAY_SIZE(aac_sample_rates); sri++) if (aac_sample_rates[sri] == samplerate) break; return sri;}static intmatroska_read_header (AVFormatContext *s, AVFormatParameters *ap){ MatroskaDemuxContext *matroska = s->priv_data; char *doctype; int version, last_level, res = 0; uint32_t id; matroska->ctx = s; /* First read the EBML header. */ doctype = NULL; if ((res = ebml_read_header(matroska, &doctype, &version)) < 0) return res; if ((doctype == NULL) || strcmp(doctype, "matroska")) { av_log(matroska->ctx, AV_LOG_ERROR, "Wrong EBML doctype ('%s' != 'matroska').\n", doctype ? doctype : "(none)"); if (doctype) av_free(doctype); return AVERROR_NOFMT; } av_free(doctype); if (version > 2) { av_log(matroska->ctx, AV_LOG_ERROR, "Matroska demuxer version 2 too old for file version %d\n", version); return AVERROR_NOFMT; } /* The next thing is a segment. */ while (1) { if (!(id = ebml_peek_id(matroska, &last_level))) return AVERROR(EIO); if (id == MATROSKA_ID_SEGMENT) break; /* oi! */ av_log(matroska->ctx, AV_LOG_INFO, "Expected a Segment ID (0x%x), but received 0x%x!\n", MATROSKA_ID_SEGMENT, id); if ((res = ebml_read_skip(matroska)) < 0) return res; } /* We now have a Matroska segment. * Seeks are from the beginning of the segment, * after the segment ID/length. */ if ((res = ebml_read_master(matroska, &id)) < 0) return res; matroska->segment_start = url_ftell(&s->pb); matroska->time_scale = 1000000; /* we've found our segment, start reading the different contents in here */ 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) { /* stream info */ case MATROSKA_ID_INFO: { if ((res = ebml_read_master(matroska, &id)) < 0) break; res = matroska_parse_info(matroska); break; } /* track info headers */ case MATROSKA_ID_TRACKS: { if ((res = ebml_read_master(matroska, &id)) < 0) break; res = matroska_parse_tracks(matroska); break; } /* stream index */ case MATROSKA_ID_CUES: { if (!matroska->index_parsed) { if ((res = ebml_read_master(matroska, &id)) < 0) break; res = matroska_parse_index(matroska); } else res = ebml_read_skip(matroska); break; } /* metadata */ case MATROSKA_ID_TAGS: { if (!matroska->metadata_parsed) { if ((res = ebml_read_master(matroska, &id)) < 0) break; res = matroska_parse_metadata(matroska); } else res = ebml_read_skip(matroska); break; } /* file index (if seekable, seek to Cues/Tags to parse it) */ case MATROSKA_ID_SEEKHEAD: { if ((res = ebml_read_master(matroska, &id)) < 0) break; res = matroska_parse_seekhead(matroska); break; } case MATROSKA_ID_CLUSTER: { /* Do not read the master - this will be done in the next * call to matroska_read_packet. */ res = 1; break; } default: av_log(matroska->ctx, AV_LOG_INFO, "Unknown matroska file header 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; } } /* Have we found a cluster? */ if (ebml_peek_id(matroska, NULL) == MATROSKA_ID_CLUSTER) { int i, j; MatroskaTrack *track; AVStream *st; for (i = 0; i < matroska->num_tracks; i++) { enum CodecID codec_id = CODEC_ID_NONE; uint8_t *extradata = NULL; int extradata_size = 0; int extradata_offset = 0; track = matroska->tracks[i]; track->stream_index = -1; /* Apply some sanity checks. */ if (track->codec_id == NULL) continue; for(j=0; ff_mkv_codec_tags[j].str; j++){ if(!strncmp(ff_mkv_codec_tags[j].str, track->codec_id, strlen(ff_mkv_codec_tags[j].str))){ codec_id= ff_mkv_codec_tags[j].id; break; } } /* Set the FourCC from the CodecID. */ /* This is the MS compatibility mode which stores a * BITMAPINFOHEADER in the CodecPrivate. */ if (!strcmp(track->codec_id, MATROSKA_CODEC_ID_VIDEO_VFW_FOURCC) && (track->codec_priv_size >= 40) && (track->codec_priv != NULL)) { MatroskaVideoTrack *vtrack = (MatroskaVideoTrack *) track; /* Offset of biCompression. Stored in LE. */ vtrack->fourcc = AV_RL32(track->codec_priv + 16); codec_id = codec_get_id(codec_bmp_tags, vtrack->fourcc); } /* This is the MS compatibility mode which stores a * WAVEF
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?