?? mov.c
字號:
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]; if((uint64_t)atom.size > (1<<30)) return -1; // currently SVQ3 decoder expect full STSD header - so let's fake it // this should be fixed and just SMI header should be passed av_free(st->codec->extradata); st->codec->extradata_size = 0x5a + atom.size; st->codec->extradata = av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); if (st->codec->extradata) { memcpy(st->codec->extradata, "SVQ3", 4); // fake get_buffer(pb, st->codec->extradata + 0x5a, atom.size); dprintf(c->fc, "Reading SMI %"PRId64" %s\n", atom.size, st->codec->extradata + 0x5a); } else url_fskip(pb, atom.size); return 0;}static int mov_read_enda(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom){ AVStream *st = c->fc->streams[c->fc->nb_streams-1]; int little_endian = get_be16(pb); if (little_endian) { switch (st->codec->codec_id) { case CODEC_ID_PCM_S24BE: st->codec->codec_id = CODEC_ID_PCM_S24LE; break; case CODEC_ID_PCM_S32BE: st->codec->codec_id = CODEC_ID_PCM_S32LE; break; default: break; } } return 0;}/* FIXME modify qdm2/svq3/h264 decoders to take full atom as extradata */static int mov_read_extradata(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom){ AVStream *st = c->fc->streams[c->fc->nb_streams-1]; uint64_t size= (uint64_t)st->codec->extradata_size + atom.size + 8 + FF_INPUT_BUFFER_PADDING_SIZE; uint8_t *buf; if(size > INT_MAX || (uint64_t)atom.size > INT_MAX) return -1; buf= av_realloc(st->codec->extradata, size); if(!buf) return -1; st->codec->extradata= buf; buf+= st->codec->extradata_size; st->codec->extradata_size= size - FF_INPUT_BUFFER_PADDING_SIZE; AV_WB32( buf , atom.size + 8); AV_WL32( buf + 4, atom.type); get_buffer(pb, buf + 8, atom.size); return 0;}static int mov_read_wave(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom){ AVStream *st = c->fc->streams[c->fc->nb_streams-1]; if((uint64_t)atom.size > (1<<30)) return -1; if (st->codec->codec_id == CODEC_ID_QDM2) { // pass all frma atom to codec, needed at least for QDM2 av_free(st->codec->extradata); st->codec->extradata_size = atom.size; st->codec->extradata = av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); if (st->codec->extradata) { get_buffer(pb, st->codec->extradata, atom.size); } else url_fskip(pb, atom.size); } else if (atom.size > 8) { /* to read frma, esds atoms */ if (mov_read_default(c, pb, atom) < 0) return -1; } else url_fskip(pb, atom.size); return 0;}/** * This function reads atom content and puts data in extradata without tag * nor size unlike mov_read_extradata. */static int mov_read_glbl(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom){ AVStream *st = c->fc->streams[c->fc->nb_streams-1]; if((uint64_t)atom.size > (1<<30)) return -1; av_free(st->codec->extradata); st->codec->extradata_size = atom.size; st->codec->extradata = av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); if (st->codec->extradata) { get_buffer(pb, st->codec->extradata, atom.size); } else url_fskip(pb, atom.size); return 0;}static int mov_read_stco(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(int64_t)) return -1; sc->chunk_count = entries; sc->chunk_offsets = av_malloc(entries * sizeof(int64_t)); if (!sc->chunk_offsets) return -1; if (atom.type == MKTAG('s', 't', 'c', 'o')) { for(i=0; i<entries; i++) { sc->chunk_offsets[i] = get_be32(pb); } } else if (atom.type == MKTAG('c', 'o', '6', '4')) { for(i=0; i<entries; i++) { sc->chunk_offsets[i] = get_be64(pb); } } else return -1; return 0;}static int mov_read_stsd(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom){ AVStream *st = c->fc->streams[c->fc->nb_streams-1]; MOVStreamContext *sc = st->priv_data; int entries, frames_per_sample; uint32_t format; uint8_t codec_name[32]; /* for palette traversal */ unsigned int color_depth; unsigned int color_start; unsigned int color_count; unsigned int color_end; int color_index; int color_dec; int color_greyscale; const uint8_t *color_table; int j, pseudo_stream_id; unsigned char r, g, b; get_byte(pb); /* version */ get_byte(pb); get_byte(pb); get_byte(pb); /* flags */ entries = get_be32(pb); for(pseudo_stream_id=0; pseudo_stream_id<entries; pseudo_stream_id++) { //Parsing Sample description table enum CodecID id; MOV_atom_t a = { 0, 0, 0 }; offset_t start_pos = url_ftell(pb); int size = get_be32(pb); /* size */ format = get_le32(pb); /* data format */ get_be32(pb); /* reserved */ get_be16(pb); /* reserved */ get_be16(pb); /* index */ if (st->codec->codec_tag && (c->fc->video_codec_id ? codec_get_id(codec_movvideo_tags, format) != c->fc->video_codec_id : st->codec->codec_tag != MKTAG('j', 'p', 'e', 'g')) ){ /* multiple fourcc, we skip jpeg, this isnt correct, we should export it as seperate AVStream but this needs a few changes in the mov demuxer, patch welcome */ url_fskip(pb, size - (url_ftell(pb) - start_pos)); continue; } sc->pseudo_stream_id= pseudo_stream_id; st->codec->codec_tag = format; id = codec_get_id(codec_movaudio_tags, format); if (id<=0 && (format&0xFFFF) == 'm' + ('s'<<8)) id = codec_get_id(codec_wav_tags, bswap_32(format)&0xFFFF); if (st->codec->codec_type != CODEC_TYPE_VIDEO && id > 0) { st->codec->codec_type = CODEC_TYPE_AUDIO; } else if (st->codec->codec_type != CODEC_TYPE_AUDIO && /* do not overwrite codec type */ format && format != MKTAG('m', 'p', '4', 's')) { /* skip old asf mpeg4 tag */ id = codec_get_id(codec_movvideo_tags, format); if (id <= 0) id = codec_get_id(codec_bmp_tags, format); if (id > 0) st->codec->codec_type = CODEC_TYPE_VIDEO; else if(st->codec->codec_type == CODEC_TYPE_DATA){ id = codec_get_id(ff_codec_movsubtitle_tags, format); if(id > 0) st->codec->codec_type = CODEC_TYPE_SUBTITLE; } } dprintf(c->fc, "size=%d 4CC= %c%c%c%c codec_type=%d\n", size, (format >> 0) & 0xff, (format >> 8) & 0xff, (format >> 16) & 0xff, (format >> 24) & 0xff, st->codec->codec_type); if(st->codec->codec_type==CODEC_TYPE_VIDEO) { st->codec->codec_id = id; get_be16(pb); /* version */ get_be16(pb); /* revision level */ get_be32(pb); /* vendor */ get_be32(pb); /* temporal quality */ get_be32(pb); /* spatial quality */ st->codec->width = get_be16(pb); /* width */ st->codec->height = get_be16(pb); /* height */ get_be32(pb); /* horiz resolution */ get_be32(pb); /* vert resolution */ get_be32(pb); /* data size, always 0 */ frames_per_sample = get_be16(pb); /* frames per samples */ dprintf(c->fc, "frames/samples = %d\n", frames_per_sample); get_buffer(pb, codec_name, 32); /* codec name, pascal string (FIXME: true for mp4?) */ if (codec_name[0] <= 31) { memcpy(st->codec->codec_name, &codec_name[1],codec_name[0]); st->codec->codec_name[codec_name[0]] = 0; } st->codec->bits_per_sample = get_be16(pb); /* depth */ st->codec->color_table_id = get_be16(pb); /* colortable id */ /* figure out the palette situation */ color_depth = st->codec->bits_per_sample & 0x1F; color_greyscale = st->codec->bits_per_sample & 0x20; /* if the depth is 2, 4, or 8 bpp, file is palettized */ if ((color_depth == 2) || (color_depth == 4) || (color_depth == 8)) { if (color_greyscale) { /* compute the greyscale palette */ color_count = 1 << color_depth; color_index = 255; color_dec = 256 / (color_count - 1); for (j = 0; j < color_count; j++) { r = g = b = color_index; c->palette_control.palette[j] = (r << 16) | (g << 8) | (b); color_index -= color_dec; if (color_index < 0) color_index = 0; } } else if (st->codec->color_table_id & 0x08) { /* if flag bit 3 is set, use the default palette */ color_count = 1 << color_depth; if (color_depth == 2) color_table = ff_qt_default_palette_4; else if (color_depth == 4) color_table = ff_qt_default_palette_16; else color_table = ff_qt_default_palette_256; for (j = 0; j < color_count; j++) { r = color_table[j * 4 + 0]; g = color_table[j * 4 + 1]; b = color_table[j * 4 + 2]; c->palette_control.palette[j] = (r << 16) | (g << 8) | (b); } } else { /* load the palette from the file */ color_start = get_be32(pb); color_count = get_be16(pb); color_end = get_be16(pb); if ((color_start <= 255) && (color_end <= 255)) { for (j = color_start; j <= color_end; j++) { /* each R, G, or B component is 16 bits; * only use the top 8 bits; skip alpha bytes * up front */ get_byte(pb); get_byte(pb); r = get_byte(pb); get_byte(pb); g = get_byte(pb); get_byte(pb); b = get_byte(pb); get_byte(pb); c->palette_control.palette[j] = (r << 16) | (g << 8) | (b); } } } st->codec->palctrl = &c->palette_control; st->codec->palctrl->palette_changed = 1; } else st->codec->palctrl = NULL; } else if(st->codec->codec_type==CODEC_TYPE_AUDIO) { int bits_per_sample; uint16_t version = get_be16(pb); st->codec->codec_id = id; get_be16(pb); /* revision level */ get_be32(pb); /* vendor */ st->codec->channels = get_be16(pb); /* channel count */ dprintf(c->fc, "audio channels %d\n", st->codec->channels); st->codec->bits_per_sample = get_be16(pb); /* sample size */ sc->audio_cid = get_be16(pb); get_be16(pb); /* packet size = 0 */ st->codec->sample_rate = ((get_be32(pb) >> 16)); switch (st->codec->codec_id) { case CODEC_ID_PCM_S8: case CODEC_ID_PCM_U8: if (st->codec->bits_per_sample == 16) st->codec->codec_id = CODEC_ID_PCM_S16BE; break; case CODEC_ID_PCM_S16LE: case CODEC_ID_PCM_S16BE: if (st->codec->bits_per_sample == 8) st->codec->codec_id = CODEC_ID_PCM_S8; else if (st->codec->bits_per_sample == 24) st->codec->codec_id = CODEC_ID_PCM_S24BE; break; default: break; } //Read QT version 1 fields. In version 0 these do not exist. dprintf(c->fc, "version =%d, isom =%d\n",version,c->isom); if(!c->isom) { if(version==1) { sc->samples_per_frame = get_be32(pb); get_be32(pb); /* bytes per packet */ sc->bytes_per_frame = get_be32(pb); 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 */ } } bits_per_sample = av_get_bits_per_sample(st->codec->codec_id); if (bits_per_sample) { st->codec->bits_per_sample = bits_per_sample; sc->sample_size = (bits_per_sample >> 3) * st->codec->channels; } } else if(st->codec->codec_type==CODEC_TYPE_SUBTITLE){ st->codec->codec_id= id; } 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) { if (mov_read_default(c, pb, a) < 0) return -1; } 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; } /* special codec parameters handling */ switch (st->codec->codec_id) {#ifdef CONFIG_H261_DECODER case CODEC_ID_H261:#endif#ifdef CONFIG_H263_DECODER case CODEC_ID_H263:#endif#ifdef CONFIG_MPEG4_DECODER case CODEC_ID_MPEG4:#endif st->codec->width= 0; /* let decoder init width/height */ st->codec->height= 0; break;#ifdef CONFIG_LIBFAAD 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;#ifdef CONFIG_DV_DEMUXER case CODEC_ID_DVAUDIO: c->dv_fctx = av_alloc_format_context();
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -