📄 mov.c
字号:
get_be32(pb); /* bytes per frame */ get_be32(pb); /* bytes per sample */ } else if(version==2) { get_be32(pb); /* sizeof struct only */ st->codec->sample_rate = av_int2dbl(get_be64(pb)); /* float 64 */ st->codec->channels = get_be32(pb); get_be32(pb); /* always 0x7F000000 */ get_be32(pb); /* bits per channel if sound is uncompressed */ get_be32(pb); /* lcpm format specific flag */ get_be32(pb); /* bytes per audio packet if constant */ get_be32(pb); /* lpcm frames per audio packet if constant */ } } else { /* other codec type, just skip (rtp, mp4s, tmcd ...) */ url_fskip(pb, size - (url_ftell(pb) - start_pos)); } /* this will read extra atoms at the end (wave, alac, damr, avcC, SMI ...) */ a.size = size - (url_ftell(pb) - start_pos); if (a.size > 8) mov_read_default(c, pb, a); else if (a.size > 0) url_fskip(pb, a.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; } switch (st->codec->codec_id) {#ifdef CONFIG_FAAD case CODEC_ID_AAC:#endif#ifdef CONFIG_VORBIS_DECODER case CODEC_ID_VORBIS:#endif case CODEC_ID_MP3ON4: st->codec->sample_rate= 0; /* let decoder init parameters properly */ 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 = (MOVStreamContext *)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_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); } 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; 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; 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) { /* override sample size for uncompressed sound */ switch (st->codec->codec_id) { case CODEC_ID_PCM_S32BE: case CODEC_ID_PCM_S32LE: sc->sample_size = 4 * st->codec->channels; break; case CODEC_ID_PCM_S24BE: case CODEC_ID_PCM_S24LE: sc->sample_size = 3 * st->codec->channels; break; case CODEC_ID_PCM_S16BE: case CODEC_ID_PCM_S16LE: sc->sample_size = 2 * st->codec->channels; break; case CODEC_ID_PCM_MULAW: case CODEC_ID_PCM_ALAW: case CODEC_ID_PCM_S8: case CODEC_ID_PCM_U8: sc->sample_size = 1 * st->codec->channels; break; default: break; } assert(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; 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; sc->stts_count = entries; sc->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 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("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 = (MOVStreamContext *)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(Time2Sample)) return -1; sc->ctts_count = entries; sc->ctts_data = av_malloc(entries * sizeof(Time2Sample)); dprintf("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 = (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 = 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 */ /*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; 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;}#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; 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 = (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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -