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

📄 mov.c

📁 ffmpeg源码分析
💻 C
📖 第 1 页 / 共 5 页
字号:
            code >>= 5;        }        return 1;    }    /* old fashion apple lang code */    if (code >= (sizeof(mov_mdhd_language_map)/sizeof(char *)))        return 0;    if (!mov_mdhd_language_map[code])        return 0;    strncpy(to, mov_mdhd_language_map[code], 4);    return 1;}extern int ff_mov_iso639_to_lang(const char *lang, int mp4); /* for movenc.c */int ff_mov_iso639_to_lang(const char *lang, int mp4){    int i, code = 0;    /* old way, only for QT? */    for (i = 0; !mp4 && (i < (sizeof(mov_mdhd_language_map)/sizeof(char *))); i++) {        if (mov_mdhd_language_map[i] && !strcmp(lang, mov_mdhd_language_map[i]))            return i;    }    /* XXX:can we do that in mov too? */    if (!mp4)        return 0;    /* handle undefined as such */    if (lang[0] == '\0')        lang = "und";    /* 5bit ascii */    for (i = 0; i < 3; i++) {        unsigned char c = (unsigned char)lang[i];        if (c < 0x60)            return 0;        if (c > 0x60 + 0x1f)            return 0;        code <<= 5;        code |= (c - 0x60);    }    return code;}static int mov_read_leaf(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom){    if (atom.size>1)        url_fskip(pb, atom.size);/*        url_seek(pb, atom_offset+atom.size, SEEK_SET); */    return 0;}static int mov_read_default(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom){    int64_t total_size = 0;    MOV_atom_t a;    int i;    int err = 0;    a.offset = atom.offset;    if (atom.size < 0)        atom.size = 0x7fffffffffffffffLL;    while(((total_size + 8) < atom.size) && !url_feof(pb) && !err) {        a.size = atom.size;        a.type=0L;        if(atom.size >= 8) {            a.size = get_be32(pb);            a.type = get_le32(pb);        }        total_size += 8;        a.offset += 8;        dprintf("type: %08x  %.4s  sz: %"PRIx64"  %"PRIx64"   %"PRIx64"\n", a.type, (char*)&a.type, a.size, atom.size, total_size);        if (a.size == 1) { /* 64 bit extended size */            a.size = get_be64(pb) - 8;            a.offset += 8;            total_size += 8;        }        if (a.size == 0) {            a.size = atom.size - total_size;            if (a.size <= 8)                break;        }        for (i = 0; c->parse_table[i].type != 0L             && c->parse_table[i].type != a.type; i++)            /* empty */;        a.size -= 8;        if(a.size < 0)            break;        if (c->parse_table[i].type == 0) { /* skip leaf atoms data */            url_fskip(pb, a.size);        } else {            err = (c->parse_table[i].func)(c, pb, a);        }        a.offset += a.size;        total_size += a.size;    }    if (!err && total_size < atom.size && atom.size < 0x7ffff) {        url_fskip(pb, atom.size - total_size);    }    return err;}static int mov_read_ctab(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom){#if 1    url_fskip(pb, atom.size); // for now#else    VERY VERY BROKEN, NEVER execute this, needs rewrite    unsigned int len;    MOV_ctab_t *t;    c->ctab = av_realloc(c->ctab, ++c->ctab_size);    t = c->ctab[c->ctab_size];    t->seed = get_be32(pb);    t->flags = get_be16(pb);    t->size = get_be16(pb) + 1;    len = 2 * t->size * 4;    if (len > 0) {        t->clrs = av_malloc(len); // 16bit A R G B        if (t->clrs)            get_buffer(pb, t->clrs, len);    }#endif    return 0;}static int mov_read_hdlr(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom){    AVStream *st = c->fc->streams[c->fc->nb_streams-1];    int len = 0;    uint32_t type;    uint32_t ctype;    get_byte(pb); /* version */    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */    /* component type */    ctype = get_le32(pb);    type = get_le32(pb); /* component subtype */    dprintf("ctype= %c%c%c%c (0x%08lx)\n", *((char *)&ctype), ((char *)&ctype)[1], ((char *)&ctype)[2], ((char *)&ctype)[3], (long) ctype);    dprintf("stype= %c%c%c%c\n", *((char *)&type), ((char *)&type)[1], ((char *)&type)[2], ((char *)&type)[3]);    if(ctype == MKTAG('m', 'h', 'l', 'r')) /* MOV */        c->mp4 = 0;    else if(ctype == 0)        c->mp4 = 1;    if(type == MKTAG('v', 'i', 'd', 'e'))        st->codec->codec_type = CODEC_TYPE_VIDEO;    else if(type == MKTAG('s', 'o', 'u', 'n'))        st->codec->codec_type = CODEC_TYPE_AUDIO;    get_be32(pb); /* component  manufacture */    get_be32(pb); /* component flags */    get_be32(pb); /* component flags mask */    if(atom.size <= 24)        return 0; /* nothing left to read */    /* XXX: MP4 uses a C string, not a pascal one */    /* component name */    if(c->mp4) {        /* .mp4: C string */        while(get_byte(pb) && (++len < (atom.size - 24)));    } else {        /* .mov: PASCAL string */        len = get_byte(pb);        url_fskip(pb, len);    }    url_fskip(pb, atom.size - (url_ftell(pb) - atom.offset));    return 0;}static int mov_mp4_read_descr_len(ByteIOContext *pb){    int len = 0;    int count = 4;    while (count--) {        int c = get_byte(pb);        len = (len << 7) | (c & 0x7f);        if (!(c & 0x80))            break;    }    return len;}static int mov_mp4_read_descr(ByteIOContext *pb, int *tag){    int len;    *tag = get_byte(pb);    len = mov_mp4_read_descr_len(pb);    dprintf("MPEG4 description: tag=0x%02x len=%d\n", *tag, len);    return len;}static int mov_read_esds(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom){    AVStream *st = c->fc->streams[c->fc->nb_streams-1];    MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;    int64_t start_pos = url_ftell(pb);    int tag, len;    /* Well, broken but suffisant for some MP4 streams */    get_be32(pb); /* version + flags */    len = mov_mp4_read_descr(pb, &tag);    if (tag == MP4ESDescrTag) {        get_be16(pb); /* ID */        get_byte(pb); /* priority */    } else        get_be16(pb); /* ID */    len = mov_mp4_read_descr(pb, &tag);    if (tag == MP4DecConfigDescrTag) {        sc->esds.object_type_id = get_byte(pb);        sc->esds.stream_type = get_byte(pb);        sc->esds.buffer_size_db = get_be24(pb);        sc->esds.max_bitrate = get_be32(pb);        sc->esds.avg_bitrate = get_be32(pb);        st->codec->codec_id= codec_get_id(ff_mov_obj_type, sc->esds.object_type_id);        len = mov_mp4_read_descr(pb, &tag);        if (tag == MP4DecSpecificDescrTag) {            dprintf("Specific MPEG4 header len=%d\n", len);            st->codec->extradata = (uint8_t*) av_mallocz(len + FF_INPUT_BUFFER_PADDING_SIZE);            if (st->codec->extradata) {                get_buffer(pb, st->codec->extradata, len);                st->codec->extradata_size = len;                /* from mplayer */                if ((*(uint8_t *)st->codec->extradata >> 3) == 29) {                    st->codec->codec_id = CODEC_ID_MP3ON4;                }            }        }    }    /* in any case, skip garbage */    url_fskip(pb, atom.size - ((url_ftell(pb) - start_pos)));    return 0;}/* this atom contains actual media data */static int mov_read_mdat(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom){    if(atom.size == 0) /* wrong one (MP4) */        return 0;    c->found_mdat=1;    c->mdat_offset = atom.offset;    c->mdat_size = atom.size;    if(c->found_moov)        return 1; /* found both, just go */    url_fskip(pb, atom.size);    return 0; /* now go for moov */}static int mov_read_ftyp(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom){    uint32_t type = get_le32(pb);    /* from mplayer */    switch (type) {    case MKTAG('i', 's', 'o', 'm'):    case MKTAG('m', 'p', '4', '1'):    case MKTAG('m', 'p', '4', '2'):    case MKTAG('3', 'g', 'p', '1'):    case MKTAG('3', 'g', 'p', '2'):    case MKTAG('3', 'g', '2', 'a'):    case MKTAG('3', 'g', 'p', '3'):    case MKTAG('3', 'g', 'p', '4'):    case MKTAG('3', 'g', 'p', '5'):    case MKTAG('m', 'm', 'p', '4'): /* Mobile MP4 */    case MKTAG('M', '4', 'A', ' '): /* Apple iTunes AAC-LC Audio */    case MKTAG('M', '4', 'P', ' '): /* Apple iTunes AAC-LC Protected Audio */    case MKTAG('m', 'j', 'p', '2'): /* Motion Jpeg 2000 */        c->mp4 = 1;    case MKTAG('q', 't', ' ', ' '):    default:        av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);    }    get_be32(pb); /* minor version */    url_fskip(pb, atom.size - 8);    return 0;}/* this atom should contain all header atoms */static int mov_read_moov(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom){    int err;    err = mov_read_default(c, pb, atom);    /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */    /* so we don't parse the whole file if over a network */    c->found_moov=1;    if(c->found_mdat)        return 1; /* found both, just go */    return 0; /* now go for mdat */}static int mov_read_mdhd(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom){    AVStream *st = c->fc->streams[c->fc->nb_streams-1];    MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;    int version = get_byte(pb);    int lang;    if (version > 1)        return 1; /* unsupported */    get_byte(pb); get_byte(pb);    get_byte(pb); /* flags */    if (version == 1) {        get_be64(pb);        get_be64(pb);    } else {        get_be32(pb); /* creation time */        get_be32(pb); /* modification time */    }    sc->time_scale = get_be32(pb);    st->duration = (version == 1) ? get_be64(pb) : get_be32(pb); /* duration */    lang = get_be16(pb); /* language */    ff_mov_lang_to_iso639(lang, st->language);    get_be16(pb); /* quality */    return 0;}static int mov_read_mvhd(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom){    int version = get_byte(pb); /* version */    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */    if (version == 1) {        get_be64(pb);        get_be64(pb);    } else {        get_be32(pb); /* creation time */        get_be32(pb); /* modification time */    }    c->time_scale = get_be32(pb); /* time scale */#ifdef DEBUG    av_log(NULL, AV_LOG_DEBUG, "time scale = %i\n", c->time_scale);#endif    c->duration = (version == 1) ? get_be64(pb) : get_be32(pb); /* duration */    get_be32(pb); /* preferred scale */    get_be16(pb); /* preferred volume */    url_fskip(pb, 10); /* reserved */    url_fskip(pb, 36); /* display matrix */    get_be32(pb); /* preview time */    get_be32(pb); /* preview duration */    get_be32(pb); /* poster time */    get_be32(pb); /* selection time */    get_be32(pb); /* selection duration */    get_be32(pb); /* current time */    get_be32(pb); /* next track ID */    return 0;}static int mov_read_smi(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom){    AVStream *st = c->fc->streams[c->fc->nb_streams-1];

⌨️ 快捷键说明

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