if(extradata){ st->codec.extradata = extradata; st->codec.extradata_size = extradata_size; } else if(track->codec_priv && track->codec_priv_size > 0){ st->codec.extradata = av_malloc(track->codec_priv_size); if(st->codec.extradata == NULL) return AVERROR_NOMEM; st->codec.extradata_size = track->codec_priv_size; memcpy(st->codec.extradata, track->codec_priv, track->codec_priv_size); }
matroska_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 != 1) {        av_log(matroska->ctx, AV_LOG_ERROR,               "Matroska demuxer version 1 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_IO;        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_IO;            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;        }    }    if (res < 0)        return res;    /* Have we found a cluster? */    if (res == 1) {        int i;        enum CodecID codec_id;        MatroskaTrack *track;        AVStream *st;        for (i = 0; i < matroska->num_tracks; i++) {            track = matroska->tracks[i];            /* libavformat does not really support subtitles.             * Also apply some sanity checks. */            if ((track->type == MATROSKA_TRACK_TYPE_SUBTITLE) ||                (track->codec_id == NULL))                continue;            /* 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)) {                unsigned char *p;                /* Offset of biCompression. Stored in LE. */                p = (unsigned char *)track->codec_priv + 16;                ((MatroskaVideoTrack *)track)->fourcc = (p[3] << 24) |                                 (p[2] << 16) | (p[1] << 8) | p[0];                codec_id = codec_get_bmp_id(((MatroskaVideoTrack *)track)->fourcc);            } else if (!strcmp(track->codec_id,                               MATROSKA_CODEC_ID_VIDEO_MPEG4_SP) ||                       !strcmp(track->codec_id,                               MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP) ||                       !strcmp(track->codec_id,                               MATROSKA_CODEC_ID_VIDEO_MPEG4_AP))                codec_id = CODEC_ID_MPEG4;/*             else if (!strcmp(track->codec_id, *//*                              MATROSKA_CODEC_ID_VIDEO_UNCOMPRESSED)) *//*                 codec_id = CODEC_ID_???; */            else if (!strcmp(track->codec_id,                             MATROSKA_CODEC_ID_VIDEO_MSMPEG4V3))                codec_id = CODEC_ID_MSMPEG4V3;            else if (!strcmp(track->codec_id,                             MATROSKA_CODEC_ID_VIDEO_MPEG1) ||                     !strcmp(track->codec_id,                             MATROSKA_CODEC_ID_VIDEO_MPEG2))                codec_id = CODEC_ID_MPEG2VIDEO;            /* This is the MS compatibility mode which stores a             * WAVEFORMATEX in the CodecPrivate. */            else if (!strcmp(track->codec_id,                              MATROSKA_CODEC_ID_AUDIO_ACM) &&                (track->codec_priv_size >= 18) &&                (track->codec_priv != NULL)) {                unsigned char *p;                uint16_t tag;                /* Offset of wFormatTag. Stored in LE. */                p = (unsigned char *)track->codec_priv;                tag = (p[1] << 8) | p[0];                codec_id = codec_get_wav_id(tag);            } else if (!strcmp(track->codec_id,                               MATROSKA_CODEC_ID_AUDIO_MPEG1_L1) ||                       !strcmp(track->codec_id,                               MATROSKA_CODEC_ID_AUDIO_MPEG1_L2) ||                       !strcmp(track->codec_id,                               MATROSKA_CODEC_ID_AUDIO_MPEG1_L3))                codec_id = CODEC_ID_MP3;            else if (!strcmp(track->codec_id,                             MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE))                codec_id = CODEC_ID_PCM_U16BE;            else if (!strcmp(track->codec_id,                             MATROSKA_CODEC_ID_AUDIO_PCM_INT_LE))                codec_id = CODEC_ID_PCM_U16LE;/*             else if (!strcmp(track->codec_id, *//*                              MATROSKA_CODEC_ID_AUDIO_PCM_FLOAT)) *//*                 codec_id = CODEC_ID_PCM_???; */            else if (!strcmp(track->codec_id,                             MATROSKA_CODEC_ID_AUDIO_AC3))                codec_id = CODEC_ID_AC3;            else if (!strcmp(track->codec_id,                             MATROSKA_CODEC_ID_AUDIO_DTS))                codec_id = CODEC_ID_DTS;            /* No such codec id so far. *//*             else if (!strcmp(track->codec_id, *//*                              MATROSKA_CODEC_ID_AUDIO_DTS)) *//*                 codec_id = CODEC_ID_DTS; */            else if (!strcmp(track->codec_id,                             MATROSKA_CODEC_ID_AUDIO_VORBIS))                codec_id = CODEC_ID_VORBIS;            else if (!strcmp(track->codec_id,                             MATROSKA_CODEC_ID_AUDIO_MPEG2) ||                     !strcmp(track->codec_id,                             MATROSKA_CODEC_ID_AUDIO_MPEG4))                codec_id = CODEC_ID_AAC;            else                codec_id = CODEC_ID_NONE;            if (codec_id == CODEC_ID_NONE) {                av_log(matroska->ctx, AV_LOG_INFO,                       "Unknown/unsupported CodecID %s.\n",                       track->codec_id);            }            track->stream_index = matroska->num_streams;            matroska->num_streams++;            st = av_new_stream(s, track->stream_index);            if (st == NULL)                return AVERROR_NOMEM;            av_set_pts_info(st, 24, 1, 1000); /* 24 bit pts in ms */            st->codec.codec_id = codec_id;            if (track->type == MATROSKA_TRACK_TYPE_VIDEO) {                MatroskaVideoTrack *videotrack = (MatroskaVideoTrack *)track;                st->codec.codec_type = CODEC_TYPE_VIDEO;                st->codec.codec_tag = videotrack->fourcc;                st->codec.width = videotrack->pixel_width;                st->codec.height = videotrack->pixel_height;                if (videotrack->display_width == 0)                    st->codec.sample_aspect_ratio.num =                        videotrack->pixel_width;                else                    st->codec.sample_aspect_ratio.num =                        videotrack->display_width;                if (videotrack->display_height == 0)                    st->codec.sample_aspect_ratio.num =                        videotrack->pixel_height;                else                    st->codec.sample_aspect_ratio.num =                        videotrack->display_height;            } else if (track->type == MATROSKA_TRACK_TYPE_AUDIO) {                MatroskaAudioTrack *audiotrack = (MatroskaAudioTrack *)track;                st->codec.codec_type = CODEC_TYPE_AUDIO;                st->codec.sample_rate = audiotrack->samplerate;                st->codec.channels = audiotrack->channels;            }            /* What do we do with private data? E.g. for Vorbis. */        }    }    return 0;}