📄 mov.c
字号:
get_be16(pb); /* compression id = 0*/ get_be16(pb); /* packet size = 0 */ st->codec->sample_rate = ((get_be32(pb) >> 16)); //av_log(NULL, AV_LOG_DEBUG, "CODECID %d %d %.4s\n", st->codec->codec_id, CODEC_ID_PCM_S16BE, (char*)&format); switch (st->codec->codec_id) { case CODEC_ID_PCM_S16BE: if (st->codec->bits_per_sample == 8) st->codec->codec_id = CODEC_ID_PCM_S8; /* fall */ case CODEC_ID_PCM_U8: st->codec->bit_rate = st->codec->sample_rate * 8; break; default: ; } //Read QT version 1 fields. In version 0 theese dont exist#ifdef DEBUG av_log(NULL, AV_LOG_DEBUG, "version =%d mp4=%d\n",version,c->mp4); av_log(NULL, AV_LOG_DEBUG, "size-(16+20+16)=%d\n",size-(16+20+16));#endif if((version==1) && size>=(16+20+16)) { get_be32(pb); /* samples per packet */ get_be32(pb); /* bytes per packet */ get_be32(pb); /* bytes per frame */ get_be32(pb); /* bytes per sample */ if(size>(16+20+16)) { //Optional, additional atom-based fields MOV_atom_t a = { format, url_ftell(pb), size - (16 + 20 + 16 + 8) };#ifdef DEBUG av_log(NULL, AV_LOG_DEBUG, "offest=0x%X, sizeleft=%d=0x%x,format=%c%c%c%c\n",(int)url_ftell(pb),size - (16 + 20 + 16 ),size - (16 + 20 + 16 ), (format >> 0) & 0xff, (format >> 8) & 0xff, (format >> 16) & 0xff, (format >> 24) & 0xff);#endif mov_read_default(c, pb, a); } } else { //We should be down to 0 bytes here, but lets make sure. size-=(16+20);#ifdef DEBUG if(size>0) av_log(NULL, AV_LOG_DEBUG, "skipping 0x%X bytes\n",size-(16+20));#endif url_fskip(pb, size); } } else { size-=16; //Unknown size, but lets do our best and skip the rest.#ifdef DEBUG av_log(NULL, AV_LOG_DEBUG, "Strange size, skipping 0x%X bytes\n",size);#endif url_fskip(pb, size); } } } if(st->codec->codec_type==CODEC_TYPE_AUDIO && st->codec->sample_rate==0 && sc->time_scale>1) { st->codec->sample_rate= sc->time_scale; } return 0;}static int mov_read_stsc(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom){ AVStream *st = c->fc->streams[c->fc->nb_streams-1]; MOVStreamContext *sc = (MOVStreamContext *)st->priv_data; unsigned int i, entries; print_atom("stsc", atom); get_byte(pb); /* version */ get_byte(pb); get_byte(pb); get_byte(pb); /* flags */ entries = get_be32(pb); if(entries >= UINT_MAX / sizeof(MOV_sample_to_chunk_tbl)) return -1; #ifdef DEBUGav_log(NULL, AV_LOG_DEBUG, "track[%i].stsc.entries = %i\n", c->fc->nb_streams-1, entries);#endif sc->sample_to_chunk_sz = entries; sc->sample_to_chunk = (MOV_sample_to_chunk_tbl*) av_malloc(entries * sizeof(MOV_sample_to_chunk_tbl)); if (!sc->sample_to_chunk) return -1; for(i=0; i<entries; i++) { sc->sample_to_chunk[i].first = get_be32(pb); sc->sample_to_chunk[i].count = get_be32(pb); sc->sample_to_chunk[i].id = get_be32(pb);#ifdef DEBUG/* av_log(NULL, AV_LOG_DEBUG, "sample_to_chunk first=%ld count=%ld, id=%ld\n", sc->sample_to_chunk[i].first, sc->sample_to_chunk[i].count, sc->sample_to_chunk[i].id); */#endif } return 0;}static int mov_read_stss(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom){ AVStream *st = c->fc->streams[c->fc->nb_streams-1]; MOVStreamContext *sc = (MOVStreamContext *)st->priv_data; unsigned int i, entries; print_atom("stss", atom); get_byte(pb); /* version */ get_byte(pb); get_byte(pb); get_byte(pb); /* flags */ entries = get_be32(pb); if(entries >= UINT_MAX / sizeof(long)) return -1; sc->keyframe_count = entries;#ifdef DEBUG av_log(NULL, AV_LOG_DEBUG, "keyframe_count = %ld\n", sc->keyframe_count);#endif sc->keyframes = (long*) av_malloc(entries * sizeof(long)); if (!sc->keyframes) return -1; for(i=0; i<entries; i++) { sc->keyframes[i] = get_be32(pb);#ifdef DEBUG/* av_log(NULL, AV_LOG_DEBUG, "keyframes[]=%ld\n", sc->keyframes[i]); */#endif } return 0;}static int mov_read_stsz(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom){ AVStream *st = c->fc->streams[c->fc->nb_streams-1]; MOVStreamContext *sc = (MOVStreamContext *)st->priv_data; unsigned int i, entries; print_atom("stsz", atom); get_byte(pb); /* version */ get_byte(pb); get_byte(pb); get_byte(pb); /* flags */ sc->sample_size = get_be32(pb); entries = get_be32(pb); if(entries >= UINT_MAX / sizeof(long)) return -1; sc->sample_count = entries;#ifdef DEBUG av_log(NULL, AV_LOG_DEBUG, "sample_size = %ld sample_count = %ld\n", sc->sample_size, sc->sample_count);#endif if(sc->sample_size) return 0; /* there isn't any table following */ sc->sample_sizes = (long*) av_malloc(entries * sizeof(long)); if (!sc->sample_sizes) return -1; for(i=0; i<entries; i++) { sc->sample_sizes[i] = get_be32(pb);#ifdef DEBUG av_log(NULL, AV_LOG_DEBUG, "sample_sizes[]=%ld\n", sc->sample_sizes[i]);#endif } return 0;}static int mov_read_stts(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom){ AVStream *st = c->fc->streams[c->fc->nb_streams-1]; //MOVStreamContext *sc = (MOVStreamContext *)st->priv_data; unsigned int i, entries; int64_t duration=0; int64_t total_sample_count=0; print_atom("stts", atom); get_byte(pb); /* version */ get_byte(pb); get_byte(pb); get_byte(pb); /* flags */ entries = get_be32(pb); if(entries >= UINT_MAX / sizeof(Time2Sample)) return -1; c->streams[c->fc->nb_streams-1]->stts_count = entries; c->streams[c->fc->nb_streams-1]->stts_data = av_malloc(entries * sizeof(Time2Sample));#ifdef DEBUGav_log(NULL, AV_LOG_DEBUG, "track[%i].stts.entries = %i\n", c->fc->nb_streams-1, entries);#endif for(i=0; i<entries; i++) { int sample_duration; int sample_count; sample_count=get_be32(pb); sample_duration = get_be32(pb); c->streams[c->fc->nb_streams - 1]->stts_data[i].count= sample_count; c->streams[c->fc->nb_streams - 1]->stts_data[i].duration= sample_duration;#ifdef DEBUG av_log(NULL, AV_LOG_DEBUG, "sample_count=%d, sample_duration=%d\n",sample_count,sample_duration);#endif duration+=sample_duration*sample_count; total_sample_count+=sample_count; } st->nb_frames= total_sample_count; if(duration) st->duration= duration; return 0;}static int mov_read_ctts(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom){// AVStream *st = c->fc->streams[c->fc->nb_streams-1]; //MOVStreamContext *sc = (MOVStreamContext *)st->priv_data; unsigned int i, entries; print_atom("ctts", atom); get_byte(pb); /* version */ get_byte(pb); get_byte(pb); get_byte(pb); /* flags */ entries = get_be32(pb); if(entries >= UINT_MAX / sizeof(Time2Sample)) return -1; c->streams[c->fc->nb_streams-1]->ctts_count = entries; c->streams[c->fc->nb_streams-1]->ctts_data = av_malloc(entries * sizeof(Time2Sample));// #ifdef DEBUGav_log(NULL, AV_LOG_DEBUG, "track[%i].ctts.entries = %i\n", c->fc->nb_streams-1, entries);// #endif for(i=0; i<entries; i++) { c->streams[c->fc->nb_streams - 1]->ctts_data[i].count= get_be32(pb); c->streams[c->fc->nb_streams - 1]->ctts_data[i].duration= get_be32(pb); } return 0;}static int mov_read_trak(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom){ AVStream *st; MOVStreamContext *sc; print_atom("trak", atom); st = av_new_stream(c->fc, c->fc->nb_streams); if (!st) return -2; sc = (MOVStreamContext*) av_mallocz(sizeof(MOVStreamContext)); if (!sc) { av_free(st); return -1; } sc->sample_to_chunk_index = -1; st->priv_data = sc; st->codec->codec_type = CODEC_TYPE_MOV_OTHER; st->start_time = 0; /* XXX: check */ c->streams[c->fc->nb_streams-1] = sc; return mov_read_default(c, pb, atom);}static int mov_read_tkhd(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom){ AVStream *st; print_atom("tkhd", atom); st = c->fc->streams[c->fc->nb_streams-1]; get_byte(pb); /* version */ get_byte(pb); get_byte(pb); get_byte(pb); /* flags */ /* MOV_TRACK_ENABLED 0x0001 MOV_TRACK_IN_MOVIE 0x0002 MOV_TRACK_IN_PREVIEW 0x0004 MOV_TRACK_IN_POSTER 0x0008 */ 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 */ get_be32(pb); /* highlevel (considering edits) duration in movie timebase */ 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 */ /*st->codec->width =*/ get_be32(pb) >> 16; /* track width */ /*st->codec->height =*/ get_be32(pb) >> 16; /* track height */ return 0;}/* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... *//* like the files created with Adobe Premiere 5.0, for samples see *//* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */static int mov_read_wide(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom){ int err;#ifdef DEBUG print_atom("wide", atom); debug_indent++;#endif if (atom.size < 8) return 0; /* continue */ if (get_be32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */ url_fskip(pb, atom.size - 4); return 0; } atom.type = get_le32(pb); atom.offset += 8; atom.size -= 8; if (atom.type != MKTAG('m', 'd', 'a', 't')) { url_fskip(pb, atom.size); return 0; } err = mov_read_mdat(c, pb, atom);#ifdef DEBUG debug_indent--;#endif return err;}#ifdef CONFIG_ZLIBstatic int null_read_packet(void *opaque, uint8_t *buf, int buf_size){ return -1;}static int mov_read_cmov(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom){ ByteIOContext ctx; uint8_t *cmov_data; uint8_t *moov_data; /* uncompressed data */ long cmov_len, moov_len; int ret; print_atom("cmov", atom); 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' )) { av_log(NULL, AV_LOG_DEBUG, "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 = (uint8_t *) av_malloc(cmov_len); if (!cmov_data) return -1; moov_data = (uint8_t *) av_malloc(moov_len); if (!moov_data) { av_free(cmov_data); return -1; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -