⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 matroskadec.c

📁 mediastreamer2是开源的网络传输媒体流的库
💻 C
📖 第 1 页 / 共 5 页
字号:
        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;                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;}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 (id) {                case MATROSKA_ID_FILENAME:                    res = ebml_read_utf8 (matroska, &id, &name);                    break;                case MATROSKA_ID_FILEMIMETYPE:                    res = ebml_read_ascii (matroska, &id, &mime);                    break;                case MATROSKA_ID_FILEDATA:                    res = ebml_read_binary(matroska, &id, &data, &data_size);                    break;                default:                    av_log(matroska->ctx, AV_LOG_INFO,                           "Unknown attachedfile ID 0x%x\n", id);                case EBML_ID_VOID:                    res = ebml_read_skip(matroska);                    break;                }                if (matroska->level_up) {                    matroska->level_up--;                    break;                }            }            if (!(name && mime && data && data_size > 0)) {                av_log(matroska->ctx, AV_LOG_ERROR, "incomplete attachment\n");                break;            }            st = av_new_stream(s, matroska->num_streams++);            if (st == NULL)                return AVERROR(ENOMEM);            st->filename = av_strdup(name);            st->codec->codec_id = CODEC_ID_NONE;            st->codec->codec_type = CODEC_TYPE_ATTACHMENT;            st->codec->extradata = av_malloc(data_size);            if(st->codec->extradata == NULL)                return AVERROR(ENOMEM);            st->codec->extradata_size = data_size;            memcpy(st->codec->extradata, data, data_size);            for (i=0; ff_mkv_mime_tags[i].id != CODEC_ID_NONE; i++) {                if (!strncmp(ff_mkv_mime_tags[i].str, mime,                             strlen(ff_mkv_mime_tags[i].str))) {                    st->codec->codec_id = ff_mkv_mime_tags[i].id;                    break;                }            }            av_log(matroska->ctx, AV_LOG_DEBUG, "new attachment: %s, %s, size %d \n", name, mime, data_size);            break;        }        default:            av_log(matroska->ctx, AV_LOG_INFO,                   "Unknown attachments 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;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -