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

📄 mov.c

📁 君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图片解码,浏览,电子书,录音,想学ucos,识货的人就下吧 russblock fmradio explore set
💻 C
📖 第 1 页 / 共 5 页
字号:
        return -1;    dprintf(c->fc, "track[%i].ctts.entries = %i\n", c->fc->nb_streams-1, entries);    for(i=0; i<entries; i++) {        int count    =get_be32(pb);        int duration =get_be32(pb);        if (duration < 0) {            av_log(c->fc, AV_LOG_ERROR, "negative ctts, ignoring\n");            sc->ctts_count = 0;            url_fskip(pb, 8 * (entries - i - 1));            break;        }        sc->ctts_data[i].count   = count;        sc->ctts_data[i].duration= duration;        sc->time_rate= ff_gcd(sc->time_rate, duration);    }    return 0;}static void mov_build_index(MOVContext *mov, AVStream *st){    MOVStreamContext *sc = st->priv_data;    offset_t current_offset;    int64_t current_dts = 0;    unsigned int stts_index = 0;    unsigned int stsc_index = 0;    unsigned int stss_index = 0;    unsigned int i, j;    /* only use old uncompressed audio chunk demuxing when stts specifies it */    if (!(st->codec->codec_type == CODEC_TYPE_AUDIO &&          sc->stts_count == 1 && sc->stts_data[0].duration == 1)) {        unsigned int current_sample = 0;        unsigned int stts_sample = 0;        unsigned int keyframe, sample_size;        unsigned int distance = 0;        int key_off = sc->keyframes && sc->keyframes[0] == 1;        st->nb_frames = sc->sample_count;        for (i = 0; i < sc->chunk_count; i++) {            current_offset = sc->chunk_offsets[i];            if (stsc_index + 1 < sc->sample_to_chunk_sz &&                i + 1 == sc->sample_to_chunk[stsc_index + 1].first)                stsc_index++;            for (j = 0; j < sc->sample_to_chunk[stsc_index].count; j++) {                if (current_sample >= sc->sample_count) {                    av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");                    goto out;                }                keyframe = !sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index];                if (keyframe) {                    distance = 0;                    if (stss_index + 1 < sc->keyframe_count)                        stss_index++;                }                sample_size = sc->sample_size > 0 ? sc->sample_size : sc->sample_sizes[current_sample];                if(sc->pseudo_stream_id == -1 ||                   sc->sample_to_chunk[stsc_index].id - 1 == sc->pseudo_stream_id) {                    av_add_index_entry(st, current_offset, current_dts, sample_size, distance,                                    keyframe ? AVINDEX_KEYFRAME : 0);                    dprintf(mov->fc, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "                            "size %d, distance %d, keyframe %d\n", st->index, current_sample,                            current_offset, current_dts, sample_size, distance, keyframe);                }                current_offset += sample_size;                assert(sc->stts_data[stts_index].duration % sc->time_rate == 0);                current_dts += sc->stts_data[stts_index].duration / sc->time_rate;                distance++;                stts_sample++;                current_sample++;                if (stts_index + 1 < sc->stts_count && stts_sample == sc->stts_data[stts_index].count) {                    stts_sample = 0;                    stts_index++;                }            }        }    } else { /* read whole chunk */        unsigned int chunk_samples, chunk_size, chunk_duration;        unsigned int frames = 1;        for (i = 0; i < sc->chunk_count; i++) {            current_offset = sc->chunk_offsets[i];            if (stsc_index + 1 < sc->sample_to_chunk_sz &&                i + 1 == sc->sample_to_chunk[stsc_index + 1].first)                stsc_index++;            chunk_samples = sc->sample_to_chunk[stsc_index].count;            /* get chunk size, beware of alaw/ulaw/mace */            if (sc->samples_per_frame > 0 &&                (chunk_samples * sc->bytes_per_frame % sc->samples_per_frame == 0)) {                if (sc->samples_per_frame < 160)                    chunk_size = chunk_samples * sc->bytes_per_frame / sc->samples_per_frame;                else {                    chunk_size = sc->bytes_per_frame;                    frames = chunk_samples / sc->samples_per_frame;                    chunk_samples = sc->samples_per_frame;                }            } else                chunk_size = chunk_samples * sc->sample_size;            for (j = 0; j < frames; j++) {                av_add_index_entry(st, current_offset, current_dts, chunk_size, 0, AVINDEX_KEYFRAME);                /* get chunk duration */                chunk_duration = 0;                while (chunk_samples > 0) {                    if (chunk_samples < sc->stts_data[stts_index].count) {                        chunk_duration += sc->stts_data[stts_index].duration * chunk_samples;                        sc->stts_data[stts_index].count -= chunk_samples;                        break;                    } else {                        chunk_duration += sc->stts_data[stts_index].duration * chunk_samples;                        chunk_samples -= sc->stts_data[stts_index].count;                        if (stts_index + 1 < sc->stts_count)                            stts_index++;                    }                }                current_offset += sc->bytes_per_frame;                dprintf(mov->fc, "AVIndex stream %d, chunk %d, offset %"PRIx64", dts %"PRId64", "                        "size %d, duration %d\n", st->index, i, current_offset, current_dts,                        chunk_size, chunk_duration);                assert(chunk_duration % sc->time_rate == 0);                current_dts += chunk_duration / sc->time_rate;            }        }    } out:    /* adjust sample count to avindex entries */    sc->sample_count = st->nb_index_entries;}static int mov_read_trak(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom){    AVStream *st;    MOVStreamContext *sc;    int ret;    st = av_new_stream(c->fc, c->fc->nb_streams);    if (!st) return AVERROR(ENOMEM);    sc = av_mallocz(sizeof(MOVStreamContext));    if (!sc) return AVERROR(ENOMEM);    st->priv_data = sc;    st->codec->codec_type = CODEC_TYPE_DATA;    st->start_time = 0; /* XXX: check */    if ((ret = mov_read_default(c, pb, atom)) < 0)        return ret;    /* sanity checks */    if(sc->chunk_count && (!sc->stts_count || !sc->sample_to_chunk_sz ||                           (!sc->sample_size && !sc->sample_count))){        av_log(c->fc, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",               st->index);        sc->sample_count = 0; //ignore track        return 0;    }    if(!sc->time_rate)        sc->time_rate=1;    if(!sc->time_scale)        sc->time_scale= c->time_scale;    av_set_pts_info(st, 64, sc->time_rate, sc->time_scale);    if (st->codec->codec_type == CODEC_TYPE_AUDIO &&        !st->codec->frame_size && sc->stts_count == 1)        st->codec->frame_size = av_rescale(sc->time_rate, st->codec->sample_rate, sc->time_scale);    if(st->duration != AV_NOPTS_VALUE){        assert(st->duration % sc->time_rate == 0);        st->duration /= sc->time_rate;    }    sc->ffindex = st->index;    mov_build_index(c, st);    if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {        if (url_fopen(&sc->pb, sc->drefs[sc->dref_id-1].path, URL_RDONLY) < 0)            av_log(c->fc, AV_LOG_ERROR, "stream %d, error opening file %s: %s\n",                   st->index, sc->drefs[sc->dref_id-1].path, strerror(errno));    } else        sc->pb = c->fc->pb;    switch (st->codec->codec_id) {#ifdef CONFIG_H261_DECODER    case CODEC_ID_H261:#endif#ifdef CONFIG_H263_DECODER    case CODEC_ID_H263:#endif#ifdef CONFIG_MPEG4_DECODER    case CODEC_ID_MPEG4:#endif        st->codec->width= 0; /* let decoder init width/height */        st->codec->height= 0;        break;#ifdef CONFIG_VORBIS_DECODER    case CODEC_ID_VORBIS:#endif        st->codec->sample_rate= 0; /* let decoder init parameters properly */        break;    }    /* Do not need those anymore. */    av_freep(&sc->chunk_offsets);    av_freep(&sc->sample_to_chunk);    av_freep(&sc->sample_sizes);    av_freep(&sc->keyframes);    av_freep(&sc->stts_data);    return 0;}static void mov_parse_udta_string(ByteIOContext *pb, char *str, int size){    uint16_t str_size = get_be16(pb); /* string length */;    get_be16(pb); /* skip language */    get_buffer(pb, str, FFMIN(size, str_size));}static int mov_read_udta(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom){    uint64_t end = url_ftell(pb) + atom.size;    while (url_ftell(pb) + 8 < end) {        uint32_t tag_size = get_be32(pb);        uint32_t tag      = get_le32(pb);        uint64_t next     = url_ftell(pb) + tag_size - 8;        if (next > end) // stop if tag_size is wrong            break;        switch (tag) {        case MKTAG(0xa9,'n','a','m'):            mov_parse_udta_string(pb, c->fc->title,     sizeof(c->fc->title));            break;        case MKTAG(0xa9,'w','r','t'):            mov_parse_udta_string(pb, c->fc->author,    sizeof(c->fc->author));            break;        case MKTAG(0xa9,'c','p','y'):            mov_parse_udta_string(pb, c->fc->copyright, sizeof(c->fc->copyright));            break;        case MKTAG(0xa9,'i','n','f'):            mov_parse_udta_string(pb, c->fc->comment,   sizeof(c->fc->comment));            break;        default:            break;        }        url_fseek(pb, next, SEEK_SET);    }    return 0;}static int mov_read_tkhd(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom){    AVStream *st = c->fc->streams[c->fc->nb_streams-1];    int version = get_byte(pb);    get_be24(pb); /* flags */    /*    MOV_TRACK_ENABLED 0x0001    MOV_TRACK_IN_MOVIE 0x0002    MOV_TRACK_IN_PREVIEW 0x0004    MOV_TRACK_IN_POSTER 0x0008    */    if (version == 1) {        get_be64(pb);        get_be64(pb);    } else {        get_be32(pb); /* creation time */        get_be32(pb); /* modification time */    }    st->id = (int)get_be32(pb); /* track id (NOT 0 !)*/    get_be32(pb); /* reserved */    st->start_time = 0; /* check */    /* highlevel (considering edits) duration in movie timebase */    (version == 1) ? get_be64(pb) : get_be32(pb);    get_be32(pb); /* reserved */    get_be32(pb); /* reserved */    get_be16(pb); /* layer */    get_be16(pb); /* alternate group */    get_be16(pb); /* volume */    get_be16(pb); /* reserved */    url_fskip(pb, 36); /* display matrix */    /* those are fixed-point */    get_be32(pb); /* track width */    get_be32(pb); /* track height */    return 0;}static int mov_read_tfhd(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom){    MOVFragment *frag = &c->fragment;    MOVTrackExt *trex = NULL;    int flags, track_id, i;    get_byte(pb); /* version */    flags = get_be24(pb);    track_id = get_be32(pb);    if (!track_id || track_id > c->fc->nb_streams)        return -1;    frag->track_id = track_id;    for (i = 0; i < c->trex_count; i++)        if (c->trex_data[i].track_id == frag->track_id) {            trex = &c->trex_data[i];            break;        }    if (!trex) {        av_log(c->fc, AV_LOG_ERROR, "could not find corresponding trex\n");        return -1;    }    if (flags & 0x01) frag->base_data_offset = get_be64(pb);    else              frag->base_data_offset = frag->moof_offset;    if (flags & 0x02) frag->stsd_id          = get_be32(pb);    else              frag->stsd_id          = trex->stsd_id;    frag->duration = flags & 0x08 ? get_be32(pb) : trex->duration;    frag->size     = flags & 0x10 ? get_be32(pb) : trex->size;    frag->flags    = flags & 0x20 ? get_be32(pb) : trex->flags;    dprintf(c->fc, "frag flags 0x%x\n", frag->flags);    return 0;}static int mov_read_trex(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom){    MOVTrackExt *trex;    if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))        return -1;    c->trex_data = av_realloc(c->trex_data, (c->trex_count+1)*sizeof(*c->trex_data));    if (!c->trex_data)        return AVERROR(ENOMEM);    trex = &c->trex_data[c->trex_count++];    get_byte(pb); /* version */    get_be24(pb); /* flags */    trex->track_id = get_be32(pb);    trex->stsd_id  = get_be32(pb);    trex->duration = get_be32(pb);    trex->size     = get_be32(pb);    trex->flags    = get_be32(pb);    return 0;}static int mov_read_trun(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom){    MOVFragment *frag = &c->fragment;    AVStream *st;    MOVStreamContext *sc;    uint64_t offset;    int64_t dts;    int data_offset = 0;    unsigned entries, first_sample_flags = frag->flags;    int flags, distance, i;    if (!frag->track_id || frag->track_id > c->fc->nb_streams)        return -1;    st = c->fc->streams[frag->track_id-1];    sc = st->priv_data;    if (sc->pseudo_stream_id+1 != frag->stsd_id)        return 0;    get_byte(pb); /* version */    flags = get_be24(pb);    entries = get_be32(pb);    dprintf(c->fc, "flags 0x%x entries %d\n", flags, entries);    if (flags & 0x001) data_offset        = get_be32(pb);    if (flags & 0x004) first_sample_flags = get_be32(pb);    if (flags & 0x800) {

⌨️ 快捷键说明

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