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

📄 mov.c

📁 Trolltech公司发布的图形界面操作系统。可在qt-embedded-2.3.7平台上编译为嵌入式图形界面操作系统。
💻 C
📖 第 1 页 / 共 3 页
字号:
    for(i=0; i<entries; i++) {        sc->sample_sizes[i] = get_be32(pb);#ifdef DEBUG/*        printf("sample_sizes[]=%ld\n", sc->sample_sizes[i]); */#endif    }    return 0;}static int parse_stts(const MOVParseTableEntry *parse_table, ByteIOContext *pb, UINT32 atom_type, INT64 atom_offset, INT64 atom_size, void *param){    MOVContext *c;    int entries, i;    AVStream *st;    MOVStreamContext *sc;#ifdef DEBUG    print_atom("stts", atom_type, atom_offset, atom_size);#endif    c = (MOVContext *)param;    st = c->fc->streams[c->fc->nb_streams-1];    sc = (MOVStreamContext *)st->priv_data;    get_byte(pb); /* version */    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */    entries = get_be32(pb);#ifdef DEBUGprintf("track[%i].stts.entries = %i\n", c->fc->nb_streams-1, entries);#endif    for(i=0; i<entries; i++) {        int sample_duration;        get_be32(pb);        sample_duration = get_be32(pb);        if (!i && st->codec.codec_type==CODEC_TYPE_VIDEO) {            st->codec.frame_rate = FRAME_RATE_BASE * c->streams[c->total_streams]->time_scale;            if (sample_duration)                st->codec.frame_rate /= sample_duration;#ifdef DEBUG            printf("VIDEO FRAME RATE= %i (sd= %i)\n", st->codec.frame_rate, sample_duration);#endif        }    }    return 0;}#ifdef CONFIG_ZLIBstatic int null_read_packet(void *opaque, UINT8 *buf, int buf_size){    return -1;}static int parse_cmov(const MOVParseTableEntry *parse_table, ByteIOContext *pb, UINT32 atom_type, INT64 atom_offset, INT64 atom_size, void *param){    MOVContext *c;    ByteIOContext ctx;    char *cmov_data;    unsigned char *moov_data; /* uncompressed data */    long cmov_len, moov_len;    int ret;#ifdef DEBUG    print_atom("cmov", atom_type, atom_offset, atom_size);#endif    c = (MOVContext *)param;    get_be32(pb); /* dcom atom */    if (get_le32(pb) != MKTAG( 'd', 'c', 'o', 'm' ))        return -1;    if (get_le32(pb) != MKTAG( 'z', 'l', 'i', 'b' )) {        puts("unknown compression for cmov atom !");        return -1;    }    get_be32(pb); /* cmvd atom */    if (get_le32(pb) != MKTAG( 'c', 'm', 'v', 'd' ))        return -1;    moov_len = get_be32(pb); /* uncompressed size */    cmov_len = atom_size - 6 * 4;        cmov_data = av_malloc(cmov_len);    if (!cmov_data)        return -1;    moov_data = av_malloc(moov_len);    if (!moov_data) {        av_free(cmov_data);        return -1;    }    get_buffer(pb, cmov_data, cmov_len);    if(uncompress (moov_data, &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)        return -1;    if(init_put_byte(&ctx, moov_data, moov_len, 0, NULL, null_read_packet, NULL, NULL) != 0)        return -1;    ctx.buf_end = ctx.buffer + moov_len;    ret = parse_default(parse_table, &ctx, MKTAG( 'm', 'o', 'o', 'v' ), 0, moov_len, param);    av_free(moov_data);    av_free(cmov_data);    return ret;}#endifstatic const MOVParseTableEntry mov_default_parse_table[] = {/* mp4 atoms */{ MKTAG( 'm', 'p', '4', 'a' ), parse_default },{ MKTAG( 'c', 'o', '6', '4' ), parse_stco },{ MKTAG( 's', 't', 'c', 'o' ), parse_stco },{ MKTAG( 'c', 'r', 'h', 'd' ), parse_default },{ MKTAG( 'c', 't', 't', 's' ), parse_leaf },{ MKTAG( 'c', 'p', 'r', 't' ), parse_default },{ MKTAG( 'u', 'r', 'l', ' ' ), parse_leaf },{ MKTAG( 'u', 'r', 'n', ' ' ), parse_leaf },{ MKTAG( 'd', 'i', 'n', 'f' ), parse_default },{ MKTAG( 'd', 'r', 'e', 'f' ), parse_leaf },{ MKTAG( 's', 't', 'd', 'p' ), parse_default },{ MKTAG( 'e', 's', 'd', 's' ), parse_default },{ MKTAG( 'e', 'd', 't', 's' ), parse_default },{ MKTAG( 'e', 'l', 's', 't' ), parse_leaf },{ MKTAG( 'u', 'u', 'i', 'd' ), parse_default },{ MKTAG( 'f', 'r', 'e', 'e' ), parse_leaf },{ MKTAG( 'h', 'd', 'l', 'r' ), parse_hdlr },{ MKTAG( 'h', 'm', 'h', 'd' ), parse_leaf },{ MKTAG( 'h', 'i', 'n', 't' ), parse_leaf },{ MKTAG( 'n', 'm', 'h', 'd' ), parse_leaf },{ MKTAG( 'm', 'p', '4', 's' ), parse_default },{ MKTAG( 'm', 'd', 'i', 'a' ), parse_default },{ MKTAG( 'm', 'd', 'a', 't' ), parse_mdat },{ MKTAG( 'm', 'd', 'h', 'd' ), parse_mdhd },{ MKTAG( 'm', 'i', 'n', 'f' ), parse_default },{ MKTAG( 'm', 'o', 'o', 'v' ), parse_moov },{ MKTAG( 'm', 'v', 'h', 'd' ), parse_mvhd },{ MKTAG( 'i', 'o', 'd', 's' ), parse_leaf },{ MKTAG( 'o', 'd', 'h', 'd' ), parse_default },{ MKTAG( 'm', 'p', 'o', 'd' ), parse_leaf },{ MKTAG( 's', 't', 's', 'd' ), parse_stsd },{ MKTAG( 's', 't', 's', 'z' ), parse_stsz },{ MKTAG( 's', 't', 'b', 'l' ), parse_default },{ MKTAG( 's', 't', 's', 'c' ), parse_stsc },{ MKTAG( 's', 'd', 'h', 'd' ), parse_default },{ MKTAG( 's', 't', 's', 'h' ), parse_default },{ MKTAG( 's', 'k', 'i', 'p' ), parse_default },{ MKTAG( 's', 'm', 'h', 'd' ), parse_leaf },{ MKTAG( 'd', 'p', 'n', 'd' ), parse_leaf },{ MKTAG( 's', 't', 's', 's' ), parse_leaf },{ MKTAG( 's', 't', 't', 's' ), parse_stts },{ MKTAG( 't', 'r', 'a', 'k' ), parse_trak },{ MKTAG( 't', 'k', 'h', 'd' ), parse_tkhd },{ MKTAG( 't', 'r', 'e', 'f' ), parse_default }, /* not really */{ MKTAG( 'u', 'd', 't', 'a' ), parse_leaf },{ MKTAG( 'v', 'm', 'h', 'd' ), parse_leaf },{ MKTAG( 'm', 'p', '4', 'v' ), parse_default },/* extra mp4 */{ MKTAG( 'M', 'D', 'E', 'S' ), parse_leaf },/* QT atoms */{ MKTAG( 'c', 'h', 'a', 'p' ), parse_leaf },{ MKTAG( 'c', 'l', 'i', 'p' ), parse_default },{ MKTAG( 'c', 'r', 'g', 'n' ), parse_leaf },{ MKTAG( 'k', 'm', 'a', 't' ), parse_leaf },{ MKTAG( 'm', 'a', 't', 't' ), parse_default },{ MKTAG( 'r', 'd', 'r', 'f' ), parse_leaf },{ MKTAG( 'r', 'm', 'd', 'a' ), parse_default },{ MKTAG( 'r', 'm', 'd', 'r' ), parse_leaf },//{ MKTAG( 'r', 'm', 'q', 'u' ), parse_leaf },{ MKTAG( 'r', 'm', 'r', 'a' ), parse_default },{ MKTAG( 's', 'c', 'p', 't' ), parse_leaf },{ MKTAG( 's', 'y', 'n', 'c' ), parse_leaf },{ MKTAG( 's', 's', 'r', 'c' ), parse_leaf },{ MKTAG( 't', 'c', 'm', 'd' ), parse_leaf },{ MKTAG( 'w', 'i', 'd', 'e' ), parse_wide }, /* place holder */#ifdef CONFIG_ZLIB{ MKTAG( 'c', 'm', 'o', 'v' ), parse_cmov },#else{ MKTAG( 'c', 'm', 'o', 'v' ), parse_leaf },#endif{ 0L, parse_leaf }};static void mov_free_stream_context(MOVStreamContext *sc){    if(sc) {        av_free(sc->chunk_offsets);        av_free(sc->sample_to_chunk);        av_free(sc->header_data);        av_free(sc);    }}static uint32_t to_tag(uint8_t *buf){    return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);}static uint32_t to_be32(uint8_t *buf){    return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];}/* XXX: is it suffisant ? */static int mov_probe(AVProbeData *p){    unsigned int offset;    uint32_t tag;    /* check file header */    if (p->buf_size <= 12)        return 0;    offset = 0;    for(;;) {        /* ignore invalid offset */        if ((offset + 8) > (unsigned int)p->buf_size)            return 0;        tag = to_tag(p->buf + offset + 4);        switch(tag) {        case MKTAG( 'm', 'o', 'o', 'v' ):        case MKTAG( 'w', 'i', 'd', 'e' ):        case MKTAG( 'f', 'r', 'e', 'e' ):        case MKTAG( 'm', 'd', 'a', 't'):            return AVPROBE_SCORE_MAX;        case MKTAG( 'f', 't', 'y', 'p' ):        case MKTAG( 's', 'k', 'i', 'p' ):                        offset = to_be32(p->buf) + offset;            break;        default:            /* unrecognized tag */            return 0;        }    }    return 0;}static int mov_read_header(AVFormatContext *s, AVFormatParameters *ap){    MOVContext *mov = s->priv_data;    ByteIOContext *pb = &s->pb;    int i, j, nb, err;    INT64 size;    mov->fc = s;#if 0    /* XXX: I think we should auto detect */    if(s->iformat->name[1] == 'p')        mov->mp4 = 1;#endif    if(!url_is_streamed(pb)) /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */        size = url_filesize(url_fileno(pb));    else        size = 0x7FFFFFFFFFFFFFFF;#ifdef DEBUG    printf("filesz=%Ld\n", size);#endif    /* check MOV header */    err = parse_default(mov_default_parse_table, pb, 0L, 0LL, size, mov);    if(err<0 || (!mov->found_moov || !mov->found_mdat)) {        puts("header not found !!!");        exit(1);    }#ifdef DEBUG    printf("on_parse_exit_offset=%d\n", (int) url_ftell(pb));#endif    /* some cleanup : make sure we are on the mdat atom */    if(!url_is_streamed(pb) && (url_ftell(pb) != mov->mdat_offset))        url_fseek(pb, mov->mdat_offset, SEEK_SET);    mov->next_chunk_offset = mov->mdat_offset; /* initialise reading */#ifdef DEBUG    printf("mdat_reset_offset=%d\n", (int) url_ftell(pb));#endif#ifdef DEBUG    printf("streams= %d\n", s->nb_streams);#endif    mov->total_streams = nb = s->nb_streams;    #if 1    for(i=0; i<s->nb_streams;) {        if(s->streams[i]->codec.codec_type == CODEC_TYPE_MOV_OTHER) {/* not audio, not video, delete */            av_free(s->streams[i]);            for(j=i+1; j<s->nb_streams; j++)                s->streams[j-1] = s->streams[j];            s->nb_streams--;        } else            i++;    }    for(i=0; i<s->nb_streams;i++) {        MOVStreamContext *sc;        sc = (MOVStreamContext *)s->streams[i]->priv_data;        sc->ffindex = i;        sc->is_ff_stream = 1;    }#endif#ifdef DEBUG    printf("real streams= %d\n", s->nb_streams);#endif    return 0;}/* Yes, this is ugly... I didn't write the specs of QT :p *//* XXX:remove useless commented code sometime */static int mov_read_packet(AVFormatContext *s, AVPacket *pkt){    MOVContext *mov = s->priv_data;    MOVStreamContext *sc;    INT64 offset = 0x0FFFFFFFFFFFFFFF;    int i;    int st_id = 0, size;    size = 0x0FFFFFFF;    #ifdef MOV_SPLIT_CHUNKS    if (mov->partial) {                int idx;        st_id = mov->partial - 1;        idx = mov->streams[st_id]->sample_to_chunk_index;        if (idx < 0) return 0;        size = mov->streams[st_id]->sample_sizes[mov->streams[st_id]->current_sample];        mov->streams[st_id]->current_sample++;        mov->streams[st_id]->left_in_chunk--;        if(mov->streams[st_id]->left_in_chunk <= 0)            mov->partial = 0;        offset = mov->next_chunk_offset;        /* extract the sample */        goto readchunk;    }#endifagain:    for(i=0; i<mov->total_streams; i++) {        if((mov->streams[i]->next_chunk < mov->streams[i]->chunk_count)        && (mov->streams[i]->chunk_offsets[mov->streams[i]->next_chunk] < offset)) {            st_id = i;            offset = mov->streams[i]->chunk_offsets[mov->streams[i]->next_chunk];        }    }    mov->streams[st_id]->next_chunk++;    if(offset==0x0FFFFFFFFFFFFFFF)        return -1;        if(mov->next_chunk_offset < offset) { /* some meta data */        url_fskip(&s->pb, (offset - mov->next_chunk_offset));        mov->next_chunk_offset = offset;    }//printf("chunk: [%i] %lli -> %lli\n", st_id, mov->next_chunk_offset, offset);    if(!mov->streams[st_id]->is_ff_stream) {        url_fskip(&s->pb, (offset - mov->next_chunk_offset));        mov->next_chunk_offset = offset;        offset = 0x0FFFFFFFFFFFFFFF;        goto again;    }    /* now get the chunk size... */    for(i=0; i<mov->total_streams; i++) {        if((mov->streams[i]->next_chunk < mov->streams[i]->chunk_count)        && ((mov->streams[i]->chunk_offsets[mov->streams[i]->next_chunk] - offset) < size)) {            size = mov->streams[i]->chunk_offsets[mov->streams[i]->next_chunk] - offset;        }    }#ifdef MOV_SPLIT_CHUNKS    /* split chunks into samples */    if(mov->streams[st_id]->sample_size == 0) {        int idx;        idx = mov->streams[st_id]->sample_to_chunk_index;        if ((idx + 1 < mov->streams[st_id]->sample_to_chunk_sz)               && (mov->streams[st_id]->next_chunk >= mov->streams[st_id]->sample_to_chunk[idx + 1].first))           idx++;         mov->streams[st_id]->sample_to_chunk_index = idx;        if(idx >= 0 && mov->streams[st_id]->sample_to_chunk[idx].count != 1) {            mov->partial = st_id+1;            /* we'll have to get those samples before next chunk */            mov->streams[st_id]->left_in_chunk = (mov->streams[st_id]->sample_to_chunk[idx].count) - 1;            size = mov->streams[st_id]->sample_sizes[mov->streams[st_id]->current_sample];        }        mov->streams[st_id]->current_sample++;    }#endifreadchunk://printf("chunk: [%i] %lli -> %lli (%i)\n", st_id, offset, offset + size, size);    if(size == 0x0FFFFFFF)        size = mov->mdat_size + mov->mdat_offset - offset;    if(size < 0)        return -1;    if(size == 0)        return -1;    url_fseek(&s->pb, offset, SEEK_SET);    sc = mov->streams[st_id];    if (sc->header_len > 0) {        av_new_packet(pkt, size + sc->header_len);        memcpy(pkt->data, sc->header_data, sc->header_len);        get_buffer(&s->pb, pkt->data + sc->header_len, size);        /* free header */        av_freep(&sc->header_data);        sc->header_len = 0;    } else {        av_new_packet(pkt, size);        get_buffer(&s->pb, pkt->data, pkt->size);    }    pkt->stream_index = sc->ffindex;#ifdef DEBUG/*    printf("Packet (%d, %d, %ld) ", pkt->stream_index, st_id, pkt->size);    for(i=0; i<8; i++)        printf("%02x ", pkt->data[i]);    for(i=0; i<8; i++)        printf("%c ", (pkt->data[i]) & 0x7F);    puts("");*/#endif    mov->next_chunk_offset = offset + size;    return 0;}static int mov_read_close(AVFormatContext *s){    int i;    MOVContext *mov = s->priv_data;    for(i=0; i<mov->total_streams; i++)        mov_free_stream_context(mov->streams[i]);    for(i=0; i<s->nb_streams; i++)	av_freep(&s->streams[i]);    return 0;}static AVInputFormat mov_iformat = {    "mov",    "QuickTime/MPEG4 format",    sizeof(MOVContext),    mov_probe,    mov_read_header,    mov_read_packet,    mov_read_close,};int mov_init(void){    av_register_input_format(&mov_iformat);    return 0;}

⌨️ 快捷键说明

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