?? mov.c
字號:
c->dv_demux = dv_init_demux(c->dv_fctx); if (!c->dv_demux) { av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n"); return -1; } sc->dv_audio_container = 1; st->codec->codec_id = CODEC_ID_PCM_S16LE; break;#endif /* no ifdef since parameters are always those */ case CODEC_ID_AMR_WB: st->codec->sample_rate= 16000; st->codec->channels= 1; /* really needed */ break; case CODEC_ID_AMR_NB: st->codec->sample_rate= 8000; st->codec->channels= 1; /* really needed */ break; case CODEC_ID_MP2: case CODEC_ID_MP3: st->codec->codec_type = CODEC_TYPE_AUDIO; /* force type after stsd for m1a hdlr */ st->need_parsing = AVSTREAM_PARSE_FULL; break; case CODEC_ID_ADPCM_MS: case CODEC_ID_ADPCM_IMA_WAV: st->codec->block_align = sc->bytes_per_frame; break; default: break; } 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 = st->priv_data; unsigned int i, entries; get_byte(pb); /* version */ get_byte(pb); get_byte(pb); get_byte(pb); /* flags */ entries = get_be32(pb); if(entries >= UINT_MAX / sizeof(MOV_stsc_t)) return -1; dprintf(c->fc, "track[%i].stsc.entries = %i\n", c->fc->nb_streams-1, entries); sc->sample_to_chunk_sz = entries; sc->sample_to_chunk = av_malloc(entries * sizeof(MOV_stsc_t)); 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); } 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 = st->priv_data; unsigned int i, entries; get_byte(pb); /* version */ get_byte(pb); get_byte(pb); get_byte(pb); /* flags */ entries = get_be32(pb); if(entries >= UINT_MAX / sizeof(int)) return -1; sc->keyframe_count = entries; dprintf(c->fc, "keyframe_count = %d\n", sc->keyframe_count); sc->keyframes = av_malloc(entries * sizeof(int)); if (!sc->keyframes) return -1; for(i=0; i<entries; i++) { sc->keyframes[i] = get_be32(pb); //dprintf(c->fc, "keyframes[]=%d\n", sc->keyframes[i]); } 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 = st->priv_data; unsigned int i, entries, sample_size; get_byte(pb); /* version */ get_byte(pb); get_byte(pb); get_byte(pb); /* flags */ sample_size = get_be32(pb); if (!sc->sample_size) /* do not overwrite value computed in stsd */ sc->sample_size = sample_size; entries = get_be32(pb); if(entries >= UINT_MAX / sizeof(int)) return -1; sc->sample_count = entries; if (sample_size) return 0; dprintf(c->fc, "sample_size = %d sample_count = %d\n", sc->sample_size, sc->sample_count); sc->sample_sizes = av_malloc(entries * sizeof(int)); if (!sc->sample_sizes) return -1; for(i=0; i<entries; i++) { sc->sample_sizes[i] = get_be32(pb); dprintf(c->fc, "sample_sizes[]=%d\n", sc->sample_sizes[i]); } 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 = st->priv_data; unsigned int i, entries; int64_t duration=0; int64_t total_sample_count=0; get_byte(pb); /* version */ get_byte(pb); get_byte(pb); get_byte(pb); /* flags */ entries = get_be32(pb); if(entries >= UINT_MAX / sizeof(MOV_stts_t)) return -1; sc->stts_count = entries; sc->stts_data = av_malloc(entries * sizeof(MOV_stts_t)); if (!sc->stts_data) return -1; dprintf(c->fc, "track[%i].stts.entries = %i\n", c->fc->nb_streams-1, entries); sc->time_rate=0; for(i=0; i<entries; i++) { int sample_duration; int sample_count; sample_count=get_be32(pb); sample_duration = get_be32(pb); sc->stts_data[i].count= sample_count; sc->stts_data[i].duration= sample_duration; sc->time_rate= ff_gcd(sc->time_rate, sample_duration); dprintf(c->fc, "sample_count=%d, sample_duration=%d\n",sample_count,sample_duration); duration+=(int64_t)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 = st->priv_data; unsigned int i, entries; get_byte(pb); /* version */ get_byte(pb); get_byte(pb); get_byte(pb); /* flags */ entries = get_be32(pb); if(entries >= UINT_MAX / sizeof(MOV_stts_t)) return -1; sc->ctts_count = entries; sc->ctts_data = av_malloc(entries * sizeof(MOV_stts_t)); if (!sc->ctts_data) return -1; dprintf(c->fc, "track[%i].ctts.entries = %i\n", c->fc->nb_streams-1, entries); for(i=0; i<entries; i++) { int count =get_be32(pb); int duration =get_be32(pb); if (duration < 0) { av_log(c->fc, AV_LOG_ERROR, "negative ctts, ignoring\n"); sc->ctts_count = 0; url_fskip(pb, 8 * (entries - i - 1)); break; } sc->ctts_data[i].count = count; sc->ctts_data[i].duration= duration; sc->time_rate= ff_gcd(sc->time_rate, duration); } return 0;}static int mov_read_trak(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom){ AVStream *st; MOVStreamContext *sc; st = av_new_stream(c->fc, c->fc->nb_streams); if (!st) return -2; sc = av_mallocz(sizeof(MOVStreamContext)); if (!sc) { av_free(st); return -1; } st->priv_data = sc; st->codec->codec_type = CODEC_TYPE_DATA; st->start_time = 0; /* XXX: check */ return mov_read_default(c, pb, atom);}static void mov_parse_udta_string(ByteIOContext *pb, char *str, int size){ uint16_t str_size = get_be16(pb); /* string length */; get_be16(pb); /* skip language */ get_buffer(pb, str, FFMIN(size, str_size));}static int mov_read_udta(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom){ uint64_t end = url_ftell(pb) + atom.size; while (url_ftell(pb) + 8 < end) { uint32_t tag_size = get_be32(pb); uint32_t tag = get_le32(pb); uint64_t next = url_ftell(pb) + tag_size - 8; if (next > end) // stop if tag_size is wrong break; switch (tag) { case MKTAG(0xa9,'n','a','m'): mov_parse_udta_string(pb, c->fc->title, sizeof(c->fc->title)); break; case MKTAG(0xa9,'w','r','t'): mov_parse_udta_string(pb, c->fc->author, sizeof(c->fc->author)); break; case MKTAG(0xa9,'c','p','y'): mov_parse_udta_string(pb, c->fc->copyright, sizeof(c->fc->copyright)); break; case MKTAG(0xa9,'i','n','f'): mov_parse_udta_string(pb, c->fc->comment, sizeof(c->fc->comment)); break; default: break; } url_fseek(pb, next, SEEK_SET); } return 0;}static int mov_read_tkhd(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom){ AVStream *st = c->fc->streams[c->fc->nb_streams-1]; int version = get_byte(pb); 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 */ if (version == 1) { get_be64(pb); get_be64(pb); } else { 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 */ (version == 1) ? get_be64(pb) : 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 */ get_be32(pb); /* track width */ get_be32(pb); /* 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; 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); return err;}static int mov_read_cmov(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom){#ifdef CONFIG_ZLIB ByteIOContext ctx; uint8_t *cmov_data; uint8_t *moov_data; /* uncompressed data */ long cmov_len, moov_len; int ret; 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_ERROR, "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, (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, NULL, NULL) != 0) return -1; 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;#else av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n"); return -1;#endif}/* edit list atom */static int mov_read_elst(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom){ MOVStreamContext *sc = c->fc->streams[c->fc->nb_streams-1]->priv_data; int i, edit_count; get_byte(pb); /* version */ get_byte(pb); get_byte(pb); get_byte(pb); /* flags */ edit_count= sc->edit_count = get_be32(pb); /* entries */ for(i=0; i<edit_count; i++){ get_be32(pb); /* Track duration */ get_be32(pb); /* Media time */ get_be32(pb); /* Media rate */ } dprintf(c->fc, "track[%i].edit_count = %i\n", c->fc->nb_streams-1, sc->edit_count); return 0;}static const MOVParseTableEntry mov_default_parse_table[] = {/* mp4 atoms */{ MKTAG( 'c', 'o', '6', '4' ), mov_read_stco },{ MKTAG( 'c', 't', 't', 's' ), mov_read_ctts }, /* composition time to sample */{ MKTAG( 'e', 'd', 't', 's' ), mov_read_default },{ MKTAG( 'e', 'l', 's', 't' ), mov_read_elst },{ MKTAG( 'e', 'n', 'd', 'a' ), mov_read_enda },{ MKTAG( 'f', 'i', 'e', 'l' ), mov_read_extradata },{ MKTAG( 'f', 't', 'y', 'p' ), mov_read_ftyp },{ MKTAG( 'g', 'l', 'b', 'l' ), mov_read_glbl },{ MKTAG( 'h', 'd', 'l', 'r' ), mov_read_hdlr },{ MKTAG( 'j', 'p', '2', 'h' ), mov_read_extradata },{ 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 },
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -