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

📄 matroskadec.c

📁 ffmpeg的完整源代码和作者自己写的文档。不但有在Linux的工程哦
💻 C
📖 第 1 页 / 共 5 页
字号:
                        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 + -