📄 mov.c
字号:
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 + -