/** Read packet table chunk */ static int read_pakt_chunk(AVFormatContext *s, int64_t size) { AVIOContext *pb = s->pb; AVStream *st = s->streams[0]; CafContext *caf = s->priv_data; int64_t pos = 0, ccount, num_packets; int i; ccount = avio_tell(pb); num_packets = avio_rb64(pb); if (num_packets < 0 || INT32_MAX / sizeof(AVIndexEntry) < num_packets) return AVERROR_INVALIDDATA; st->nb_frames = avio_rb64(pb); /* valid frames */ st->nb_frames += avio_rb32(pb); /* priming frames */ st->nb_frames += avio_rb32(pb); /* remainder frames */ st->duration = 0; for (i = 0; i < num_packets; i++) { av_add_index_entry(s->streams[0], pos, st->duration, 0, 0, AVINDEX_KEYFRAME); pos += caf->bytes_per_packet ? caf->bytes_per_packet : ff_mp4_read_descr_len(pb); st->duration += caf->frames_per_packet ? caf->frames_per_packet : ff_mp4_read_descr_len(pb); } if (avio_tell(pb) - ccount > size) { av_log(s, AV_LOG_ERROR, "error reading packet table\n"); return AVERROR_INVALIDDATA; } avio_skip(pb, ccount + size - avio_tell(pb)); caf->num_bytes = pos; return 0; }
static int wv_read_packet(AVFormatContext *s, AVPacket *pkt) { WVContext *wc = s->priv_data; int ret; if (url_feof(s->pb)) return AVERROR(EIO); if(wc->block_parsed){ if(wv_read_block_header(s, s->pb) < 0) return -1; } if(av_new_packet(pkt, wc->blksize + WV_EXTRA_SIZE) < 0) return AVERROR(ENOMEM); memcpy(pkt->data, wc->extra, WV_EXTRA_SIZE); ret = get_buffer(s->pb, pkt->data + WV_EXTRA_SIZE, wc->blksize); if(ret != wc->blksize){ av_free_packet(pkt); return AVERROR(EIO); } pkt->stream_index = 0; wc->block_parsed = 1; pkt->size = ret + WV_EXTRA_SIZE; pkt->pts = wc->soff; av_add_index_entry(s->streams[0], wc->pos, pkt->pts, 0, 0, AVINDEX_KEYFRAME); return 0; }
static int wv_read_packet(AVFormatContext *s, AVPacket *pkt) { WVContext *wc = s->priv_data; int ret; int off; int64_t pos; uint32_t block_samples; if (url_feof(s->pb)) return AVERROR_EOF; if (wc->block_parsed) { if ((ret = wv_read_block_header(s, s->pb)) < 0) return ret; } pos = wc->pos; if (av_new_packet(pkt, wc->header.blocksize + WV_HEADER_SIZE) < 0) return AVERROR(ENOMEM); memcpy(pkt->data, wc->block_header, WV_HEADER_SIZE); ret = avio_read(s->pb, pkt->data + WV_HEADER_SIZE, wc->header.blocksize); if (ret != wc->header.blocksize) { av_free_packet(pkt); return AVERROR(EIO); } while (!(wc->header.flags & WV_FLAG_FINAL_BLOCK)) { if ((ret = wv_read_block_header(s, s->pb)) < 0) { av_free_packet(pkt); return ret; } off = pkt->size; if ((ret = av_grow_packet(pkt, WV_HEADER_SIZE + wc->header.blocksize)) < 0) { av_free_packet(pkt); return ret; } memcpy(pkt->data + off, wc->block_header, WV_HEADER_SIZE); ret = avio_read(s->pb, pkt->data + off + WV_HEADER_SIZE, wc->header.blocksize); if (ret != wc->header.blocksize) { av_free_packet(pkt); return (ret < 0) ? ret : AVERROR_EOF; } } pkt->stream_index = 0; wc->block_parsed = 1; pkt->pts = wc->header.block_idx; block_samples = wc->header.samples; if (block_samples > INT32_MAX) av_log(s, AV_LOG_WARNING, "Too many samples in block: %"PRIu32"\n", block_samples); else pkt->duration = block_samples; av_add_index_entry(s->streams[0], pos, pkt->pts, 0, 0, AVINDEX_KEYFRAME); return 0; }
/** this function assumes that the demuxer has already seeked to the start * of the INDX chunk, and will bail out if not. */ static int rm_read_index(AVFormatContext *s) { AVIOContext *pb = s->pb; unsigned int size, n_pkts, str_id, next_off, n, pos, pts; AVStream *st; do { if (avio_rl32(pb) != MKTAG('I','N','D','X')) return -1; size = avio_rb32(pb); if (size < 20) return -1; avio_skip(pb, 2); n_pkts = avio_rb32(pb); str_id = avio_rb16(pb); next_off = avio_rb32(pb); for (n = 0; n < s->nb_streams; n++) if (s->streams[n]->id == str_id) { st = s->streams[n]; break; } if (n == s->nb_streams) { av_log(s, AV_LOG_ERROR, "Invalid stream index %d for index at pos %"PRId64"\n", str_id, avio_tell(pb)); goto skip; } else if ((avio_size(pb) - avio_tell(pb)) / 14 < n_pkts) { av_log(s, AV_LOG_ERROR, "Nr. of packets in packet index for stream index %d " "exceeds filesize (%"PRId64" at %"PRId64" = %"PRId64")\n", str_id, avio_size(pb), avio_tell(pb), (avio_size(pb) - avio_tell(pb)) / 14); goto skip; } for (n = 0; n < n_pkts; n++) { avio_skip(pb, 2); pts = avio_rb32(pb); pos = avio_rb32(pb); avio_skip(pb, 4); /* packet no. */ av_add_index_entry(st, pos, pts, 0, 0, AVINDEX_KEYFRAME); } skip: if (next_off && avio_tell(pb) < next_off && avio_seek(pb, next_off, SEEK_SET) < 0) { av_log(s, AV_LOG_ERROR, "Non-linear index detected, not supported\n"); return -1; } } while (next_off); return 0; }
/** * \brief attempts to read a timestamp from stream at the given stream position * \return timestamp if successfull and AV_NOPTS_VALUE if failure */ static int64_t nuv_read_dts(AVFormatContext *s, int stream_index, int64_t *ppos, int64_t pos_limit) { NUVContext *ctx = s->priv_data; AVIOContext *pb = s->pb; uint8_t hdr[HDRSIZE]; nuv_frametype frametype; int size, key, idx; int64_t pos, dts; if (avio_seek(pb, *ppos, SEEK_SET) < 0) return AV_NOPTS_VALUE; if (!nuv_resync(s, pos_limit)) return AV_NOPTS_VALUE; while (!url_feof(pb) && avio_tell(pb) < pos_limit) { if (avio_read(pb, hdr, HDRSIZE) < HDRSIZE) return AV_NOPTS_VALUE; frametype = hdr[0]; size = PKTSIZE(AV_RL32(&hdr[8])); switch (frametype) { case NUV_SEEKP: break; case NUV_AUDIO: case NUV_VIDEO: if (frametype == NUV_VIDEO) { idx = ctx->v_id; key = hdr[2] == 0; } else { idx = ctx->a_id; key = 1; } if (stream_index == idx) { pos = avio_tell(s->pb) - HDRSIZE; dts = AV_RL32(&hdr[4]); // TODO - add general support in av_gen_search, so it adds positions after reading timestamps av_add_index_entry(s->streams[stream_index], pos, dts, size + HDRSIZE, 0, key ? AVINDEX_KEYFRAME : 0); *ppos = pos; return dts; } default: avio_skip(pb, size); break; } } return AV_NOPTS_VALUE; }
static int pva_read_header(AVFormatContext *s, AVFormatParameters *ap) { AVStream *st; if (!(st = avformat_new_stream(s, NULL))) return AVERROR(ENOMEM); st->codec->codec_type = AVMEDIA_TYPE_VIDEO; st->codec->codec_id = CODEC_ID_MPEG2VIDEO; st->need_parsing = AVSTREAM_PARSE_FULL; avpriv_set_pts_info(st, 32, 1, 90000); av_add_index_entry(st, 0, 0, 0, 0, AVINDEX_KEYFRAME); if (!(st = avformat_new_stream(s, NULL))) return AVERROR(ENOMEM); st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_id = CODEC_ID_MP2; st->need_parsing = AVSTREAM_PARSE_FULL; avpriv_set_pts_info(st, 33, 1, 90000); av_add_index_entry(st, 0, 0, 0, 0, AVINDEX_KEYFRAME); /* the parameters will be extracted from the compressed bitstream */ return 0; }
int32_t Stream :: addIndexEntry(IIndexEntry* entry) { if (!entry) return -1; if (!mStream) return -1; return av_add_index_entry(mStream, entry->getPosition(), entry->getTimeStamp(), entry->getSize(), entry->getMinDistance(), entry->getFlags()); }
static void read_index(AVIOContext *pb, AVStream *st) { uint64_t timestamp = 0; int i; for (i = 0; i < st->nb_frames; i++) { uint32_t pos = avio_rb32(pb); uint32_t size = avio_rb32(pb); avio_skip(pb, 8); av_add_index_entry(st, pos, timestamp, size, 0, AVINDEX_KEYFRAME); if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { timestamp += size / (st->codecpar->channels * 2); } else { timestamp++; } } }
static void read_xing_toc(AVFormatContext *s, int64_t filesize, int64_t duration) { int i; MP3Context *mp3 = s->priv_data; if (!filesize && !(filesize = avio_size(s->pb))) { av_log(s, AV_LOG_WARNING, "Cannot determine file size, skipping TOC table.\n"); return; } for (i = 0; i < XING_TOC_COUNT; i++) { uint8_t b = avio_r8(s->pb); av_add_index_entry(s->streams[0], av_rescale(b, filesize, 256), av_rescale(i, duration, XING_TOC_COUNT), 0, 0, AVINDEX_KEYFRAME); } mp3->xing_toc = 1; }
static int wv_read_packet(AVFormatContext *s, AVPacket *pkt) { WVContext *wc = s->priv_data; int ret; int size, ver, off; int64_t pos; uint32_t block_samples; if (s->pb->eof_reached) return AVERROR_EOF; if(wc->block_parsed) { if ((ret = wv_read_block_header(s, s->pb, 0)) < 0) return ret; } pos = wc->pos; off = wc->multichannel ? 4 : 0; if(av_new_packet(pkt, wc->blksize + WV_EXTRA_SIZE + off) < 0) return AVERROR(ENOMEM); if(wc->multichannel) AV_WL32(pkt->data, wc->blksize + WV_EXTRA_SIZE + 12); memcpy(pkt->data + off, wc->extra, WV_EXTRA_SIZE); ret = avio_read(s->pb, pkt->data + WV_EXTRA_SIZE + off, wc->blksize); if(ret != wc->blksize) { av_free_packet(pkt); return AVERROR(EIO); } while(!(wc->flags & WV_END_BLOCK)) { if(avio_rl32(s->pb) != MKTAG('w', 'v', 'p', 'k')) { av_free_packet(pkt); return AVERROR_INVALIDDATA; } if((ret = av_append_packet(s->pb, pkt, 4)) < 0) { av_free_packet(pkt); return ret; } size = AV_RL32(pkt->data + pkt->size - 4); if(size < 24 || size > WV_BLOCK_LIMIT) { av_free_packet(pkt); av_log(s, AV_LOG_ERROR, "Incorrect block size %d\n", size); return AVERROR_INVALIDDATA; } wc->blksize = size; ver = avio_rl16(s->pb); if(ver < 0x402 || ver > 0x410) { av_free_packet(pkt); av_log(s, AV_LOG_ERROR, "Unsupported version %03X\n", ver); return AVERROR_PATCHWELCOME; } avio_r8(s->pb); // track no avio_r8(s->pb); // track sub index wc->samples = avio_rl32(s->pb); // total samples in file wc->soff = avio_rl32(s->pb); // offset in samples of current block if((ret = av_append_packet(s->pb, pkt, WV_EXTRA_SIZE)) < 0) { av_free_packet(pkt); return ret; } memcpy(wc->extra, pkt->data + pkt->size - WV_EXTRA_SIZE, WV_EXTRA_SIZE); if ((ret = wv_read_block_header(s, s->pb, 1)) < 0) { av_free_packet(pkt); return ret; } ret = av_append_packet(s->pb, pkt, wc->blksize); if(ret < 0) { av_free_packet(pkt); return ret; } } pkt->stream_index = 0; wc->block_parsed = 1; pkt->pts = wc->soff; block_samples = AV_RN32(wc->extra); if (block_samples > INT32_MAX) av_log(s, AV_LOG_WARNING, "Too many samples in block: %"PRIu32"\n", block_samples); else pkt->duration = block_samples; av_add_index_entry(s->streams[0], pos, pkt->pts, 0, 0, AVINDEX_KEYFRAME); return 0; }
/** * read rl2 header data and setup the avstreams * @param s demuxer context * @param ap format parameters * @return 0 on success, AVERROR otherwise */ static av_cold int rl2_read_header(AVFormatContext *s, AVFormatParameters *ap) { AVIOContext *pb = s->pb; AVStream *st; unsigned int frame_count; unsigned int audio_frame_counter = 0; unsigned int video_frame_counter = 0; unsigned int back_size; int data_size; unsigned short encoding_method; unsigned short sound_rate; unsigned short rate; unsigned short channels; unsigned short def_sound_size; unsigned int signature; unsigned int pts_den = 11025; /* video only case */ unsigned int pts_num = 1103; unsigned int* chunk_offset = NULL; int* chunk_size = NULL; int* audio_size = NULL; int i; int ret = 0; avio_seek(pb,4, SEEK_CUR); /* skip FORM tag */ back_size = avio_rl32(pb); /**< get size of the background frame */ signature = avio_rb32(pb); data_size = avio_rb32(pb); frame_count = avio_rl32(pb); /* disallow back_sizes and frame_counts that may lead to overflows later */ if(back_size > INT_MAX/2 || frame_count > INT_MAX / sizeof(uint32_t)) return AVERROR_INVALIDDATA; encoding_method = avio_rl16(pb); sound_rate = avio_rl16(pb); rate = avio_rl16(pb); channels = avio_rl16(pb); def_sound_size = avio_rl16(pb); /** setup video stream */ st = av_new_stream(s, 0); if(!st) return AVERROR(ENOMEM); st->codec->codec_type = AVMEDIA_TYPE_VIDEO; st->codec->codec_id = CODEC_ID_RL2; st->codec->codec_tag = 0; /* no fourcc */ st->codec->width = 320; st->codec->height = 200; /** allocate and fill extradata */ st->codec->extradata_size = EXTRADATA1_SIZE; if(signature == RLV3_TAG && back_size > 0) st->codec->extradata_size += back_size; st->codec->extradata = av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); if(!st->codec->extradata) return AVERROR(ENOMEM); if(avio_read(pb,st->codec->extradata,st->codec->extradata_size) != st->codec->extradata_size) return AVERROR(EIO); /** setup audio stream if present */ if(sound_rate) { pts_num = def_sound_size; pts_den = rate; st = av_new_stream(s, 0); if (!st) return AVERROR(ENOMEM); st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_id = CODEC_ID_PCM_U8; st->codec->codec_tag = 1; st->codec->channels = channels; st->codec->bits_per_coded_sample = 8; st->codec->sample_rate = rate; st->codec->bit_rate = st->codec->channels * st->codec->sample_rate * st->codec->bits_per_coded_sample; st->codec->block_align = st->codec->channels * st->codec->bits_per_coded_sample / 8; av_set_pts_info(st,32,1,rate); } av_set_pts_info(s->streams[0], 32, pts_num, pts_den); chunk_size = av_malloc(frame_count * sizeof(uint32_t)); audio_size = av_malloc(frame_count * sizeof(uint32_t)); chunk_offset = av_malloc(frame_count * sizeof(uint32_t)); if(!chunk_size || !audio_size || !chunk_offset) { av_free(chunk_size); av_free(audio_size); av_free(chunk_offset); return AVERROR(ENOMEM); } /** read offset and size tables */ for(i=0; i < frame_count; i++) chunk_size[i] = avio_rl32(pb); for(i=0; i < frame_count; i++) chunk_offset[i] = avio_rl32(pb); for(i=0; i < frame_count; i++) audio_size[i] = avio_rl32(pb) & 0xFFFF; /** build the sample index */ for(i=0; i<frame_count; i++) { if(chunk_size[i] < 0 || audio_size[i] > chunk_size[i]) { ret = AVERROR_INVALIDDATA; break; } if(sound_rate && audio_size[i]) { av_add_index_entry(s->streams[1], chunk_offset[i], audio_frame_counter,audio_size[i], 0, AVINDEX_KEYFRAME); audio_frame_counter += audio_size[i] / channels; } av_add_index_entry(s->streams[0], chunk_offset[i] + audio_size[i], video_frame_counter,chunk_size[i]-audio_size[i],0,AVINDEX_KEYFRAME); ++video_frame_counter; } av_free(chunk_size); av_free(audio_size); av_free(chunk_offset); return ret; }
static int tta_read_header(AVFormatContext *s) { TTAContext *c = s->priv_data; AVStream *st; int i, channels, bps, samplerate; uint64_t framepos, start_offset; uint32_t nb_samples, crc; ff_id3v1_read(s); if (s->pb->seekable) { int64_t pos = avio_tell(s->pb); ff_ape_parse_tag(s); avio_seek(s->pb, pos, SEEK_SET); } start_offset = avio_tell(s->pb); ffio_init_checksum(s->pb, tta_check_crc, UINT32_MAX); if (avio_rl32(s->pb) != AV_RL32("TTA1")) return AVERROR_INVALIDDATA; avio_skip(s->pb, 2); // FIXME: flags channels = avio_rl16(s->pb); bps = avio_rl16(s->pb); samplerate = avio_rl32(s->pb); if(samplerate <= 0 || samplerate > 1000000){ av_log(s, AV_LOG_ERROR, "nonsense samplerate\n"); return AVERROR_INVALIDDATA; } nb_samples = avio_rl32(s->pb); if (!nb_samples) { av_log(s, AV_LOG_ERROR, "invalid number of samples\n"); return AVERROR_INVALIDDATA; } crc = ffio_get_checksum(s->pb) ^ UINT32_MAX; if (crc != avio_rl32(s->pb)) { av_log(s, AV_LOG_ERROR, "Header CRC error\n"); return AVERROR_INVALIDDATA; } c->frame_size = samplerate * 256 / 245; c->last_frame_size = nb_samples % c->frame_size; if (!c->last_frame_size) c->last_frame_size = c->frame_size; c->totalframes = nb_samples / c->frame_size + (c->last_frame_size < c->frame_size); c->currentframe = 0; if(c->totalframes >= UINT_MAX/sizeof(uint32_t) || c->totalframes <= 0){ av_log(s, AV_LOG_ERROR, "totalframes %d invalid\n", c->totalframes); return AVERROR_INVALIDDATA; } st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); avpriv_set_pts_info(st, 64, 1, samplerate); st->start_time = 0; st->duration = nb_samples; framepos = avio_tell(s->pb) + 4*c->totalframes + 4; st->codec->extradata_size = avio_tell(s->pb) - start_offset; st->codec->extradata = av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); if (!st->codec->extradata) { st->codec->extradata_size = 0; return AVERROR(ENOMEM); } avio_seek(s->pb, start_offset, SEEK_SET); avio_read(s->pb, st->codec->extradata, st->codec->extradata_size); ffio_init_checksum(s->pb, tta_check_crc, UINT32_MAX); for (i = 0; i < c->totalframes; i++) { uint32_t size = avio_rl32(s->pb); av_add_index_entry(st, framepos, i * c->frame_size, size, 0, AVINDEX_KEYFRAME); framepos += size; } crc = ffio_get_checksum(s->pb) ^ UINT32_MAX; if (crc != avio_rl32(s->pb)) { av_log(s, AV_LOG_ERROR, "Seek table CRC error\n"); return AVERROR_INVALIDDATA; } st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_id = AV_CODEC_ID_TTA; st->codec->channels = channels; st->codec->sample_rate = samplerate; st->codec->bits_per_coded_sample = bps; return 0; }
static int parse_keyframes_index(AVFormatContext *s, AVIOContext *ioc, AVStream *vstream, int64_t max_pos) { FLVContext *flv = s->priv_data; unsigned int timeslen = 0, fileposlen = 0, i; char str_val[256]; int64_t *times = NULL; int64_t *filepositions = NULL; int ret = AVERROR(ENOSYS); int64_t initial_pos = avio_tell(ioc); if(vstream->nb_index_entries>0) { av_log(s, AV_LOG_WARNING, "Skiping duplicate index\n"); return 0; } if (s->flags & AVFMT_FLAG_IGNIDX) return 0; while (avio_tell(ioc) < max_pos - 2 && amf_get_string(ioc, str_val, sizeof(str_val)) > 0) { int64_t** current_array; unsigned int arraylen; // Expect array object in context if (avio_r8(ioc) != AMF_DATA_TYPE_ARRAY) break; arraylen = avio_rb32(ioc); if(arraylen>>28) break; if (!strcmp(KEYFRAMES_TIMESTAMP_TAG , str_val) && !times) { current_array= × timeslen= arraylen; } else if (!strcmp(KEYFRAMES_BYTEOFFSET_TAG, str_val) && !filepositions) { current_array= &filepositions; fileposlen= arraylen; } else // unexpected metatag inside keyframes, will not use such metadata for indexing break; if (!(*current_array = av_mallocz(sizeof(**current_array) * arraylen))) { ret = AVERROR(ENOMEM); goto finish; } for (i = 0; i < arraylen && avio_tell(ioc) < max_pos - 1; i++) { if (avio_r8(ioc) != AMF_DATA_TYPE_NUMBER) goto invalid; current_array[0][i] = av_int2double(avio_rb64(ioc)); } if (times && filepositions) { // All done, exiting at a position allowing amf_parse_object // to finish parsing the object ret = 0; break; } } if (timeslen == fileposlen && fileposlen>1 && max_pos <= filepositions[0]) { for (i = 0; i < fileposlen; i++) { av_add_index_entry(vstream, filepositions[i], times[i]*1000, 0, 0, AVINDEX_KEYFRAME); if (i < 2) { flv->validate_index[i].pos = filepositions[i]; flv->validate_index[i].dts = times[i] * 1000; flv->validate_count = i + 1; } } } else { invalid: av_log(s, AV_LOG_WARNING, "Invalid keyframes object, skipping.\n"); } finish: av_freep(×); av_freep(&filepositions); avio_seek(ioc, initial_pos, SEEK_SET); return ret; }
static int read_header(AVFormatContext *s, AVFormatParameters *ap) { BinkDemuxContext *bink = s->priv_data; AVIOContext *pb = s->pb; uint32_t fps_num, fps_den; AVStream *vst, *ast; unsigned int i; uint32_t pos, next_pos; uint16_t flags; int keyframe; vst = av_new_stream(s, 0); if (!vst) return AVERROR(ENOMEM); vst->codec->codec_tag = avio_rl32(pb); bink->file_size = avio_rl32(pb) + 8; vst->duration = avio_rl32(pb); if (vst->duration > 1000000) { av_log(s, AV_LOG_ERROR, "invalid header: more than 1000000 frames\n"); return AVERROR(EIO); } if (avio_rl32(pb) > bink->file_size) { av_log(s, AV_LOG_ERROR, "invalid header: largest frame size greater than file size\n"); return AVERROR(EIO); } avio_seek(pb, 4, SEEK_CUR); vst->codec->width = avio_rl32(pb); vst->codec->height = avio_rl32(pb); fps_num = avio_rl32(pb); fps_den = avio_rl32(pb); if (fps_num == 0 || fps_den == 0) { av_log(s, AV_LOG_ERROR, "invalid header: invalid fps (%d/%d)\n", fps_num, fps_den); return AVERROR(EIO); } av_set_pts_info(vst, 64, fps_den, fps_num); vst->codec->codec_type = AVMEDIA_TYPE_VIDEO; vst->codec->codec_id = CODEC_ID_BINKVIDEO; vst->codec->extradata = av_mallocz(4 + FF_INPUT_BUFFER_PADDING_SIZE); vst->codec->extradata_size = 4; avio_read(pb, vst->codec->extradata, 4); bink->num_audio_tracks = avio_rl32(pb); if (bink->num_audio_tracks > BINK_MAX_AUDIO_TRACKS) { av_log(s, AV_LOG_ERROR, "invalid header: more than "AV_STRINGIFY(BINK_MAX_AUDIO_TRACKS)" audio tracks (%d)\n", bink->num_audio_tracks); return AVERROR(EIO); } if (bink->num_audio_tracks) { avio_seek(pb, 4 * bink->num_audio_tracks, SEEK_CUR); for (i = 0; i < bink->num_audio_tracks; i++) { ast = av_new_stream(s, 1); if (!ast) return AVERROR(ENOMEM); ast->codec->codec_type = AVMEDIA_TYPE_AUDIO; ast->codec->codec_tag = vst->codec->codec_tag; ast->codec->sample_rate = avio_rl16(pb); av_set_pts_info(ast, 64, 1, ast->codec->sample_rate); flags = avio_rl16(pb); ast->codec->codec_id = flags & BINK_AUD_USEDCT ? CODEC_ID_BINKAUDIO_DCT : CODEC_ID_BINKAUDIO_RDFT; ast->codec->channels = flags & BINK_AUD_STEREO ? 2 : 1; } for (i = 0; i < bink->num_audio_tracks; i++) s->streams[i + 1]->id = avio_rl32(pb); } /* frame index table */ next_pos = avio_rl32(pb); for (i = 0; i < vst->duration; i++) { pos = next_pos; if (i == vst->duration - 1) { next_pos = bink->file_size; keyframe = 0; } else { next_pos = avio_rl32(pb); keyframe = pos & 1; } pos &= ~1; next_pos &= ~1; if (next_pos <= pos) { av_log(s, AV_LOG_ERROR, "invalid frame index table\n"); return AVERROR(EIO); } av_add_index_entry(vst, pos, i, next_pos - pos, 0, keyframe ? AVINDEX_KEYFRAME : 0); } avio_seek(pb, 4, SEEK_CUR); bink->current_track = -1; return 0; }
static int mv_read_header(AVFormatContext *avctx) { MvContext *mv = avctx->priv_data; AVIOContext *pb = avctx->pb; AVStream *ast = NULL, *vst = NULL; //initialization to suppress warning int version, i; int ret; avio_skip(pb, 4); version = avio_rb16(pb); if (version == 2) { uint64_t timestamp; int v; avio_skip(pb, 22); /* allocate audio track first to prevent unnecessary seeking * (audio packet always precede video packet for a given frame) */ ast = avformat_new_stream(avctx, NULL); if (!ast) return AVERROR(ENOMEM); vst = avformat_new_stream(avctx, NULL); if (!vst) return AVERROR(ENOMEM); avpriv_set_pts_info(vst, 64, 1, 15); vst->codecpar->codec_type = AVMEDIA_TYPE_VIDEO; vst->avg_frame_rate = av_inv_q(vst->time_base); vst->nb_frames = avio_rb32(pb); v = avio_rb32(pb); switch (v) { case 1: vst->codecpar->codec_id = AV_CODEC_ID_MVC1; break; case 2: vst->codecpar->format = AV_PIX_FMT_ARGB; vst->codecpar->codec_id = AV_CODEC_ID_RAWVIDEO; break; default: avpriv_request_sample(avctx, "Video compression %i", v); break; } vst->codecpar->codec_tag = 0; vst->codecpar->width = avio_rb32(pb); vst->codecpar->height = avio_rb32(pb); avio_skip(pb, 12); ast->codecpar->codec_type = AVMEDIA_TYPE_AUDIO; ast->nb_frames = vst->nb_frames; ast->codecpar->sample_rate = avio_rb32(pb); if (ast->codecpar->sample_rate <= 0) { av_log(avctx, AV_LOG_ERROR, "Invalid sample rate %d\n", ast->codecpar->sample_rate); return AVERROR_INVALIDDATA; } avpriv_set_pts_info(ast, 33, 1, ast->codecpar->sample_rate); if (set_channels(avctx, ast, avio_rb32(pb)) < 0) return AVERROR_INVALIDDATA; v = avio_rb32(pb); if (v == AUDIO_FORMAT_SIGNED) { ast->codecpar->codec_id = AV_CODEC_ID_PCM_S16BE; } else { avpriv_request_sample(avctx, "Audio compression (format %i)", v); } avio_skip(pb, 12); var_read_metadata(avctx, "title", 0x80); var_read_metadata(avctx, "comment", 0x100); avio_skip(pb, 0x80); timestamp = 0; for (i = 0; i < vst->nb_frames; i++) { uint32_t pos = avio_rb32(pb); uint32_t asize = avio_rb32(pb); uint32_t vsize = avio_rb32(pb); avio_skip(pb, 8); av_add_index_entry(ast, pos, timestamp, asize, 0, AVINDEX_KEYFRAME); av_add_index_entry(vst, pos + asize, i, vsize, 0, AVINDEX_KEYFRAME); timestamp += asize / (ast->codecpar->channels * 2); } } else if (!version && avio_rb16(pb) == 3) { avio_skip(pb, 4); if ((ret = read_table(avctx, NULL, parse_global_var)) < 0) return ret; if (mv->nb_audio_tracks > 1) { avpriv_request_sample(avctx, "Multiple audio streams support"); return AVERROR_PATCHWELCOME; } else if (mv->nb_audio_tracks) { ast = avformat_new_stream(avctx, NULL); if (!ast) return AVERROR(ENOMEM); ast->codecpar->codec_type = AVMEDIA_TYPE_AUDIO; if ((read_table(avctx, ast, parse_audio_var)) < 0) return ret; if (mv->acompression == 100 && mv->aformat == AUDIO_FORMAT_SIGNED && ast->codecpar->bits_per_coded_sample == 16) { ast->codecpar->codec_id = AV_CODEC_ID_PCM_S16BE; } else { avpriv_request_sample(avctx, "Audio compression %i (format %i, sr %i)", mv->acompression, mv->aformat, ast->codecpar->bits_per_coded_sample); ast->codecpar->codec_id = AV_CODEC_ID_NONE; } if (ast->codecpar->channels <= 0) { av_log(avctx, AV_LOG_ERROR, "No valid channel count found.\n"); return AVERROR_INVALIDDATA; } } if (mv->nb_video_tracks > 1) { avpriv_request_sample(avctx, "Multiple video streams support"); return AVERROR_PATCHWELCOME; } else if (mv->nb_video_tracks) { vst = avformat_new_stream(avctx, NULL); if (!vst) return AVERROR(ENOMEM); vst->codecpar->codec_type = AVMEDIA_TYPE_VIDEO; if ((ret = read_table(avctx, vst, parse_video_var))<0) return ret; } if (mv->nb_audio_tracks) read_index(pb, ast); if (mv->nb_video_tracks) read_index(pb, vst); } else { avpriv_request_sample(avctx, "Version %i", version); return AVERROR_PATCHWELCOME; } return 0; }
int ff_voc_get_packet(AVFormatContext *s, AVPacket *pkt, AVStream *st, int max_size) { VocDecContext *voc = s->priv_data; AVCodecContext *dec = st->codec; AVIOContext *pb = s->pb; VocType type; int size, tmp_codec=-1; int sample_rate = 0; int channels = 1; int64_t duration; int ret; av_add_index_entry(st, avio_tell(pb), voc->pts, voc->remaining_size, 0, AVINDEX_KEYFRAME); while (!voc->remaining_size) { type = avio_r8(pb); if (type == VOC_TYPE_EOF) return AVERROR_EOF; voc->remaining_size = avio_rl24(pb); if (!voc->remaining_size) { if (!s->pb->seekable) return AVERROR(EIO); voc->remaining_size = avio_size(pb) - avio_tell(pb); } max_size -= 4; switch (type) { case VOC_TYPE_VOICE_DATA: if (!dec->sample_rate) { dec->sample_rate = 1000000 / (256 - avio_r8(pb)); if (sample_rate) dec->sample_rate = sample_rate; avpriv_set_pts_info(st, 64, 1, dec->sample_rate); dec->channels = channels; dec->bits_per_coded_sample = av_get_bits_per_sample(dec->codec_id); } else avio_skip(pb, 1); tmp_codec = avio_r8(pb); voc->remaining_size -= 2; max_size -= 2; channels = 1; break; case VOC_TYPE_VOICE_DATA_CONT: break; case VOC_TYPE_EXTENDED: sample_rate = avio_rl16(pb); avio_r8(pb); channels = avio_r8(pb) + 1; sample_rate = 256000000 / (channels * (65536 - sample_rate)); voc->remaining_size = 0; max_size -= 4; break; case VOC_TYPE_NEW_VOICE_DATA: if (!dec->sample_rate) { dec->sample_rate = avio_rl32(pb); avpriv_set_pts_info(st, 64, 1, dec->sample_rate); dec->bits_per_coded_sample = avio_r8(pb); dec->channels = avio_r8(pb); } else avio_skip(pb, 6); tmp_codec = avio_rl16(pb); avio_skip(pb, 4); voc->remaining_size -= 12; max_size -= 12; break; default: avio_skip(pb, voc->remaining_size); max_size -= voc->remaining_size; voc->remaining_size = 0; break; } } if (tmp_codec >= 0) { tmp_codec = ff_codec_get_id(ff_voc_codec_tags, tmp_codec); if (dec->codec_id == AV_CODEC_ID_NONE) dec->codec_id = tmp_codec; else if (dec->codec_id != tmp_codec) av_log(s, AV_LOG_WARNING, "Ignoring mid-stream change in audio codec\n"); if (dec->codec_id == AV_CODEC_ID_NONE) { if (s->audio_codec_id == AV_CODEC_ID_NONE) { av_log(s, AV_LOG_ERROR, "unknown codec tag\n"); return AVERROR(EINVAL); } av_log(s, AV_LOG_WARNING, "unknown codec tag\n"); } } dec->bit_rate = dec->sample_rate * dec->channels * dec->bits_per_coded_sample; if (max_size <= 0) max_size = 2048; size = FFMIN(voc->remaining_size, max_size); voc->remaining_size -= size; ret = av_get_packet(pb, pkt, size); pkt->dts = pkt->pts = voc->pts; duration = av_get_audio_frame_duration(st->codec, size); if (duration > 0 && voc->pts != AV_NOPTS_VALUE) voc->pts += duration; else voc->pts = AV_NOPTS_VALUE; return ret; }
int ff_img_read_packet(AVFormatContext *s1, AVPacket *pkt) { VideoDemuxData *s = s1->priv_data; char filename_bytes[1024]; char *filename = filename_bytes; int i, res; int size[3] = { 0 }, ret[3] = { 0 }; AVIOContext *f[3] = { NULL }; AVCodecParameters *par = s1->streams[0]->codecpar; if (!s->is_pipe) { /* loop over input */ if (s->loop && s->img_number > s->img_last) { s->img_number = s->img_first; } if (s->img_number > s->img_last) return AVERROR_EOF; if (s->pattern_type == PT_NONE) { av_strlcpy(filename_bytes, s->path, sizeof(filename_bytes)); } else if (s->use_glob) { #if HAVE_GLOB filename = s->globstate.gl_pathv[s->img_number]; #endif } else { if (av_get_frame_filename(filename_bytes, sizeof(filename_bytes), s->path, s->img_number) < 0 && s->img_number > 1) return AVERROR(EIO); } for (i = 0; i < 3; i++) { if (s1->pb && !strcmp(filename_bytes, s->path) && !s->loop && !s->split_planes) { f[i] = s1->pb; } else if (s1->io_open(s1, &f[i], filename, AVIO_FLAG_READ, NULL) < 0) { if (i >= 1) break; av_log(s1, AV_LOG_ERROR, "Could not open file : %s\n", filename); return AVERROR(EIO); } size[i] = avio_size(f[i]); if (!s->split_planes) break; filename[strlen(filename) - 1] = 'U' + i; } if (par->codec_id == AV_CODEC_ID_NONE) { AVProbeData pd = { 0 }; AVInputFormat *ifmt; uint8_t header[PROBE_BUF_MIN + AVPROBE_PADDING_SIZE]; int ret; int score = 0; ret = avio_read(f[0], header, PROBE_BUF_MIN); if (ret < 0) return ret; memset(header + ret, 0, sizeof(header) - ret); avio_skip(f[0], -ret); pd.buf = header; pd.buf_size = ret; pd.filename = filename; ifmt = av_probe_input_format3(&pd, 1, &score); if (ifmt && ifmt->read_packet == ff_img_read_packet && ifmt->raw_codec_id) par->codec_id = ifmt->raw_codec_id; } if (par->codec_id == AV_CODEC_ID_RAWVIDEO && !par->width) infer_size(&par->width, &par->height, size[0]); } else { f[0] = s1->pb; if (avio_feof(f[0]) && s->loop && s->is_pipe) avio_seek(f[0], 0, SEEK_SET); if (avio_feof(f[0])) return AVERROR_EOF; if (s->frame_size > 0) { size[0] = s->frame_size; } else if (!s1->streams[0]->parser) { size[0] = avio_size(s1->pb); } else { size[0] = 4096; } } res = av_new_packet(pkt, size[0] + size[1] + size[2]); if (res < 0) { goto fail; } pkt->stream_index = 0; pkt->flags |= AV_PKT_FLAG_KEY; if (s->ts_from_file) { struct stat img_stat; if (stat(filename, &img_stat)) { res = AVERROR(EIO); goto fail; } pkt->pts = (int64_t)img_stat.st_mtime; #if HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC if (s->ts_from_file == 2) pkt->pts = 1000000000*pkt->pts + img_stat.st_mtim.tv_nsec; #endif av_add_index_entry(s1->streams[0], s->img_number, pkt->pts, 0, 0, AVINDEX_KEYFRAME); } else if (!s->is_pipe) { pkt->pts = s->pts; } if (s->is_pipe) pkt->pos = avio_tell(f[0]); pkt->size = 0; for (i = 0; i < 3; i++) { if (f[i]) { ret[i] = avio_read(f[i], pkt->data + pkt->size, size[i]); if (s->loop && s->is_pipe && ret[i] == AVERROR_EOF) { if (avio_seek(f[i], 0, SEEK_SET) >= 0) { pkt->pos = 0; ret[i] = avio_read(f[i], pkt->data + pkt->size, size[i]); } } if (!s->is_pipe && f[i] != s1->pb) ff_format_io_close(s1, &f[i]); if (ret[i] > 0) pkt->size += ret[i]; } } if (ret[0] <= 0 || ret[1] < 0 || ret[2] < 0) { av_packet_unref(pkt); if (ret[0] < 0) { res = ret[0]; } else if (ret[1] < 0) { res = ret[1]; } else if (ret[2] < 0) { res = ret[2]; } else { res = AVERROR_EOF; } goto fail; } else { s->img_count++; s->img_number++; s->pts++; return 0; } fail: if (!s->is_pipe) { for (i = 0; i < 3; i++) { if (f[i] != s1->pb) ff_format_io_close(s1, &f[i]); } } return res; }
static int cine_read_header(AVFormatContext *avctx) { AVIOContext *pb = avctx->pb; AVStream *st; unsigned int version, compression, offImageHeader, offSetup, offImageOffsets, biBitCount, length, CFA; int vflip; char *description; uint64_t i; st = avformat_new_stream(avctx, NULL); if (!st) return AVERROR(ENOMEM); st->codec->codec_type = AVMEDIA_TYPE_VIDEO; st->codec->codec_id = AV_CODEC_ID_RAWVIDEO; st->codec->codec_tag = 0; /* CINEFILEHEADER structure */ avio_skip(pb, 4); // Type, Headersize compression = avio_rl16(pb); version = avio_rl16(pb); if (version != 1) { avpriv_request_sample(avctx, "uknown version %i", version); return AVERROR_INVALIDDATA; } avio_skip(pb, 12); // FirstMovieImage, TotalImageCount, FirstImageNumber st->duration = avio_rl32(pb); offImageHeader = avio_rl32(pb); offSetup = avio_rl32(pb); offImageOffsets = avio_rl32(pb); avio_skip(pb, 8); // TriggerTime /* BITMAPINFOHEADER structure */ avio_seek(pb, offImageHeader, SEEK_SET); avio_skip(pb, 4); //biSize st->codec->width = avio_rl32(pb); st->codec->height = avio_rl32(pb); if (avio_rl16(pb) != 1) // biPlanes return AVERROR_INVALIDDATA; biBitCount = avio_rl16(pb); if (biBitCount != 8 && biBitCount != 16 && biBitCount != 24 && biBitCount != 48) { avpriv_request_sample(avctx, "unsupported biBitCount %i", biBitCount); return AVERROR_INVALIDDATA; } switch (avio_rl32(pb)) { case BMP_RGB: vflip = 0; break; case 0x100: /* BI_PACKED */ st->codec->codec_tag = MKTAG('B', 'I', 'T', 0); vflip = 1; break; default: avpriv_request_sample(avctx, "unknown bitmap compression"); return AVERROR_INVALIDDATA; } avio_skip(pb, 4); // biSizeImage /* parse SETUP structure */ avio_seek(pb, offSetup, SEEK_SET); avio_skip(pb, 140); // FrameRatae16 .. descriptionOld if (avio_rl16(pb) != 0x5453) return AVERROR_INVALIDDATA; length = avio_rl16(pb); if (length < 0x163C) { avpriv_request_sample(avctx, "short SETUP header"); return AVERROR_INVALIDDATA; } avio_skip(pb, 616); // Binning .. bFlipH if (!avio_rl32(pb) ^ vflip) { st->codec->extradata = av_strdup("BottomUp"); st->codec->extradata_size = 9; } avio_skip(pb, 4); // Grid avpriv_set_pts_info(st, 64, 1, avio_rl32(pb)); avio_skip(pb, 20); // Shutter .. bEnableColor set_metadata_int(&st->metadata, "camera_version", avio_rl32(pb), 0); set_metadata_int(&st->metadata, "firmware_version", avio_rl32(pb), 0); set_metadata_int(&st->metadata, "software_version", avio_rl32(pb), 0); set_metadata_int(&st->metadata, "recording_timezone", avio_rl32(pb), 0); CFA = avio_rl32(pb); set_metadata_int(&st->metadata, "brightness", avio_rl32(pb), 1); set_metadata_int(&st->metadata, "contrast", avio_rl32(pb), 1); set_metadata_int(&st->metadata, "gamma", avio_rl32(pb), 1); avio_skip(pb, 72); // Reserved1 .. WBView st->codec->bits_per_coded_sample = avio_rl32(pb); if (compression == CC_RGB) { if (biBitCount == 8) { st->codec->pix_fmt = AV_PIX_FMT_GRAY8; } else if (biBitCount == 16) { st->codec->pix_fmt = AV_PIX_FMT_GRAY16LE; } else if (biBitCount == 24) { st->codec->pix_fmt = AV_PIX_FMT_BGR24; } else if (biBitCount == 48) { st->codec->pix_fmt = AV_PIX_FMT_BGR48LE; } else { avpriv_request_sample(avctx, "unsupported biBitCount %i", biBitCount); return AVERROR_INVALIDDATA; } } else if (compression == CC_UNINT) { switch (CFA & 0xFFFFFF) { case CFA_BAYER: if (biBitCount == 8) { st->codec->pix_fmt = AV_PIX_FMT_BAYER_GBRG8; } else if (biBitCount == 16) { st->codec->pix_fmt = AV_PIX_FMT_BAYER_GBRG16LE; } else { avpriv_request_sample(avctx, "unsupported biBitCount %i", biBitCount); return AVERROR_INVALIDDATA; } break; case CFA_BAYERFLIP: if (biBitCount == 8) { st->codec->pix_fmt = AV_PIX_FMT_BAYER_RGGB8; } else if (biBitCount == 16) { st->codec->pix_fmt = AV_PIX_FMT_BAYER_RGGB16LE; } else { avpriv_request_sample(avctx, "unsupported biBitCount %i", biBitCount); return AVERROR_INVALIDDATA; } break; default: avpriv_request_sample(avctx, "unsupported Color Field Array (CFA) %i", CFA & 0xFFFFFF); return AVERROR_INVALIDDATA; } } else { //CC_LEAD avpriv_request_sample(avctx, "unsupported compression %i", compression); return AVERROR_INVALIDDATA; } avio_skip(pb, 668); // Conv8Min ... Sensor set_metadata_int(&st->metadata, "shutter_ns", avio_rl32(pb), 0); avio_skip(pb, 24); // EDRShutterNs ... ImHeightAcq #define DESCRIPTION_SIZE 4096 description = av_malloc(DESCRIPTION_SIZE + 1); if (!description) return AVERROR(ENOMEM); i = avio_get_str(pb, DESCRIPTION_SIZE, description, DESCRIPTION_SIZE + 1); if (i < DESCRIPTION_SIZE) avio_skip(pb, DESCRIPTION_SIZE - i); if (description[0]) av_dict_set(&st->metadata, "description", description, AV_DICT_DONT_STRDUP_VAL); else av_free(description); avio_skip(pb, 1176); // RisingEdge ... cmUser set_metadata_int(&st->metadata, "enable_crop", avio_rl32(pb), 1); set_metadata_int(&st->metadata, "crop_left", avio_rl32(pb), 1); set_metadata_int(&st->metadata, "crop_top", avio_rl32(pb), 1); set_metadata_int(&st->metadata, "crop_right", avio_rl32(pb), 1); set_metadata_int(&st->metadata, "crop_bottom", avio_rl32(pb), 1); /* parse image offsets */ avio_seek(pb, offImageOffsets, SEEK_SET); for (i = 0; i < st->duration; i++) av_add_index_entry(st, avio_rl64(pb), i, 0, 0, AVINDEX_KEYFRAME); return 0; }
static int pmp_header(AVFormatContext *s, AVFormatParameters *ap) { PMPContext *pmp = s->priv_data; AVIOContext *pb = s->pb; int tb_num, tb_den; int index_cnt; int audio_codec_id = CODEC_ID_NONE; int srate, channels; int i; uint64_t pos; AVStream *vst = av_new_stream(s, 0); if (!vst) return AVERROR(ENOMEM); vst->codec->codec_type = AVMEDIA_TYPE_VIDEO; avio_skip(pb, 8); switch (avio_rl32(pb)) { case 0: vst->codec->codec_id = CODEC_ID_MPEG4; break; case 1: vst->codec->codec_id = CODEC_ID_H264; break; default: av_log(s, AV_LOG_ERROR, "Unsupported video format\n"); break; } index_cnt = avio_rl32(pb); vst->codec->width = avio_rl32(pb); vst->codec->height = avio_rl32(pb); tb_num = avio_rl32(pb); tb_den = avio_rl32(pb); av_set_pts_info(vst, 32, tb_num, tb_den); vst->nb_frames = index_cnt; vst->duration = index_cnt; switch (avio_rl32(pb)) { case 0: audio_codec_id = CODEC_ID_MP3; break; case 1: av_log(s, AV_LOG_ERROR, "AAC not yet correctly supported\n"); audio_codec_id = CODEC_ID_AAC; break; default: av_log(s, AV_LOG_ERROR, "Unsupported audio format\n"); break; } pmp->num_streams = avio_rl16(pb) + 1; avio_skip(pb, 10); srate = avio_rl32(pb); channels = avio_rl32(pb) + 1; for (i = 1; i < pmp->num_streams; i++) { AVStream *ast = av_new_stream(s, i); if (!ast) return AVERROR(ENOMEM); ast->codec->codec_type = AVMEDIA_TYPE_AUDIO; ast->codec->codec_id = audio_codec_id; ast->codec->channels = channels; ast->codec->sample_rate = srate; av_set_pts_info(ast, 32, 1, srate); } pos = avio_tell(pb) + 4*index_cnt; for (i = 0; i < index_cnt; i++) { int size = avio_rl32(pb); int flags = size & 1 ? AVINDEX_KEYFRAME : 0; size >>= 1; av_add_index_entry(vst, pos, i, size, 0, flags); pos += size; } return 0; }
static int read_header(AVFormatContext *s) { BinkDemuxContext *bink = s->priv_data; AVIOContext *pb = s->pb; uint32_t fps_num, fps_den; AVStream *vst, *ast; unsigned int i; uint32_t pos, next_pos; uint16_t flags; int keyframe; int ret; vst = avformat_new_stream(s, NULL); if (!vst) return AVERROR(ENOMEM); vst->codecpar->codec_tag = avio_rl32(pb); bink->file_size = avio_rl32(pb) + 8; vst->duration = avio_rl32(pb); if (vst->duration > 1000000) { av_log(s, AV_LOG_ERROR, "invalid header: more than 1000000 frames\n"); return AVERROR(EIO); } if (avio_rl32(pb) > bink->file_size) { av_log(s, AV_LOG_ERROR, "invalid header: largest frame size greater than file size\n"); return AVERROR(EIO); } avio_skip(pb, 4); vst->codecpar->width = avio_rl32(pb); vst->codecpar->height = avio_rl32(pb); fps_num = avio_rl32(pb); fps_den = avio_rl32(pb); if (fps_num == 0 || fps_den == 0) { av_log(s, AV_LOG_ERROR, "invalid header: invalid fps (%"PRIu32"/%"PRIu32")\n", fps_num, fps_den); return AVERROR(EIO); } avpriv_set_pts_info(vst, 64, fps_den, fps_num); vst->avg_frame_rate = av_inv_q(vst->time_base); vst->codecpar->codec_type = AVMEDIA_TYPE_VIDEO; vst->codecpar->codec_id = AV_CODEC_ID_BINKVIDEO; if ((vst->codecpar->codec_tag & 0xFFFFFF) == MKTAG('K', 'B', '2', 0)) { av_log(s, AV_LOG_WARNING, "Bink 2 video is not implemented\n"); vst->codecpar->codec_id = AV_CODEC_ID_NONE; } if (ff_get_extradata(vst->codecpar, pb, 4) < 0) return AVERROR(ENOMEM); bink->num_audio_tracks = avio_rl32(pb); if (bink->num_audio_tracks > BINK_MAX_AUDIO_TRACKS) { av_log(s, AV_LOG_ERROR, "invalid header: more than "AV_STRINGIFY(BINK_MAX_AUDIO_TRACKS)" audio tracks (%"PRIu32")\n", bink->num_audio_tracks); return AVERROR(EIO); } if (bink->num_audio_tracks) { avio_skip(pb, 4 * bink->num_audio_tracks); for (i = 0; i < bink->num_audio_tracks; i++) { ast = avformat_new_stream(s, NULL); if (!ast) return AVERROR(ENOMEM); ast->codecpar->codec_type = AVMEDIA_TYPE_AUDIO; ast->codecpar->codec_tag = 0; ast->codecpar->sample_rate = avio_rl16(pb); avpriv_set_pts_info(ast, 64, 1, ast->codecpar->sample_rate); flags = avio_rl16(pb); ast->codecpar->codec_id = flags & BINK_AUD_USEDCT ? AV_CODEC_ID_BINKAUDIO_DCT : AV_CODEC_ID_BINKAUDIO_RDFT; if (flags & BINK_AUD_STEREO) { ast->codecpar->channels = 2; ast->codecpar->channel_layout = AV_CH_LAYOUT_STEREO; } else { ast->codecpar->channels = 1; ast->codecpar->channel_layout = AV_CH_LAYOUT_MONO; } if (ff_alloc_extradata(ast->codecpar, 4)) return AVERROR(ENOMEM); AV_WL32(ast->codecpar->extradata, vst->codecpar->codec_tag); } for (i = 0; i < bink->num_audio_tracks; i++) s->streams[i + 1]->id = avio_rl32(pb); } /* frame index table */ next_pos = avio_rl32(pb); for (i = 0; i < vst->duration; i++) { pos = next_pos; if (i == vst->duration - 1) { next_pos = bink->file_size; keyframe = 0; } else { next_pos = avio_rl32(pb); keyframe = pos & 1; } pos &= ~1; next_pos &= ~1; if (next_pos <= pos) { av_log(s, AV_LOG_ERROR, "invalid frame index table\n"); return AVERROR(EIO); } if ((ret = av_add_index_entry(vst, pos, i, next_pos - pos, 0, keyframe ? AVINDEX_KEYFRAME : 0)) < 0) return ret; } if (vst->index_entries) avio_seek(pb, vst->index_entries[0].pos, SEEK_SET); else avio_skip(pb, 4); bink->current_track = -1; return 0; }
static int rpl_read_header(AVFormatContext *s, AVFormatParameters *ap) { ByteIOContext *pb = s->pb; RPLContext *rpl = s->priv_data; AVStream *vst = NULL, *ast = NULL; int total_audio_size; int error = 0; uint32_t i; int32_t audio_format, chunk_catalog_offset, number_of_chunks; AVRational fps; char line[RPL_LINE_LENGTH]; // The header for RPL/ARMovie files is 21 lines of text // containing the various header fields. The fields are always // in the same order, and other text besides the first // number usually isn't important. // (The spec says that there exists some significance // for the text in a few cases; samples needed.) error |= read_line(pb, line, sizeof(line)); // ARMovie error |= read_line(pb, line, sizeof(line)); // movie name av_metadata_set2(&s->metadata, "title" , line, 0); error |= read_line(pb, line, sizeof(line)); // date/copyright av_metadata_set2(&s->metadata, "copyright", line, 0); error |= read_line(pb, line, sizeof(line)); // author and other av_metadata_set2(&s->metadata, "author" , line, 0); // video headers vst = av_new_stream(s, 0); if (!vst) return AVERROR(ENOMEM); vst->codec->codec_type = AVMEDIA_TYPE_VIDEO; vst->codec->codec_tag = read_line_and_int(pb, &error); // video format vst->codec->width = read_line_and_int(pb, &error); // video width vst->codec->height = read_line_and_int(pb, &error); // video height vst->codec->bits_per_coded_sample = read_line_and_int(pb, &error); // video bits per sample error |= read_line(pb, line, sizeof(line)); // video frames per second fps = read_fps(line, &error); av_set_pts_info(vst, 32, fps.den, fps.num); // Figure out the video codec switch (vst->codec->codec_tag) { #if 0 case 122: vst->codec->codec_id = CODEC_ID_ESCAPE122; break; #endif case 124: vst->codec->codec_id = CODEC_ID_ESCAPE124; // The header is wrong here, at least sometimes vst->codec->bits_per_coded_sample = 16; break; #if 0 case 130: vst->codec->codec_id = CODEC_ID_ESCAPE130; break; #endif default: av_log(s, AV_LOG_WARNING, "RPL video format %i not supported yet!\n", vst->codec->codec_tag); vst->codec->codec_id = CODEC_ID_NONE; } // Audio headers // ARMovie supports multiple audio tracks; I don't have any // samples, though. This code will ignore additional tracks. audio_format = read_line_and_int(pb, &error); // audio format ID if (audio_format) { ast = av_new_stream(s, 0); if (!ast) return AVERROR(ENOMEM); ast->codec->codec_type = AVMEDIA_TYPE_AUDIO; ast->codec->codec_tag = audio_format; ast->codec->sample_rate = read_line_and_int(pb, &error); // audio bitrate ast->codec->channels = read_line_and_int(pb, &error); // number of audio channels ast->codec->bits_per_coded_sample = read_line_and_int(pb, &error); // audio bits per sample // At least one sample uses 0 for ADPCM, which is really 4 bits // per sample. if (ast->codec->bits_per_coded_sample == 0) ast->codec->bits_per_coded_sample = 4; ast->codec->bit_rate = ast->codec->sample_rate * ast->codec->bits_per_coded_sample * ast->codec->channels; ast->codec->codec_id = CODEC_ID_NONE; switch (audio_format) { case 1: if (ast->codec->bits_per_coded_sample == 16) { // 16-bit audio is always signed ast->codec->codec_id = CODEC_ID_PCM_S16LE; break; } // There are some other formats listed as legal per the spec; // samples needed. break; case 101: if (ast->codec->bits_per_coded_sample == 8) { // The samples with this kind of audio that I have // are all unsigned. ast->codec->codec_id = CODEC_ID_PCM_U8; break; } else if (ast->codec->bits_per_coded_sample == 4) { ast->codec->codec_id = CODEC_ID_ADPCM_IMA_EA_SEAD; break; } break; } if (ast->codec->codec_id == CODEC_ID_NONE) { av_log(s, AV_LOG_WARNING, "RPL audio format %i not supported yet!\n", audio_format); } av_set_pts_info(ast, 32, 1, ast->codec->bit_rate); } else { for (i = 0; i < 3; i++) error |= read_line(pb, line, sizeof(line)); } rpl->frames_per_chunk = read_line_and_int(pb, &error); // video frames per chunk if (rpl->frames_per_chunk > 1 && vst->codec->codec_tag != 124) av_log(s, AV_LOG_WARNING, "Don't know how to split frames for video format %i. " "Video stream will be broken!\n", vst->codec->codec_tag); number_of_chunks = read_line_and_int(pb, &error); // number of chunks in the file // The number in the header is actually the index of the last chunk. number_of_chunks++; error |= read_line(pb, line, sizeof(line)); // "even" chunk size in bytes error |= read_line(pb, line, sizeof(line)); // "odd" chunk size in bytes chunk_catalog_offset = // offset of the "chunk catalog" read_line_and_int(pb, &error); // (file index) error |= read_line(pb, line, sizeof(line)); // offset to "helpful" sprite error |= read_line(pb, line, sizeof(line)); // size of "helpful" sprite error |= read_line(pb, line, sizeof(line)); // offset to key frame list // Read the index url_fseek(pb, chunk_catalog_offset, SEEK_SET); total_audio_size = 0; for (i = 0; i < number_of_chunks; i++) { int64_t offset, video_size, audio_size; error |= read_line(pb, line, sizeof(line)); if (3 != sscanf(line, "%"PRId64" , %"PRId64" ; %"PRId64, &offset, &video_size, &audio_size)) error = -1; av_add_index_entry(vst, offset, i * rpl->frames_per_chunk, video_size, rpl->frames_per_chunk, 0); if (ast) av_add_index_entry(ast, offset + video_size, total_audio_size, audio_size, audio_size * 8, 0); total_audio_size += audio_size * 8; } if (error) return AVERROR(EIO); return 0; }
static int film_read_header(AVFormatContext *s) { FilmDemuxContext *film = s->priv_data; AVIOContext *pb = s->pb; AVStream *st; unsigned char scratch[256]; int i, ret; unsigned int data_offset; unsigned int audio_frame_counter; unsigned int video_frame_counter; film->sample_table = NULL; /* load the main FILM header */ if (avio_read(pb, scratch, 16) != 16) return AVERROR(EIO); data_offset = AV_RB32(&scratch[4]); film->version = AV_RB32(&scratch[8]); /* load the FDSC chunk */ if (film->version == 0) { /* special case for Lemmings .film files; 20-byte header */ if (avio_read(pb, scratch, 20) != 20) return AVERROR(EIO); /* make some assumptions about the audio parameters */ film->audio_type = AV_CODEC_ID_PCM_S8; film->audio_samplerate = 22050; film->audio_channels = 1; film->audio_bits = 8; } else { /* normal Saturn .cpk files; 32-byte header */ if (avio_read(pb, scratch, 32) != 32) return AVERROR(EIO); film->audio_samplerate = AV_RB16(&scratch[24]); film->audio_channels = scratch[21]; film->audio_bits = scratch[22]; if (scratch[23] == 2 && film->audio_channels > 0) film->audio_type = AV_CODEC_ID_ADPCM_ADX; else if (film->audio_channels > 0) { if (film->audio_bits == 8) film->audio_type = AV_CODEC_ID_PCM_S8_PLANAR; else if (film->audio_bits == 16) film->audio_type = AV_CODEC_ID_PCM_S16BE_PLANAR; else film->audio_type = AV_CODEC_ID_NONE; } else film->audio_type = AV_CODEC_ID_NONE; } if (AV_RB32(&scratch[0]) != FDSC_TAG) return AVERROR_INVALIDDATA; if (AV_RB32(&scratch[8]) == CVID_TAG) { film->video_type = AV_CODEC_ID_CINEPAK; } else if (AV_RB32(&scratch[8]) == RAW_TAG) { film->video_type = AV_CODEC_ID_RAWVIDEO; } else { film->video_type = AV_CODEC_ID_NONE; } /* initialize the decoder streams */ if (film->video_type) { st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); film->video_stream_index = st->index; st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO; st->codecpar->codec_id = film->video_type; st->codecpar->codec_tag = 0; /* no fourcc */ st->codecpar->width = AV_RB32(&scratch[16]); st->codecpar->height = AV_RB32(&scratch[12]); if (film->video_type == AV_CODEC_ID_RAWVIDEO) { if (scratch[20] == 24) { st->codecpar->format = AV_PIX_FMT_RGB24; } else { av_log(s, AV_LOG_ERROR, "raw video is using unhandled %dbpp\n", scratch[20]); return -1; } } } if (film->audio_type) { st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); film->audio_stream_index = st->index; st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO; st->codecpar->codec_id = film->audio_type; st->codecpar->codec_tag = 1; st->codecpar->channels = film->audio_channels; st->codecpar->sample_rate = film->audio_samplerate; if (film->audio_type == AV_CODEC_ID_ADPCM_ADX) { st->codecpar->bits_per_coded_sample = 18 * 8 / 32; st->codecpar->block_align = st->codecpar->channels * 18; st->need_parsing = AVSTREAM_PARSE_FULL; } else { st->codecpar->bits_per_coded_sample = film->audio_bits; st->codecpar->block_align = st->codecpar->channels * st->codecpar->bits_per_coded_sample / 8; } st->codecpar->bit_rate = st->codecpar->channels * st->codecpar->sample_rate * st->codecpar->bits_per_coded_sample; } /* load the sample table */ if (avio_read(pb, scratch, 16) != 16) return AVERROR(EIO); if (AV_RB32(&scratch[0]) != STAB_TAG) return AVERROR_INVALIDDATA; film->base_clock = AV_RB32(&scratch[8]); film->sample_count = AV_RB32(&scratch[12]); if(film->sample_count >= UINT_MAX / sizeof(film_sample)) return -1; film->sample_table = av_malloc_array(film->sample_count, sizeof(film_sample)); if (!film->sample_table) return AVERROR(ENOMEM); for (i = 0; i < s->nb_streams; i++) { st = s->streams[i]; if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) avpriv_set_pts_info(st, 33, 1, film->base_clock); else avpriv_set_pts_info(st, 64, 1, film->audio_samplerate); } audio_frame_counter = video_frame_counter = 0; for (i = 0; i < film->sample_count; i++) { /* load the next sample record and transfer it to an internal struct */ if (avio_read(pb, scratch, 16) != 16) { ret = AVERROR(EIO); goto fail; } film->sample_table[i].sample_offset = data_offset + AV_RB32(&scratch[0]); film->sample_table[i].sample_size = AV_RB32(&scratch[4]); if (film->sample_table[i].sample_size > INT_MAX / 4) { ret = AVERROR_INVALIDDATA; goto fail; } if (AV_RB32(&scratch[8]) == 0xFFFFFFFF) { film->sample_table[i].stream = film->audio_stream_index; film->sample_table[i].pts = audio_frame_counter; if (film->audio_type == AV_CODEC_ID_ADPCM_ADX) audio_frame_counter += (film->sample_table[i].sample_size * 32 / (18 * film->audio_channels)); else if (film->audio_type != AV_CODEC_ID_NONE) audio_frame_counter += (film->sample_table[i].sample_size / (film->audio_channels * film->audio_bits / 8)); } else { film->sample_table[i].stream = film->video_stream_index; film->sample_table[i].pts = AV_RB32(&scratch[8]) & 0x7FFFFFFF; film->sample_table[i].keyframe = (scratch[8] & 0x80) ? AVINDEX_KEYFRAME : 0; video_frame_counter++; if (film->video_type) av_add_index_entry(s->streams[film->video_stream_index], film->sample_table[i].sample_offset, film->sample_table[i].pts, film->sample_table[i].sample_size, 0, film->sample_table[i].keyframe); } } if (film->audio_type) s->streams[film->audio_stream_index]->duration = audio_frame_counter; if (film->video_type) s->streams[film->video_stream_index]->duration = video_frame_counter; film->current_sample = 0; return 0; fail: film_read_close(s); return ret; }
static int xwma_read_header(AVFormatContext *s) { int64_t size; int ret; uint32_t dpds_table_size = 0; uint32_t *dpds_table = NULL; unsigned int tag; AVIOContext *pb = s->pb; AVStream *st; XWMAContext *xwma = s->priv_data; int i; /* The following code is mostly copied from wav.c, with some * minor alterations. */ /* check RIFF header */ tag = avio_rl32(pb); if (tag != MKTAG('R', 'I', 'F', 'F')) return -1; avio_rl32(pb); /* file size */ tag = avio_rl32(pb); if (tag != MKTAG('X', 'W', 'M', 'A')) return -1; /* parse fmt header */ tag = avio_rl32(pb); if (tag != MKTAG('f', 'm', 't', ' ')) return -1; size = avio_rl32(pb); st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); ret = ff_get_wav_header(pb, st->codec, size); if (ret < 0) return ret; st->need_parsing = AVSTREAM_PARSE_NONE; /* All xWMA files I have seen contained WMAv2 data. If there are files * using WMA Pro or some other codec, then we need to figure out the right * extradata for that. Thus, ask the user for feedback, but try to go on * anyway. */ if (st->codec->codec_id != AV_CODEC_ID_WMAV2) { avpriv_request_sample(s, "Unexpected codec (tag 0x04%x; id %d)", st->codec->codec_tag, st->codec->codec_id); } else { /* In all xWMA files I have seen, there is no extradata. But the WMA * codecs require extradata, so we provide our own fake extradata. * * First, check that there really was no extradata in the header. If * there was, then try to use it, after asking the user to provide a * sample of this unusual file. */ if (st->codec->extradata_size != 0) { /* Surprise, surprise: We *did* get some extradata. No idea * if it will work, but just go on and try it, after asking * the user for a sample. */ avpriv_request_sample(s, "Unexpected extradata (%d bytes)", st->codec->extradata_size); } else { st->codec->extradata_size = 6; st->codec->extradata = av_mallocz(6 + FF_INPUT_BUFFER_PADDING_SIZE); if (!st->codec->extradata) return AVERROR(ENOMEM); /* setup extradata with our experimentally obtained value */ st->codec->extradata[4] = 31; } } if (!st->codec->channels) { av_log(s, AV_LOG_WARNING, "Invalid channel count: %d\n", st->codec->channels); return AVERROR_INVALIDDATA; } if (!st->codec->bits_per_coded_sample) { av_log(s, AV_LOG_WARNING, "Invalid bits_per_coded_sample: %d\n", st->codec->bits_per_coded_sample); return AVERROR_INVALIDDATA; } /* set the sample rate */ avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate); /* parse the remaining RIFF chunks */ for (;;) { if (pb->eof_reached) { ret = AVERROR_EOF; goto end; } /* read next chunk tag */ tag = avio_rl32(pb); size = avio_rl32(pb); if (tag == MKTAG('d', 'a', 't', 'a')) { /* We assume that the data chunk comes last. */ break; } else if (tag == MKTAG('d','p','d','s')) { /* Quoting the MSDN xWMA docs on the dpds chunk: "Contains the * decoded packet cumulative data size array, each element is the * number of bytes accumulated after the corresponding xWMA packet * is decoded in order." * * Each packet has size equal to st->codec->block_align, which in * all cases I saw so far was always 2230. Thus, we can use the * dpds data to compute a seeking index. */ /* Error out if there is more than one dpds chunk. */ if (dpds_table) { av_log(s, AV_LOG_ERROR, "two dpds chunks present\n"); ret = AVERROR_INVALIDDATA; goto end; } /* Compute the number of entries in the dpds chunk. */ if (size & 3) { /* Size should be divisible by four */ av_log(s, AV_LOG_WARNING, "dpds chunk size %"PRId64" not divisible by 4\n", size); } dpds_table_size = size / 4; if (dpds_table_size == 0 || dpds_table_size >= INT_MAX / 4) { av_log(s, AV_LOG_ERROR, "dpds chunk size %"PRId64" invalid\n", size); return AVERROR_INVALIDDATA; } /* Allocate some temporary storage to keep the dpds data around. * for processing later on. */ dpds_table = av_malloc(dpds_table_size * sizeof(uint32_t)); if (!dpds_table) { return AVERROR(ENOMEM); } for (i = 0; i < dpds_table_size; ++i) { dpds_table[i] = avio_rl32(pb); size -= 4; } } avio_skip(pb, size); } /* Determine overall data length */ if (size < 0) { ret = AVERROR_INVALIDDATA; goto end; } if (!size) { xwma->data_end = INT64_MAX; } else xwma->data_end = avio_tell(pb) + size; if (dpds_table && dpds_table_size) { int64_t cur_pos; const uint32_t bytes_per_sample = (st->codec->channels * st->codec->bits_per_coded_sample) >> 3; /* Estimate the duration from the total number of output bytes. */ const uint64_t total_decoded_bytes = dpds_table[dpds_table_size - 1]; if (!bytes_per_sample) { av_log(s, AV_LOG_ERROR, "Invalid bits_per_coded_sample %d for %d channels\n", st->codec->bits_per_coded_sample, st->codec->channels); ret = AVERROR_INVALIDDATA; goto end; } st->duration = total_decoded_bytes / bytes_per_sample; /* Use the dpds data to build a seek table. We can only do this after * we know the offset to the data chunk, as we need that to determine * the actual offset to each input block. * Note: If we allowed ourselves to assume that the data chunk always * follows immediately after the dpds block, we could of course guess * the data block's start offset already while reading the dpds chunk. * I decided against that, just in case other chunks ever are * discovered. */ cur_pos = avio_tell(pb); for (i = 0; i < dpds_table_size; ++i) { /* From the number of output bytes that would accumulate in the * output buffer after decoding the first (i+1) packets, we compute * an offset / timestamp pair. */ av_add_index_entry(st, cur_pos + (i+1) * st->codec->block_align, /* pos */ dpds_table[i] / bytes_per_sample, /* timestamp */ st->codec->block_align, /* size */ 0, /* duration */ AVINDEX_KEYFRAME); } } else if (st->codec->bit_rate) {
static int flv_read_packet(AVFormatContext *s, AVPacket *pkt) { FLVContext *flv = s->priv_data; int ret, i, type, size, flags; int stream_type=-1; int64_t next, pos; int64_t dts, pts = AV_NOPTS_VALUE; int av_uninit(channels); int av_uninit(sample_rate); AVStream *st = NULL; for(;; avio_skip(s->pb, 4)) { /* pkt size is repeated at end. skip it */ pos = avio_tell(s->pb); type = avio_r8(s->pb); size = avio_rb24(s->pb); dts = avio_rb24(s->pb); dts |= avio_r8(s->pb) << 24; av_dlog(s, "type:%d, size:%d, dts:%"PRId64"\n", type, size, dts); if (url_feof(s->pb)) return AVERROR_EOF; avio_skip(s->pb, 3); /* stream id, always 0 */ flags = 0; if (flv->validate_next < flv->validate_count) { int64_t validate_pos = flv->validate_index[flv->validate_next].pos; if (pos == validate_pos) { if (FFABS(dts - flv->validate_index[flv->validate_next].dts) <= VALIDATE_INDEX_TS_THRESH) { flv->validate_next++; } else { clear_index_entries(s, validate_pos); flv->validate_count = 0; } } else if (pos > validate_pos) { clear_index_entries(s, validate_pos); flv->validate_count = 0; } } if(size == 0) continue; next= size + avio_tell(s->pb); if (type == FLV_TAG_TYPE_AUDIO) { stream_type=FLV_STREAM_TYPE_AUDIO; flags = avio_r8(s->pb); size--; } else if (type == FLV_TAG_TYPE_VIDEO) { stream_type=FLV_STREAM_TYPE_VIDEO; flags = avio_r8(s->pb); size--; if ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_VIDEO_INFO_CMD) goto skip; } else if (type == FLV_TAG_TYPE_META) { if (size > 13+1+4 && dts == 0) { // Header-type metadata stuff flv_read_metabody(s, next); goto skip; } else if (dts != 0) { // Script-data "special" metadata frames - don't skip stream_type=FLV_STREAM_TYPE_DATA; } else { goto skip; } } else { av_log(s, AV_LOG_DEBUG, "skipping flv packet: type %d, size %d, flags %d\n", type, size, flags); skip: avio_seek(s->pb, next, SEEK_SET); continue; } /* skip empty data packets */ if (!size) continue; /* now find stream */ for(i=0; i<s->nb_streams; i++) { st = s->streams[i]; if (st->id == stream_type) break; } if(i == s->nb_streams) { av_log(s, AV_LOG_WARNING, "Stream discovered after head already parsed\n"); st = create_stream(s, stream_type, (int[]) { AVMEDIA_TYPE_VIDEO, AVMEDIA_TYPE_AUDIO, AVMEDIA_TYPE_DATA }[stream_type]); } av_dlog(s, "%d %X %d \n", stream_type, flags, st->discard); if( (st->discard >= AVDISCARD_NONKEY && !((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY || (stream_type == FLV_STREAM_TYPE_AUDIO))) ||(st->discard >= AVDISCARD_BIDIR && ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_DISP_INTER && (stream_type == FLV_STREAM_TYPE_VIDEO))) || st->discard >= AVDISCARD_ALL ) { avio_seek(s->pb, next, SEEK_SET); continue; } if ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY) av_add_index_entry(st, pos, dts, size, 0, AVINDEX_KEYFRAME); break; }
static int tta_read_header(AVFormatContext *s, AVFormatParameters *ap) { TTAContext *c = s->priv_data; AVStream *st; int i, channels, bps, samplerate, datalen, framelen; uint64_t framepos, start_offset; if (!av_dict_get(s->metadata, "", NULL, AV_DICT_IGNORE_SUFFIX)) ff_id3v1_read(s); start_offset = avio_tell(s->pb); if (avio_rl32(s->pb) != AV_RL32("TTA1")) return -1; // not tta file avio_skip(s->pb, 2); // FIXME: flags channels = avio_rl16(s->pb); bps = avio_rl16(s->pb); samplerate = avio_rl32(s->pb); if(samplerate <= 0 || samplerate > 1000000){ av_log(s, AV_LOG_ERROR, "nonsense samplerate\n"); return -1; } datalen = avio_rl32(s->pb); if(datalen < 0){ av_log(s, AV_LOG_ERROR, "nonsense datalen\n"); return -1; } avio_skip(s->pb, 4); // header crc framelen = samplerate*256/245; c->totalframes = datalen / framelen + ((datalen % framelen) ? 1 : 0); c->currentframe = 0; if(c->totalframes >= UINT_MAX/sizeof(uint32_t)){ av_log(s, AV_LOG_ERROR, "totalframes too large\n"); return -1; } st = av_new_stream(s, 0); if (!st) return AVERROR(ENOMEM); av_set_pts_info(st, 64, 1, samplerate); st->start_time = 0; st->duration = datalen; framepos = avio_tell(s->pb) + 4*c->totalframes + 4; for (i = 0; i < c->totalframes; i++) { uint32_t size = avio_rl32(s->pb); av_add_index_entry(st, framepos, i*framelen, size, 0, AVINDEX_KEYFRAME); framepos += size; } avio_skip(s->pb, 4); // seektable crc st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_id = CODEC_ID_TTA; st->codec->channels = channels; st->codec->sample_rate = samplerate; st->codec->bits_per_coded_sample = bps; st->codec->extradata_size = avio_tell(s->pb) - start_offset; if(st->codec->extradata_size+FF_INPUT_BUFFER_PADDING_SIZE <= (unsigned)st->codec->extradata_size){ //this check is redundant as avio_read should fail av_log(s, AV_LOG_ERROR, "extradata_size too large\n"); return -1; } st->codec->extradata = av_mallocz(st->codec->extradata_size+FF_INPUT_BUFFER_PADDING_SIZE); avio_seek(s->pb, start_offset, SEEK_SET); avio_read(s->pb, st->codec->extradata, st->codec->extradata_size); return 0; }
static int pmp_header(AVFormatContext *s) { PMPContext *pmp = s->priv_data; AVIOContext *pb = s->pb; int tb_num, tb_den; uint32_t index_cnt; int audio_codec_id = AV_CODEC_ID_NONE; int srate, channels; unsigned i; uint64_t pos; int64_t fsize = avio_size(pb); AVStream *vst = avformat_new_stream(s, NULL); if (!vst) return AVERROR(ENOMEM); vst->codec->codec_type = AVMEDIA_TYPE_VIDEO; avio_skip(pb, 8); switch (avio_rl32(pb)) { case 0: vst->codec->codec_id = AV_CODEC_ID_MPEG4; break; case 1: vst->codec->codec_id = AV_CODEC_ID_H264; break; default: av_log(s, AV_LOG_ERROR, "Unsupported video format\n"); break; } index_cnt = avio_rl32(pb); vst->codec->width = avio_rl32(pb); vst->codec->height = avio_rl32(pb); tb_num = avio_rl32(pb); tb_den = avio_rl32(pb); avpriv_set_pts_info(vst, 32, tb_num, tb_den); vst->nb_frames = index_cnt; vst->duration = index_cnt; switch (avio_rl32(pb)) { case 0: audio_codec_id = AV_CODEC_ID_MP3; break; case 1: av_log(s, AV_LOG_ERROR, "AAC not yet correctly supported\n"); audio_codec_id = AV_CODEC_ID_AAC; break; default: av_log(s, AV_LOG_ERROR, "Unsupported audio format\n"); break; } pmp->num_streams = avio_rl16(pb) + 1; avio_skip(pb, 10); srate = avio_rl32(pb); channels = avio_rl32(pb) + 1; pos = avio_tell(pb) + 4LL*index_cnt; for (i = 0; i < index_cnt; i++) { uint32_t size = avio_rl32(pb); int flags = size & 1 ? AVINDEX_KEYFRAME : 0; if (url_feof(pb)) { av_log(s, AV_LOG_FATAL, "Encountered EOF while reading index.\n"); return AVERROR_INVALIDDATA; } size >>= 1; if (size < 9 + 4*pmp->num_streams) { av_log(s, AV_LOG_ERROR, "Packet too small\n"); return AVERROR_INVALIDDATA; } av_add_index_entry(vst, pos, i, size, 0, flags); pos += size; if (fsize > 0 && i == 0 && pos > fsize) { av_log(s, AV_LOG_ERROR, "File ends before first packet\n"); return AVERROR_INVALIDDATA; } } for (i = 1; i < pmp->num_streams; i++) { AVStream *ast = avformat_new_stream(s, NULL); if (!ast) return AVERROR(ENOMEM); ast->codec->codec_type = AVMEDIA_TYPE_AUDIO; ast->codec->codec_id = audio_codec_id; ast->codec->channels = channels; ast->codec->sample_rate = srate; avpriv_set_pts_info(ast, 32, 1, srate); } return 0; }
static int read_part_of_packet(AVFormatContext *s, int64_t *pts, int *len, int *strid, int read_packet) { AVIOContext *pb = s->pb; PVAContext *pvactx = s->priv_data; int syncword, streamid, reserved, flags, length, pts_flag; int64_t pva_pts = AV_NOPTS_VALUE, startpos; recover: startpos = avio_tell(pb); syncword = avio_rb16(pb); streamid = avio_r8(pb); avio_r8(pb); /* counter not used */ reserved = avio_r8(pb); flags = avio_r8(pb); length = avio_rb16(pb); pts_flag = flags & 0x10; if (syncword != PVA_MAGIC) { pva_log(s, AV_LOG_ERROR, "invalid syncword\n"); return AVERROR(EIO); } if (streamid != PVA_VIDEO_PAYLOAD && streamid != PVA_AUDIO_PAYLOAD) { pva_log(s, AV_LOG_ERROR, "invalid streamid\n"); return AVERROR(EIO); } if (reserved != 0x55) { pva_log(s, AV_LOG_WARNING, "expected reserved byte to be 0x55\n"); } if (length > PVA_MAX_PAYLOAD_LENGTH) { pva_log(s, AV_LOG_ERROR, "invalid payload length %u\n", length); return AVERROR(EIO); } if (streamid == PVA_VIDEO_PAYLOAD && pts_flag) { pva_pts = avio_rb32(pb); length -= 4; } else if (streamid == PVA_AUDIO_PAYLOAD) { /* PVA Audio Packets either start with a signaled PES packet or * are a continuation of the previous PES packet. New PES packets * always start at the beginning of a PVA Packet, never somewhere in * the middle. */ if (!pvactx->continue_pes) { int pes_signal, pes_header_data_length, pes_packet_length, pes_flags; unsigned char pes_header_data[256]; pes_signal = avio_rb24(pb); avio_r8(pb); pes_packet_length = avio_rb16(pb); pes_flags = avio_rb16(pb); pes_header_data_length = avio_r8(pb); if (pes_signal != 1) { pva_log(s, AV_LOG_WARNING, "expected signaled PES packet, " "trying to recover\n"); avio_skip(pb, length - 9); if (!read_packet) return AVERROR(EIO); goto recover; } avio_read(pb, pes_header_data, pes_header_data_length); length -= 9 + pes_header_data_length; pes_packet_length -= 3 + pes_header_data_length; pvactx->continue_pes = pes_packet_length; if (pes_flags & 0x80 && (pes_header_data[0] & 0xf0) == 0x20) pva_pts = ff_parse_pes_pts(pes_header_data); } pvactx->continue_pes -= length; if (pvactx->continue_pes < 0) { pva_log(s, AV_LOG_WARNING, "audio data corruption\n"); pvactx->continue_pes = 0; } } if (pva_pts != AV_NOPTS_VALUE) av_add_index_entry(s->streams[streamid-1], startpos, pva_pts, 0, 0, AVINDEX_KEYFRAME); *pts = pva_pts; *len = length; *strid = streamid; return 0; }
static int wv_read_packet(AVFormatContext *s, AVPacket *pkt) { WVContext *wc = s->priv_data; int ret; int size, ver, off; if (url_feof(s->pb)) return AVERROR(EIO); if(wc->block_parsed){ if(wv_read_block_header(s, s->pb, 0) < 0) return -1; } off = wc->multichannel ? 4 : 0; if(av_new_packet(pkt, wc->blksize + WV_EXTRA_SIZE + off) < 0) return AVERROR(ENOMEM); if(wc->multichannel) AV_WL32(pkt->data, wc->blksize + WV_EXTRA_SIZE + 12); memcpy(pkt->data + off, wc->extra, WV_EXTRA_SIZE); ret = get_buffer(s->pb, pkt->data + WV_EXTRA_SIZE + off, wc->blksize); if(ret != wc->blksize){ av_free_packet(pkt); return AVERROR(EIO); } while(!(wc->flags & WV_END_BLOCK)){ if(get_le32(s->pb) != MKTAG('w', 'v', 'p', 'k')){ av_free_packet(pkt); return -1; } if((ret = av_append_packet(s->pb, pkt, 4)) < 0){ av_free_packet(pkt); return ret; } size = AV_RL32(pkt->data + pkt->size - 4); if(size < 24 || size > WV_BLOCK_LIMIT){ av_free_packet(pkt); av_log(s, AV_LOG_ERROR, "Incorrect block size %d\n", size); return -1; } wc->blksize = size; ver = get_le16(s->pb); if(ver < 0x402 || ver > 0x410){ av_free_packet(pkt); av_log(s, AV_LOG_ERROR, "Unsupported version %03X\n", ver); return -1; } get_byte(s->pb); // track no get_byte(s->pb); // track sub index wc->samples = get_le32(s->pb); // total samples in file wc->soff = get_le32(s->pb); // offset in samples of current block if((ret = av_append_packet(s->pb, pkt, WV_EXTRA_SIZE)) < 0){ av_free_packet(pkt); return ret; } memcpy(wc->extra, pkt->data + pkt->size - WV_EXTRA_SIZE, WV_EXTRA_SIZE); if(wv_read_block_header(s, s->pb, 1) < 0){ av_free_packet(pkt); return -1; } ret = av_append_packet(s->pb, pkt, wc->blksize); if(ret < 0){ av_free_packet(pkt); return ret; } } pkt->stream_index = 0; wc->block_parsed = 1; pkt->pts = wc->soff; av_add_index_entry(s->streams[0], wc->pos, pkt->pts, 0, 0, AVINDEX_KEYFRAME); return 0; }
static int ape_read_header(AVFormatContext * s, AVFormatParameters * ap) { AVIOContext *pb = s->pb; APEContext *ape = s->priv_data; AVStream *st; uint32_t tag; int i; int total_blocks; int64_t pts; /* Skip any leading junk such as id3v2 tags */ ape->junklength = avio_tell(pb); tag = avio_rl32(pb); if (tag != MKTAG('M', 'A', 'C', ' ')) return -1; ape->fileversion = avio_rl16(pb); if (ape->fileversion < APE_MIN_VERSION || ape->fileversion > APE_MAX_VERSION) { av_log(s, AV_LOG_ERROR, "Unsupported file version - %"PRId16".%02"PRId16"\n", ape->fileversion / 1000, (ape->fileversion % 1000) / 10); return -1; } if (ape->fileversion >= 3980) { ape->padding1 = avio_rl16(pb); ape->descriptorlength = avio_rl32(pb); ape->headerlength = avio_rl32(pb); ape->seektablelength = avio_rl32(pb); ape->wavheaderlength = avio_rl32(pb); ape->audiodatalength = avio_rl32(pb); ape->audiodatalength_high = avio_rl32(pb); ape->wavtaillength = avio_rl32(pb); avio_read(pb, ape->md5, 16); /* Skip any unknown bytes at the end of the descriptor. This is for future compatibility */ if (ape->descriptorlength > 52) avio_skip(pb, ape->descriptorlength - 52); /* Read header data */ ape->compressiontype = avio_rl16(pb); ape->formatflags = avio_rl16(pb); ape->blocksperframe = avio_rl32(pb); ape->finalframeblocks = avio_rl32(pb); ape->totalframes = avio_rl32(pb); ape->bps = avio_rl16(pb); ape->channels = avio_rl16(pb); ape->samplerate = avio_rl32(pb); } else { ape->descriptorlength = 0; ape->headerlength = 32; ape->compressiontype = avio_rl16(pb); ape->formatflags = avio_rl16(pb); ape->channels = avio_rl16(pb); ape->samplerate = avio_rl32(pb); ape->wavheaderlength = avio_rl32(pb); ape->wavtaillength = avio_rl32(pb); ape->totalframes = avio_rl32(pb); ape->finalframeblocks = avio_rl32(pb); if (ape->formatflags & MAC_FORMAT_FLAG_HAS_PEAK_LEVEL) { avio_skip(pb, 4); /* Skip the peak level */ ape->headerlength += 4; } if (ape->formatflags & MAC_FORMAT_FLAG_HAS_SEEK_ELEMENTS) { ape->seektablelength = avio_rl32(pb); ape->headerlength += 4; ape->seektablelength *= sizeof(int32_t); } else ape->seektablelength = ape->totalframes * sizeof(int32_t); if (ape->formatflags & MAC_FORMAT_FLAG_8_BIT) ape->bps = 8; else if (ape->formatflags & MAC_FORMAT_FLAG_24_BIT) ape->bps = 24; else ape->bps = 16; if (ape->fileversion >= 3950) ape->blocksperframe = 73728 * 4; else if (ape->fileversion >= 3900 || (ape->fileversion >= 3800 && ape->compressiontype >= 4000)) ape->blocksperframe = 73728; else ape->blocksperframe = 9216; /* Skip any stored wav header */ if (!(ape->formatflags & MAC_FORMAT_FLAG_CREATE_WAV_HEADER)) avio_skip(pb, ape->wavheaderlength); } if(!ape->totalframes){ av_log(s, AV_LOG_ERROR, "No frames in the file!\n"); return AVERROR(EINVAL); } if(ape->totalframes > UINT_MAX / sizeof(APEFrame)){ av_log(s, AV_LOG_ERROR, "Too many frames: %"PRIu32"\n", ape->totalframes); return -1; } if (ape->seektablelength && (ape->seektablelength / sizeof(*ape->seektable)) < ape->totalframes) { av_log(s, AV_LOG_ERROR, "Number of seek entries is less than number of frames: %ld vs. %"PRIu32"\n", ape->seektablelength / sizeof(*ape->seektable), ape->totalframes); return AVERROR_INVALIDDATA; } ape->frames = av_malloc(ape->totalframes * sizeof(APEFrame)); if(!ape->frames) return AVERROR(ENOMEM); ape->firstframe = ape->junklength + ape->descriptorlength + ape->headerlength + ape->seektablelength + ape->wavheaderlength; ape->currentframe = 0; ape->totalsamples = ape->finalframeblocks; if (ape->totalframes > 1) ape->totalsamples += ape->blocksperframe * (ape->totalframes - 1); if (ape->seektablelength > 0) { ape->seektable = av_malloc(ape->seektablelength); for (i = 0; i < ape->seektablelength / sizeof(uint32_t); i++) ape->seektable[i] = avio_rl32(pb); } ape->frames[0].pos = ape->firstframe; ape->frames[0].nblocks = ape->blocksperframe; ape->frames[0].skip = 0; for (i = 1; i < ape->totalframes; i++) { ape->frames[i].pos = ape->seektable[i] + ape->junklength; ape->frames[i].nblocks = ape->blocksperframe; ape->frames[i - 1].size = ape->frames[i].pos - ape->frames[i - 1].pos; ape->frames[i].skip = (ape->frames[i].pos - ape->frames[0].pos) & 3; } ape->frames[ape->totalframes - 1].size = ape->finalframeblocks * 4; ape->frames[ape->totalframes - 1].nblocks = ape->finalframeblocks; for (i = 0; i < ape->totalframes; i++) { if(ape->frames[i].skip){ ape->frames[i].pos -= ape->frames[i].skip; ape->frames[i].size += ape->frames[i].skip; } ape->frames[i].size = (ape->frames[i].size + 3) & ~3; } ape_dumpinfo(s, ape); /* try to read APE tags */ if (pb->seekable) { ff_ape_parse_tag(s); avio_seek(pb, 0, SEEK_SET); } av_log(s, AV_LOG_DEBUG, "Decoding file - v%d.%02d, compression level %"PRIu16"\n", ape->fileversion / 1000, (ape->fileversion % 1000) / 10, ape->compressiontype); /* now we are ready: build format streams */ st = av_new_stream(s, 0); if (!st) return -1; total_blocks = (ape->totalframes == 0) ? 0 : ((ape->totalframes - 1) * ape->blocksperframe) + ape->finalframeblocks; st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_id = CODEC_ID_APE; st->codec->codec_tag = MKTAG('A', 'P', 'E', ' '); st->codec->channels = ape->channels; st->codec->sample_rate = ape->samplerate; st->codec->bits_per_coded_sample = ape->bps; st->codec->frame_size = MAC_SUBFRAME_SIZE; st->nb_frames = ape->totalframes; st->start_time = 0; st->duration = total_blocks / MAC_SUBFRAME_SIZE; av_set_pts_info(st, 64, MAC_SUBFRAME_SIZE, ape->samplerate); st->codec->extradata = av_malloc(APE_EXTRADATA_SIZE); st->codec->extradata_size = APE_EXTRADATA_SIZE; AV_WL16(st->codec->extradata + 0, ape->fileversion); AV_WL16(st->codec->extradata + 2, ape->compressiontype); AV_WL16(st->codec->extradata + 4, ape->formatflags); pts = 0; for (i = 0; i < ape->totalframes; i++) { ape->frames[i].pts = pts; av_add_index_entry(st, ape->frames[i].pos, ape->frames[i].pts, 0, 0, AVINDEX_KEYFRAME); pts += ape->blocksperframe / MAC_SUBFRAME_SIZE; } return 0; }
static int tta_read_header(AVFormatContext *s) { TTAContext *c = s->priv_data; AVStream *st; int i, channels, bps, samplerate; uint64_t framepos, start_offset; uint32_t datalen; if (!av_dict_get(s->metadata, "", NULL, AV_DICT_IGNORE_SUFFIX)) ff_id3v1_read(s); start_offset = avio_tell(s->pb); if (avio_rl32(s->pb) != AV_RL32("TTA1")) return -1; // not tta file avio_skip(s->pb, 2); // FIXME: flags channels = avio_rl16(s->pb); bps = avio_rl16(s->pb); samplerate = avio_rl32(s->pb); if(samplerate <= 0 || samplerate > 1000000){ av_log(s, AV_LOG_ERROR, "nonsense samplerate\n"); return -1; } datalen = avio_rl32(s->pb); if (!datalen) { av_log(s, AV_LOG_ERROR, "invalid datalen\n"); return AVERROR_INVALIDDATA; } avio_skip(s->pb, 4); // header crc c->frame_size = samplerate * 256 / 245; c->last_frame_size = datalen % c->frame_size; if (!c->last_frame_size) c->last_frame_size = c->frame_size; c->totalframes = datalen / c->frame_size + (c->last_frame_size < c->frame_size); c->currentframe = 0; if(c->totalframes >= UINT_MAX/sizeof(uint32_t) || c->totalframes <= 0){ av_log(s, AV_LOG_ERROR, "totalframes %d invalid\n", c->totalframes); return -1; } st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); avpriv_set_pts_info(st, 64, 1, samplerate); st->start_time = 0; st->duration = datalen; framepos = avio_tell(s->pb) + 4*c->totalframes + 4; st->codec->extradata_size = avio_tell(s->pb) - start_offset; st->codec->extradata = av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); if (!st->codec->extradata) { st->codec->extradata_size = 0; return AVERROR(ENOMEM); } avio_seek(s->pb, start_offset, SEEK_SET); avio_read(s->pb, st->codec->extradata, st->codec->extradata_size); for (i = 0; i < c->totalframes; i++) { uint32_t size = avio_rl32(s->pb); av_add_index_entry(st, framepos, i * c->frame_size, size, 0, AVINDEX_KEYFRAME); framepos += size; } avio_skip(s->pb, 4); // seektable crc st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_id = AV_CODEC_ID_TTA; st->codec->channels = channels; st->codec->sample_rate = samplerate; st->codec->bits_per_coded_sample = bps; return 0; }