📄 mov.c
字号:
} 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; int entries, i; print_atom("stss", atom); get_byte(pb); /* version */ get_byte(pb); get_byte(pb); get_byte(pb); /* flags */ entries = get_be32(pb); 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; int entries, i; 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); 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; int entries, i; 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); c->streams[c->fc->nb_streams-1]->stts_count = entries; c->streams[c->fc->nb_streams-1]->stts_data = (uint64_t*) av_malloc(entries * sizeof(uint64_t));#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++) { int32_t sample_duration; int32_t sample_count; sample_count=get_be32(pb); sample_duration = get_be32(pb); c->streams[c->fc->nb_streams - 1]->stts_data[i] = (uint64_t)sample_count<<32 | (uint64_t)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;#if 0 //We calculate an average instead, needed by .mp4-files created with nec e606 3g phone if (!i && st->codec.codec_type==CODEC_TYPE_VIDEO) { st->codec.frame_rate_base = sample_duration ? sample_duration : 1; st->codec.frame_rate = c->streams[c->fc->nb_streams-1]->time_scale;#ifdef DEBUG av_log(NULL, AV_LOG_DEBUG, "VIDEO FRAME RATE= %i (sd= %i)\n", st->codec.frame_rate, sample_duration);#endif }#endif } /*The stsd atom which contain codec type sometimes comes after the stts so we cannot check for codec_type*/ if(duration>0) { av_reduce( &st->codec.frame_rate, &st->codec.frame_rate_base, c->streams[c->fc->nb_streams-1]->time_scale * total_sample_count, duration, INT_MAX );#ifdef DEBUG av_log(NULL, AV_LOG_DEBUG, "FRAME RATE average (video or audio)= %f (tot sample count= %i ,tot dur= %i timescale=%d)\n", (float)st->codec.frame_rate/st->codec.frame_rate_base,total_sample_count,duration,c->streams[c->fc->nb_streams-1]->time_scale);#endif } else { st->codec.frame_rate_base = 1; st->codec.frame_rate = c->streams[c->fc->nb_streams-1]->time_scale; } 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 */ st->duration = (c->duration * (int64_t)AV_TIME_BASE) / c->time_scale; 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 */ st->duration = (get_be32(pb) * (int64_t)AV_TIME_BASE) / c->time_scale; /* duration */ 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; } get_buffer(pb, cmov_data, cmov_len); if(uncompress (moov_data, (uLongf *) &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; atom.type = MKTAG( 'm', 'o', 'o', 'v' ); atom.offset = 0; atom.size = moov_len;#ifdef DEBUG { int fd = open("/tmp/uncompheader.mov", O_WRONLY | O_CREAT); write(fd, moov_data, moov_len); close(fd); }#endif ret = mov_read_default(c, &ctx, atom); av_free(moov_data); av_free(cmov_data); return ret;}#endif/* edit list atom */static int mov_read_elst(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom){ print_atom("elst", atom); get_byte(pb); /* version */ get_byte(pb); get_byte(pb); get_byte(pb); /* flags */ c->streams[c->fc->nb_streams-1]->edit_count = get_be32(pb); /* entries */#ifdef DEBUG av_log(NULL, AV_LOG_DEBUG, "track[%i].edit_count = %i\n", c->fc->nb_streams-1, c->streams[c->fc->nb_streams-1]->edit_count);#endif return 0;}static const MOVParseTableEntry mov_default_parse_table[] = {/* mp4 atoms */{ MKTAG( 'c', 'o', '6', '4' ), mov_read_stco },{ MKTAG( 'c', 'p', 'r', 't' ), mov_read_default },{ MKTAG( 'c', 'r', 'h', 'd' ), mov_read_default },{ MKTAG( 'c', 't', 't', 's' ), mov_read_leaf }, /* composition time to sample */{ MKTAG( 'd', 'i', 'n', 'f' ), mov_read_default }, /* data information */{ MKTAG( 'd', 'p', 'n', 'd' ), mov_read_leaf },{ MKTAG( 'd', 'r', 'e', 'f' ), mov_read_leaf },{ MKTAG( 'e', 'd', 't', 's' ), mov_read_default },{ MKTAG( 'e', 'l', 's', 't' ), mov_read_elst },{ MKTAG( 'f', 'r', 'e', 'e' ), mov_read_leaf },{ MKTAG( 'h', 'd', 'l', 'r' ), mov_read_hdlr },{ MKTAG( 'h', 'i', 'n', 't' ), mov_read_leaf },{ MKTAG( 'h', 'm', 'h', 'd' ), mov_read_leaf },{ MKTAG( 'i', 'o', 'd', 's' ), mov_read_leaf },{ MKTAG( 'm', 'd', 'a', 't' ), mov_read_mdat },{ MKTAG( 'm', 'd', 'h', 'd' ), mov_read_mdhd },{ MKTAG( 'm', 'd', 'i', 'a' ), mov_read_default },{ MKTAG( 'm', 'i', 'n', 'f' ), mov_read_default },{ MKTAG( 'm', 'o', 'o', 'v' ), mov_read_moov },{ MKTAG( 'm', 'p', '4', 'a' ), mov_read_default },{ MKTAG( 'm', 'p', '4', 's' ), mov_read_default },{ MKTAG( 'm', 'p', '4', 'v' ), mov_read_default },{ MKTAG( 'm', 'p', 'o', 'd' ), mov_read_leaf },{ MKTAG( 'm', 'v', 'h', 'd' ), mov_read_mvhd },{ MKTAG( 'n', 'm', 'h', 'd' ), mov_read_leaf },{ MKTAG( 'o', 'd', 'h', 'd' ), mov_read_default },{ MKTAG( 's', 'd', 'h', 'd' ), mov_read_default },{ MKTAG( 's', 'k', 'i', 'p' ), mov_read_leaf },{ MKTAG( 's', 'm', 'h', 'd' ), mov_read_leaf }, /* sound media info header */{ MKTAG( 'S', 'M', 'I', ' ' ), mov_read_smi }, /* Sorrenson extension ??? */{ MKTAG( 's', 't', 'b', 'l' ), mov_read_default },{ MKTAG( 's', 't', 'c', 'o' ), mov_read_stco },{ MKTAG( 's', 't', 'd', 'p' ), mov_read_default },{ MKTAG( 's', 't', 's', 'c' ), mov_read_stsc },{ MKTAG( 's', 't', 's', 'd' ), mov_read_stsd }, /* sample description */{ MKTAG( 's', 't', 's', 'h' ), mov_read_default },{ MKTAG( 's', 't', 's', 's' ), mov_read_stss }, /* sync sample */{ MKTAG( 's', 't', 's', 'z' ), mov_read_stsz }, /* sample size */{ MKTAG( 's', 't', 't', 's' ), mov_read_stts },{ MKTAG( 't', 'k', 'h', 'd' ), mov_read_tkhd }, /* track header */{ MKTAG( 't', 'r', 'a', 'k' ), mov_read_trak },{ MKTAG( 't', 'r', 'e', 'f' ), mov_read_default }, /* not really */{ MKTAG( 'u', 'd', 't', 'a' ), mov_read_leaf },{ MKTAG( 'u', 'r', 'l', ' ' ), mov_read_leaf },{ MKTAG( 'u', 'r', 'n', ' ' ), mov_read_leaf },{ MKTAG( 'u', 'u', 'i', 'd' ), mov_read_default },{ MKTAG( 'v', 'm', 'h', 'd' ), mov_read_leaf }, /* video media info header */{ MKTAG( 'w', 'a', 'v', 'e' ), mov_read_default },/* extra mp4 */{ MKTAG( 'M', 'D', 'E', 'S' ), mov_read_leaf },/* QT atoms */{ MKTAG( 'c', 'h', 'a', 'p' ), mov_read_leaf },{ MKTAG( 'c', 'l', 'i', 'p' ), mov_read_default },{ MKTAG( 'c', 'r', 'g', 'n' ), mov_read_leaf },{ MKTAG( 'c', 't', 'a', 'b' ), mov_read_ctab },{ MKTAG( 'e', 's', 'd', 's' ), mov_read_esds },{ MKTAG( 'k', 'm', 'a', 't' ), mov_read_leaf },{ MKTAG( 'm', 'a', 't', 't' ), mov_read_default },{ MKTAG( 'r', 'd', 'r', 'f' ), mov_read_leaf },{ MKTAG( 'r', 'm', 'd', 'a' ), mov_read_default },{ MKTAG( 'r', 'm', 'd', 'r' ), mov_read_leaf },{ MKTAG( 'r', 'm', 'r', 'a' ), mov_read_default },{ MKTAG( 's', 'c', 'p', 't' ), mov_read_leaf },{ MKTAG( 's', 's', 'r', 'c' ), mov_read_leaf },{ MKTAG( 's', 'y', 'n', 'c' ), mov_read_leaf },{ MKTAG( 't', 'c', 'm', 'd' ), mov_read_leaf },{ MKTAG( 'w', 'i', 'd', 'e' ), mov_read_wide }, /* place holder *///{ MKTAG( 'r', 'm', 'q', 'u' ), mov_read_leaf },#ifdef CONFIG_ZLIB{ MKTAG( 'c', 'm', 'o', 'v' ), mov_read_cmov },#else{ MKTAG( 'c', 'm', 'o', 'v' ), mov_read_leaf },#endif{ 0L, mov_read_leaf }};static void mov_free_stream_context(MOVStreamContext *sc){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -