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 avs_read_packet(AVFormatContext * s, AVPacket * pkt) { AvsFormat *avs = s->priv_data; int sub_type = 0, size = 0; AvsBlockType type = AVS_NONE; int palette_size = 0; uint8_t palette[4 + 3 * 256]; int ret; if (avs->remaining_audio_size > 0) if (avs_read_audio_packet(s, pkt) > 0) return 0; while (1) { if (avs->remaining_frame_size <= 0) { if (!avio_rl16(s->pb)) /* found EOF */ return AVERROR(EIO); avs->remaining_frame_size = avio_rl16(s->pb) - 4; } while (avs->remaining_frame_size > 0) { sub_type = avio_r8(s->pb); type = avio_r8(s->pb); size = avio_rl16(s->pb); if (size < 4) return AVERROR_INVALIDDATA; avs->remaining_frame_size -= size; switch (type) { case AVS_PALETTE: if (size - 4 > sizeof(palette)) return AVERROR_INVALIDDATA; ret = avio_read(s->pb, palette, size - 4); if (ret < size - 4) return AVERROR(EIO); palette_size = size; break; case AVS_VIDEO: if (!avs->st_video) { avs->st_video = avformat_new_stream(s, NULL); if (avs->st_video == NULL) return AVERROR(ENOMEM); avs->st_video->codec->codec_type = AVMEDIA_TYPE_VIDEO; avs->st_video->codec->codec_id = CODEC_ID_AVS; avs->st_video->codec->width = avs->width; avs->st_video->codec->height = avs->height; avs->st_video->codec->bits_per_coded_sample=avs->bits_per_sample; avs->st_video->nb_frames = avs->nb_frames; avs->st_video->codec->time_base = (AVRational) { 1, avs->fps}; } return avs_read_video_packet(s, pkt, type, sub_type, size, palette, palette_size); case AVS_AUDIO: if (!avs->st_audio) { avs->st_audio = avformat_new_stream(s, NULL); if (avs->st_audio == NULL) return AVERROR(ENOMEM); avs->st_audio->codec->codec_type = AVMEDIA_TYPE_AUDIO; } avs->remaining_audio_size = size - 4; size = avs_read_audio_packet(s, pkt); if (size != 0) return size; break; default: avio_skip(s->pb, size - 4); } } } }
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; }
static int read_packet(AVFormatContext *s, AVPacket *pkt) { AVIOContext *pb = s->pb; C93DemuxContext *c93 = s->priv_data; C93BlockRecord *br = &c93->block_records[c93->current_block]; int datasize; int ret, i; if (c93->next_pkt_is_audio) { c93->current_frame++; c93->next_pkt_is_audio = 0; datasize = avio_rl16(pb); if (datasize > 42) { if (!c93->audio) { c93->audio = avformat_new_stream(s, NULL); if (!c93->audio) return AVERROR(ENOMEM); c93->audio->codec->codec_type = AVMEDIA_TYPE_AUDIO; } avio_skip(pb, 26); /* VOC header */ ret = voc_get_packet(s, pkt, c93->audio, datasize - 26); if (ret > 0) { pkt->stream_index = 1; pkt->flags |= AV_PKT_FLAG_KEY; return ret; } } } if (c93->current_frame >= br->frames) { if (c93->current_block >= 511 || !br[1].length) return AVERROR(EIO); br++; c93->current_block++; c93->current_frame = 0; } if (c93->current_frame == 0) { avio_seek(pb, br->index * 2048, SEEK_SET); for (i = 0; i < 32; i++) { c93->frame_offsets[i] = avio_rl32(pb); } } avio_seek(pb,br->index * 2048 + c93->frame_offsets[c93->current_frame], SEEK_SET); datasize = avio_rl16(pb); /* video frame size */ ret = av_new_packet(pkt, datasize + 768 + 1); if (ret < 0) return ret; pkt->data[0] = 0; pkt->size = datasize + 1; ret = avio_read(pb, pkt->data + 1, datasize); if (ret < datasize) { ret = AVERROR(EIO); goto fail; } datasize = avio_rl16(pb); /* palette size */ if (datasize) { if (datasize != 768) { av_log(s, AV_LOG_ERROR, "invalid palette size %u\n", datasize); ret = AVERROR_INVALIDDATA; goto fail; } pkt->data[0] |= C93_HAS_PALETTE; ret = avio_read(pb, pkt->data + pkt->size, datasize); if (ret < datasize) { ret = AVERROR(EIO); goto fail; } pkt->size += 768; } pkt->stream_index = 0; c93->next_pkt_is_audio = 1; /* only the first frame is guaranteed to not reference previous frames */ if (c93->current_block == 0 && c93->current_frame == 0) { pkt->flags |= AV_PKT_FLAG_KEY; pkt->data[0] |= C93_FIRST_FRAME; } return 0; fail: av_free_packet(pkt); 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); 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; if (ff_alloc_extradata(st->codec, avio_tell(s->pb) - start_offset)) 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; if (s->pb->seekable) { int64_t pos = avio_tell(s->pb); ff_ape_parse_tag(s); avio_seek(s->pb, pos, SEEK_SET); } return 0; }
static int read_frame(BVID_DemuxContext *vid, AVIOContext *pb, AVPacket *pkt, uint8_t block_type, AVFormatContext *s, int npixels) { uint8_t * vidbuf_start = NULL; int vidbuf_nbytes = 0; int code; int bytes_copied = 0; int position; unsigned int vidbuf_capacity; vidbuf_start = av_malloc(vidbuf_capacity = BUFFER_PADDING_SIZE); if(!vidbuf_start) return AVERROR(ENOMEM); // save the file position for the packet, include block type position = avio_tell(pb) - 1; vidbuf_start[vidbuf_nbytes++] = block_type; // get the video delay (next int16), and set the presentation time vid->video_pts += vid->bethsoft_global_delay + avio_rl16(pb); // set the y offset if it exists (decoder header data should be in data section) if(block_type == VIDEO_YOFF_P_FRAME) { if(avio_read(pb, &vidbuf_start[vidbuf_nbytes], 2) != 2) goto fail; vidbuf_nbytes += 2; } do { vidbuf_start = av_fast_realloc(vidbuf_start, &vidbuf_capacity, vidbuf_nbytes + BUFFER_PADDING_SIZE); if(!vidbuf_start) return AVERROR(ENOMEM); code = avio_r8(pb); vidbuf_start[vidbuf_nbytes++] = code; if(code >= 0x80) // rle sequence { if(block_type == VIDEO_I_FRAME) vidbuf_start[vidbuf_nbytes++] = avio_r8(pb); } else if(code) // plain sequence { if(avio_read(pb, &vidbuf_start[vidbuf_nbytes], code) != code) goto fail; vidbuf_nbytes += code; } bytes_copied += code & 0x7F; if(bytes_copied == npixels) // sometimes no stop character is given, need to keep track of bytes copied { // may contain a 0 byte even if read all pixels if(avio_r8(pb)) avio_seek(pb, -1, SEEK_CUR); break; } if(bytes_copied > npixels) goto fail; } while(code); // copy data into packet if(av_new_packet(pkt, vidbuf_nbytes) < 0) goto fail; memcpy(pkt->data, vidbuf_start, vidbuf_nbytes); av_free(vidbuf_start); pkt->pos = position; pkt->stream_index = 0; // use the video decoder, which was initialized as the first stream pkt->pts = vid->video_pts; vid->nframes--; // used to check if all the frames were read return vidbuf_nbytes; fail: av_free(vidbuf_start); return -1; }
int ff_spdif_read_packet(AVFormatContext *s, AVPacket *pkt) { AVIOContext *pb = s->pb; enum IEC61937DataType data_type; enum AVCodecID codec_id; uint32_t state = 0; int pkt_size_bits, offset, ret; while (state != (AV_BSWAP16C(SYNCWORD1) << 16 | AV_BSWAP16C(SYNCWORD2))) { state = (state << 8) | avio_r8(pb); if (avio_feof(pb)) return AVERROR_EOF; } data_type = avio_rl16(pb); pkt_size_bits = avio_rl16(pb); if (pkt_size_bits % 16) avpriv_request_sample(s, "Packet not ending at a 16-bit boundary"); ret = av_new_packet(pkt, FFALIGN(pkt_size_bits, 16) >> 3); if (ret) return ret; pkt->pos = avio_tell(pb) - BURST_HEADER_SIZE; if (avio_read(pb, pkt->data, pkt->size) < pkt->size) { av_free_packet(pkt); return AVERROR_EOF; } ff_spdif_bswap_buf16((uint16_t *)pkt->data, (uint16_t *)pkt->data, pkt->size >> 1); ret = spdif_get_offset_and_codec(s, data_type, pkt->data, &offset, &codec_id); if (ret) { av_free_packet(pkt); return ret; } /* skip over the padding to the beginning of the next frame */ avio_skip(pb, offset - pkt->size - BURST_HEADER_SIZE); if (!s->nb_streams) { /* first packet, create a stream */ AVStream *st = avformat_new_stream(s, NULL); if (!st) { av_free_packet(pkt); return AVERROR(ENOMEM); } st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_id = codec_id; } else if (codec_id != s->streams[0]->codec->codec_id) { avpriv_report_missing_feature(s, "Codec change in IEC 61937"); return AVERROR_PATCHWELCOME; } if (!s->bit_rate && s->streams[0]->codec->sample_rate) /* stream bitrate matches 16-bit stereo PCM bitrate for currently supported codecs */ s->bit_rate = 2 * 16 * s->streams[0]->codec->sample_rate; return 0; }
static int wav_parse_bext_tag(AVFormatContext *s, int64_t size) { char temp[131], *coding_history; int ret, x; uint64_t time_reference; int64_t umid_parts[8], umid_mask = 0; if ((ret = wav_parse_bext_string(s, "description", 256)) < 0 || (ret = wav_parse_bext_string(s, "originator", 32)) < 0 || (ret = wav_parse_bext_string(s, "originator_reference", 32)) < 0 || (ret = wav_parse_bext_string(s, "origination_date", 10)) < 0 || (ret = wav_parse_bext_string(s, "origination_time", 8)) < 0) return ret; time_reference = avio_rl64(s->pb); snprintf(temp, sizeof(temp), "%"PRIu64, time_reference); if ((ret = av_dict_set(&s->metadata, "time_reference", temp, 0)) < 0) return ret; /* check if version is >= 1, in which case an UMID may be present */ if (avio_rl16(s->pb) >= 1) { for (x = 0; x < 8; x++) umid_mask |= umid_parts[x] = avio_rb64(s->pb); if (umid_mask) { /* the string formatting below is per SMPTE 330M-2004 Annex C */ if (umid_parts[4] == 0 && umid_parts[5] == 0 && umid_parts[6] == 0 && umid_parts[7] == 0) { /* basic UMID */ snprintf(temp, sizeof(temp), "0x%016"PRIX64"%016"PRIX64"%016"PRIX64"%016"PRIX64, umid_parts[0], umid_parts[1], umid_parts[2], umid_parts[3]); } else { /* extended UMID */ snprintf(temp, sizeof(temp), "0x%016"PRIX64"%016"PRIX64"%016"PRIX64"%016"PRIX64 "%016"PRIX64"%016"PRIX64"%016"PRIX64"%016"PRIX64, umid_parts[0], umid_parts[1], umid_parts[2], umid_parts[3], umid_parts[4], umid_parts[5], umid_parts[6], umid_parts[7]); } if ((ret = av_dict_set(&s->metadata, "umid", temp, 0)) < 0) return ret; } avio_skip(s->pb, 190); } else avio_skip(s->pb, 254); if (size > 602) { /* CodingHistory present */ size -= 602; if (!(coding_history = av_malloc(size+1))) return AVERROR(ENOMEM); if ((ret = avio_read(s->pb, coding_history, size)) < 0) return ret; coding_history[size] = 0; if ((ret = av_dict_set(&s->metadata, "coding_history", coding_history, AV_DICT_DONT_STRDUP_VAL)) < 0) return ret; } return 0; }
static int wv_read_block_header(AVFormatContext *ctx, AVIOContext *pb) { WVContext *wc = ctx->priv_data; int ret; int rate, bpp, chan; uint32_t chmask, flags; wc->pos = avio_tell(pb); /* don't return bogus packets with the ape tag data */ if (wc->apetag_start && wc->pos >= wc->apetag_start) return AVERROR_EOF; ret = avio_read(pb, wc->block_header, WV_HEADER_SIZE); if (ret != WV_HEADER_SIZE) return (ret < 0) ? ret : AVERROR_EOF; ret = ff_wv_parse_header(&wc->header, wc->block_header); if (ret < 0) { av_log(ctx, AV_LOG_ERROR, "Invalid block header.\n"); return ret; } if (wc->header.version < 0x402 || wc->header.version > 0x410) { av_log(ctx, AV_LOG_ERROR, "Unsupported version %03X\n", wc->header.version); return AVERROR_PATCHWELCOME; } /* Blocks with zero samples don't contain actual audio information * and should be ignored */ if (!wc->header.samples) return 0; // parse flags flags = wc->header.flags; bpp = ((flags & 3) + 1) << 3; chan = 1 + !(flags & WV_MONO); chmask = flags & WV_MONO ? AV_CH_LAYOUT_MONO : AV_CH_LAYOUT_STEREO; rate = wv_rates[(flags >> 23) & 0xF]; wc->multichannel = !(wc->header.initial && wc->header.final); if (wc->multichannel) { chan = wc->chan; chmask = wc->chmask; } if ((rate == -1 || !chan) && !wc->block_parsed) { int64_t block_end = avio_tell(pb) + wc->header.blocksize; if (!pb->seekable) { av_log(ctx, AV_LOG_ERROR, "Cannot determine additional parameters\n"); return AVERROR_INVALIDDATA; } while (avio_tell(pb) < block_end) { int id, size; id = avio_r8(pb); size = (id & 0x80) ? avio_rl24(pb) : avio_r8(pb); size <<= 1; if (id & 0x40) size--; switch (id & 0x3F) { case 0xD: if (size <= 1) { av_log(ctx, AV_LOG_ERROR, "Insufficient channel information\n"); return AVERROR_INVALIDDATA; } chan = avio_r8(pb); switch (size - 2) { case 0: chmask = avio_r8(pb); break; case 1: chmask = avio_rl16(pb); break; case 2: chmask = avio_rl24(pb); break; case 3: chmask = avio_rl32(pb); break; case 5: avio_skip(pb, 1); chan |= (avio_r8(pb) & 0xF) << 8; chmask = avio_rl24(pb); break; default: av_log(ctx, AV_LOG_ERROR, "Invalid channel info size %d\n", size); return AVERROR_INVALIDDATA; } break; case 0x27: rate = avio_rl24(pb); break; default: avio_skip(pb, size); } if (id & 0x40) avio_skip(pb, 1); } if (rate == -1) { av_log(ctx, AV_LOG_ERROR, "Cannot determine custom sampling rate\n"); return AVERROR_INVALIDDATA; } avio_seek(pb, block_end - wc->header.blocksize, SEEK_SET); } if (!wc->bpp) wc->bpp = bpp; if (!wc->chan) wc->chan = chan; if (!wc->chmask) wc->chmask = chmask; if (!wc->rate) wc->rate = rate; if (flags && bpp != wc->bpp) { av_log(ctx, AV_LOG_ERROR, "Bits per sample differ, this block: %i, header block: %i\n", bpp, wc->bpp); return AVERROR_INVALIDDATA; } if (flags && !wc->multichannel && chan != wc->chan) { av_log(ctx, AV_LOG_ERROR, "Channels differ, this block: %i, header block: %i\n", chan, wc->chan); return AVERROR_INVALIDDATA; } if (flags && rate != -1 && rate != wc->rate) { av_log(ctx, AV_LOG_ERROR, "Sampling rate differ, this block: %i, header block: %i\n", rate, wc->rate); return AVERROR_INVALIDDATA; } return 0; }
static int read_frame(BVID_DemuxContext *vid, AVIOContext *pb, AVPacket *pkt, uint8_t block_type, AVFormatContext *s) { uint8_t * vidbuf_start = NULL; int vidbuf_nbytes = 0; int code; int bytes_copied = 0; int position, duration, npixels; unsigned int vidbuf_capacity; int ret = 0; AVStream *st; if (vid->video_index < 0) { st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); vid->video_index = st->index; if (vid->audio_index < 0) { av_log_ask_for_sample(s, "No audio packet before first video " "packet. Using default video time base.\n"); } avpriv_set_pts_info(st, 64, 185, vid->sample_rate); st->codec->codec_type = AVMEDIA_TYPE_VIDEO; st->codec->codec_id = CODEC_ID_BETHSOFTVID; st->codec->width = vid->width; st->codec->height = vid->height; } st = s->streams[vid->video_index]; npixels = st->codec->width * st->codec->height; vidbuf_start = av_malloc(vidbuf_capacity = BUFFER_PADDING_SIZE); if(!vidbuf_start) return AVERROR(ENOMEM); // save the file position for the packet, include block type position = avio_tell(pb) - 1; vidbuf_start[vidbuf_nbytes++] = block_type; // get the current packet duration duration = vid->bethsoft_global_delay + avio_rl16(pb); // set the y offset if it exists (decoder header data should be in data section) if(block_type == VIDEO_YOFF_P_FRAME){ if (avio_read(pb, &vidbuf_start[vidbuf_nbytes], 2) != 2) { ret = AVERROR(EIO); goto fail; } vidbuf_nbytes += 2; } do{ vidbuf_start = av_fast_realloc(vidbuf_start, &vidbuf_capacity, vidbuf_nbytes + BUFFER_PADDING_SIZE); if(!vidbuf_start) return AVERROR(ENOMEM); code = avio_r8(pb); vidbuf_start[vidbuf_nbytes++] = code; if(code >= 0x80){ // rle sequence if(block_type == VIDEO_I_FRAME) vidbuf_start[vidbuf_nbytes++] = avio_r8(pb); } else if(code){ // plain sequence if (avio_read(pb, &vidbuf_start[vidbuf_nbytes], code) != code) { ret = AVERROR(EIO); goto fail; } vidbuf_nbytes += code; } bytes_copied += code & 0x7F; if(bytes_copied == npixels){ // sometimes no stop character is given, need to keep track of bytes copied // may contain a 0 byte even if read all pixels if(avio_r8(pb)) avio_seek(pb, -1, SEEK_CUR); break; } if (bytes_copied > npixels) { ret = AVERROR_INVALIDDATA; goto fail; } } while(code); // copy data into packet if ((ret = av_new_packet(pkt, vidbuf_nbytes)) < 0) goto fail; memcpy(pkt->data, vidbuf_start, vidbuf_nbytes); av_free(vidbuf_start); pkt->pos = position; pkt->stream_index = vid->video_index; pkt->duration = duration; if (block_type == VIDEO_I_FRAME) pkt->flags |= AV_PKT_FLAG_KEY; /* if there is a new palette available, add it to packet side data */ if (vid->palette) { uint8_t *pdata = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, BVID_PALETTE_SIZE); memcpy(pdata, vid->palette, BVID_PALETTE_SIZE); av_freep(&vid->palette); } vid->nframes--; // used to check if all the frames were read return 0; fail: av_free(vidbuf_start); return ret; }
static int read_header(AVFormatContext *s, AVFormatParameters *ap) { AnmDemuxContext *anm = s->priv_data; AVIOContext *pb = s->pb; AVStream *st; int i, ret; avio_skip(pb, 4); /* magic number */ if (avio_rl16(pb) != MAX_PAGES) { av_log_ask_for_sample(s, "max_pages != " AV_STRINGIFY(MAX_PAGES) "\n"); return AVERROR_INVALIDDATA; } anm->nb_pages = avio_rl16(pb); anm->nb_records = avio_rl32(pb); avio_skip(pb, 2); /* max records per page */ anm->page_table_offset = avio_rl16(pb); if (avio_rl32(pb) != ANIM_TAG) return AVERROR_INVALIDDATA; /* 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_ANM; st->codec->codec_tag = 0; /* no fourcc */ st->codec->width = avio_rl16(pb); st->codec->height = avio_rl16(pb); if (avio_r8(pb) != 0) goto invalid; avio_skip(pb, 1); /* frame rate multiplier info */ /* ignore last delta record (used for looping) */ if (avio_r8(pb)) /* has_last_delta */ anm->nb_records = FFMAX(anm->nb_records - 1, 0); avio_skip(pb, 1); /* last_delta_valid */ if (avio_r8(pb) != 0) goto invalid; if (avio_r8(pb) != 1) goto invalid; avio_skip(pb, 1); /* other recs per frame */ if (avio_r8(pb) != 1) goto invalid; avio_skip(pb, 32); /* record_types */ st->nb_frames = avio_rl32(pb); av_set_pts_info(st, 64, 1, avio_rl16(pb)); avio_skip(pb, 58); /* color cycling and palette data */ st->codec->extradata_size = 16*8 + 4*256; st->codec->extradata = av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); if (!st->codec->extradata) { ret = AVERROR(ENOMEM); goto close_and_return; } ret = avio_read(pb, st->codec->extradata, st->codec->extradata_size); if (ret < 0) goto close_and_return; /* read page table */ ret = avio_seek(pb, anm->page_table_offset, SEEK_SET); if (ret < 0) goto close_and_return; for (i = 0; i < MAX_PAGES; i++) { Page *p = &anm->pt[i]; p->base_record = avio_rl16(pb); p->nb_records = avio_rl16(pb); p->size = avio_rl16(pb); } /* find page of first frame */ anm->page = find_record(anm, 0); if (anm->page < 0) { ret = anm->page; goto close_and_return; } anm->record = -1; return 0; invalid: av_log_ask_for_sample(s, NULL); ret = AVERROR_INVALIDDATA; close_and_return: av_close_input_stream(s); return ret; }
static int vid_read_packet(AVFormatContext *s, AVPacket *pkt) { BVID_DemuxContext *vid = s->priv_data; AVIOContext *pb = s->pb; unsigned char block_type; int audio_length; int ret_value; if(vid->is_finished || url_feof(pb)) return AVERROR(EIO); block_type = avio_r8(pb); switch(block_type){ case PALETTE_BLOCK: if (vid->palette) { av_log(s, AV_LOG_WARNING, "discarding unused palette\n"); av_freep(&vid->palette); } vid->palette = av_malloc(BVID_PALETTE_SIZE); if (!vid->palette) return AVERROR(ENOMEM); if (avio_read(pb, vid->palette, BVID_PALETTE_SIZE) != BVID_PALETTE_SIZE) { av_freep(&vid->palette); return AVERROR(EIO); } return vid_read_packet(s, pkt); case FIRST_AUDIO_BLOCK: avio_rl16(pb); // soundblaster DAC used for sample rate, as on specification page (link above) vid->sample_rate = 1000000 / (256 - avio_r8(pb)); case AUDIO_BLOCK: if (vid->audio_index < 0) { AVStream *st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); vid->audio_index = st->index; st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_id = CODEC_ID_PCM_U8; st->codec->channels = 1; st->codec->bits_per_coded_sample = 8; st->codec->sample_rate = vid->sample_rate; st->codec->bit_rate = 8 * st->codec->sample_rate; st->start_time = 0; avpriv_set_pts_info(st, 64, 1, vid->sample_rate); } audio_length = avio_rl16(pb); if ((ret_value = av_get_packet(pb, pkt, audio_length)) != audio_length) { if (ret_value < 0) return ret_value; av_log(s, AV_LOG_ERROR, "incomplete audio block\n"); return AVERROR(EIO); } pkt->stream_index = vid->audio_index; pkt->duration = audio_length; pkt->flags |= AV_PKT_FLAG_KEY; return 0; case VIDEO_P_FRAME: case VIDEO_YOFF_P_FRAME: case VIDEO_I_FRAME: return read_frame(vid, pb, pkt, block_type, s); case EOF_BLOCK: if(vid->nframes != 0) av_log(s, AV_LOG_VERBOSE, "reached terminating character but not all frames read.\n"); vid->is_finished = 1; return AVERROR(EIO); default: av_log(s, AV_LOG_ERROR, "unknown block (character = %c, decimal = %d, hex = %x)!!!\n", block_type, block_type, block_type); return AVERROR_INVALIDDATA; } }
static int lvf_read_header(AVFormatContext *s) { AVStream *st; int64_t next_offset; unsigned size, nb_streams, id; avio_skip(s->pb, 16); nb_streams = avio_rl32(s->pb); if (!nb_streams) return AVERROR_INVALIDDATA; if (nb_streams > 2) { avpriv_request_sample(s, "%d streams", nb_streams); return AVERROR_PATCHWELCOME; } avio_skip(s->pb, 1012); while (!url_feof(s->pb)) { id = avio_rl32(s->pb); size = avio_rl32(s->pb); next_offset = avio_tell(s->pb) + size; switch (id) { case MKTAG('0', '0', 'f', 'm'): st = avformat_new_stream(s, 0); if (!st) return AVERROR(ENOMEM); st->codec->codec_type = AVMEDIA_TYPE_VIDEO; avio_skip(s->pb, 4); st->codec->width = avio_rl32(s->pb); st->codec->height = avio_rl32(s->pb); avio_skip(s->pb, 4); st->codec->codec_tag = avio_rl32(s->pb); st->codec->codec_id = ff_codec_get_id(ff_codec_bmp_tags, st->codec->codec_tag); avpriv_set_pts_info(st, 32, 1, 1000); break; case MKTAG('0', '1', 'f', 'm'): st = avformat_new_stream(s, 0); if (!st) return AVERROR(ENOMEM); st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_tag = avio_rl16(s->pb); st->codec->channels = avio_rl16(s->pb); st->codec->sample_rate = avio_rl16(s->pb); avio_skip(s->pb, 8); st->codec->bits_per_coded_sample = avio_r8(s->pb); st->codec->codec_id = ff_codec_get_id(ff_codec_wav_tags, st->codec->codec_tag); avpriv_set_pts_info(st, 32, 1, 1000); break; case 0: avio_seek(s->pb, 2048 + 8, SEEK_SET); return 0; default: avpriv_request_sample(s, "id %d", id); return AVERROR_PATCHWELCOME; } avio_seek(s->pb, next_offset, SEEK_SET); } return AVERROR_EOF; }
static int gdv_read_header(AVFormatContext *ctx) { GDVContext *gdv = ctx->priv_data; AVIOContext *pb = ctx->pb; AVStream *vst, *ast; unsigned fps, snd_flags, vid_depth, size_id; avio_skip(pb, 4); size_id = avio_rl16(pb); vst = avformat_new_stream(ctx, 0); if (!vst) return AVERROR(ENOMEM); vst->start_time = 0; vst->duration = vst->nb_frames = avio_rl16(pb); fps = avio_rl16(pb); snd_flags = avio_rl16(pb); if (snd_flags & 1) { ast = avformat_new_stream(ctx, 0); if (!ast) return AVERROR(ENOMEM); ast->start_time = 0; ast->codecpar->codec_type = AVMEDIA_TYPE_AUDIO; ast->codecpar->codec_tag = 0; ast->codecpar->sample_rate = avio_rl16(pb); ast->codecpar->channels = 1 + !!(snd_flags & 2); if (snd_flags & 8) { ast->codecpar->codec_id = AV_CODEC_ID_GREMLIN_DPCM; } else { ast->codecpar->codec_id = (snd_flags & 4) ? AV_CODEC_ID_PCM_S16LE : AV_CODEC_ID_PCM_U8; } avpriv_set_pts_info(ast, 64, 1, ast->codecpar->sample_rate); gdv->audio_size = (ast->codecpar->sample_rate / fps) * ast->codecpar->channels * (1 + !!(snd_flags & 4)) / (1 + !!(snd_flags & 8)); gdv->is_audio = 1; } else { avio_skip(pb, 2); } vid_depth = avio_rl16(pb); avio_skip(pb, 4); vst->codecpar->codec_type = AVMEDIA_TYPE_VIDEO; vst->codecpar->codec_id = AV_CODEC_ID_GDV; vst->codecpar->codec_tag = 0; vst->codecpar->width = avio_rl16(pb); vst->codecpar->height = avio_rl16(pb); if (vst->codecpar->width == 0 || vst->codecpar->height == 0) { int i; for (i = 0; i < FF_ARRAY_ELEMS(FixedSize) - 1; i++) { if (FixedSize[i].id == size_id) break; } vst->codecpar->width = FixedSize[i].width; vst->codecpar->height = FixedSize[i].height; } avpriv_set_pts_info(vst, 64, 1, fps); if (vid_depth & 1) { int i; for (i = 0; i < 256; i++) { unsigned r = avio_r8(pb); unsigned g = avio_r8(pb); unsigned b = avio_r8(pb); gdv->pal[i] = 0xFFU << 24 | r << 18 | g << 10 | b << 2; } } gdv->is_first_video = 1; return 0; }
static int ape_read_header(AVFormatContext * s) { AVIOContext *pb = s->pb; APEContext *ape = s->priv_data; AVStream *st; uint32_t tag; int i; int total_blocks, final_size = 0; int64_t pts, file_size; /* Skip any leading junk such as id3v2 tags */ ape->junklength = avio_tell(pb); tag = avio_rl32(pb); if (tag != MKTAG('M', 'A', 'C', ' ')) return AVERROR_INVALIDDATA; 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 - %d.%02d\n", ape->fileversion / 1000, (ape->fileversion % 1000) / 10); return AVERROR_PATCHWELCOME; } 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 AVERROR_INVALIDDATA; } 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: %zu 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); if (!ape->seektable) return AVERROR(ENOMEM); for (i = 0; i < ape->seektablelength / sizeof(uint32_t); i++) ape->seektable[i] = avio_rl32(pb); }else{ av_log(s, AV_LOG_ERROR, "Missing seektable\n"); return AVERROR_INVALIDDATA; } 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].nblocks = ape->finalframeblocks; /* calculate final packet size from total file size, if available */ file_size = avio_size(pb); if (file_size > 0) { final_size = file_size - ape->frames[ape->totalframes - 1].pos - ape->wavtaillength; final_size -= final_size & 3; } if (file_size <= 0 || final_size <= 0) final_size = ape->finalframeblocks * 8; ape->frames[ape->totalframes - 1].size = final_size; 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); 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 = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); total_blocks = (ape->totalframes == 0) ? 0 : ((ape->totalframes - 1) * ape->blocksperframe) + ape->finalframeblocks; st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_id = AV_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->nb_frames = ape->totalframes; st->start_time = 0; st->duration = total_blocks; avpriv_set_pts_info(st, 64, 1, 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; } /* try to read APE tags */ if (pb->seekable) { ff_ape_parse_tag(s); avio_seek(pb, 0, SEEK_SET); } return 0; }
static int read_header(AVFormatContext *s) { JVDemuxContext *jv = s->priv_data; AVIOContext *pb = s->pb; AVStream *vst, *ast; int64_t audio_pts = 0; int64_t offset; int i; avio_skip(pb, 80); ast = avformat_new_stream(s, NULL); vst = avformat_new_stream(s, NULL); if (!ast || !vst) return AVERROR(ENOMEM); vst->codec->codec_type = AVMEDIA_TYPE_VIDEO; vst->codec->codec_id = CODEC_ID_JV; vst->codec->codec_tag = 0; /* no fourcc */ vst->codec->width = avio_rl16(pb); vst->codec->height = avio_rl16(pb); vst->duration = vst->nb_frames = ast->nb_index_entries = avio_rl16(pb); avpriv_set_pts_info(vst, 64, avio_rl16(pb), 1000); avio_skip(pb, 4); ast->codec->codec_type = AVMEDIA_TYPE_AUDIO; ast->codec->codec_id = CODEC_ID_PCM_U8; ast->codec->codec_tag = 0; /* no fourcc */ ast->codec->sample_rate = avio_rl16(pb); ast->codec->channels = 1; avpriv_set_pts_info(ast, 64, 1, ast->codec->sample_rate); avio_skip(pb, 10); ast->index_entries = av_malloc(ast->nb_index_entries * sizeof(*ast->index_entries)); if (!ast->index_entries) return AVERROR(ENOMEM); jv->frames = av_malloc(ast->nb_index_entries * sizeof(JVFrame)); if (!jv->frames) return AVERROR(ENOMEM); offset = 0x68 + ast->nb_index_entries * 16; for(i = 0; i < ast->nb_index_entries; i++) { AVIndexEntry *e = ast->index_entries + i; JVFrame *jvf = jv->frames + i; /* total frame size including audio, video, palette data and padding */ e->size = avio_rl32(pb); e->timestamp = i; e->pos = offset; offset += e->size; jvf->audio_size = avio_rl32(pb); jvf->video_size = avio_rl32(pb); jvf->palette_size = avio_r8(pb) ? 768 : 0; jvf->video_size = FFMIN(FFMAX(jvf->video_size, 0), INT_MAX - JV_PREAMBLE_SIZE - jvf->palette_size); if (avio_r8(pb)) av_log(s, AV_LOG_WARNING, "unsupported audio codec\n"); jvf->video_type = avio_r8(pb); avio_skip(pb, 1); e->timestamp = jvf->audio_size ? audio_pts : AV_NOPTS_VALUE; audio_pts += jvf->audio_size; e->flags = jvf->video_type != 1 ? AVINDEX_KEYFRAME : 0; } jv->state = JV_AUDIO; return 0; }
int ff_voc_get_packet(AVFormatContext *s, AVPacket *pkt, AVStream *st, int max_size) { VocDecContext *voc = s->priv_data; AVCodecParameters *par = st->codecpar; 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 & AVIO_SEEKABLE_NORMAL)) return AVERROR(EIO); voc->remaining_size = avio_size(pb) - avio_tell(pb); } max_size -= 4; switch (type) { case VOC_TYPE_VOICE_DATA: if (!par->sample_rate) { par->sample_rate = 1000000 / (256 - avio_r8(pb)); if (sample_rate) par->sample_rate = sample_rate; avpriv_set_pts_info(st, 64, 1, par->sample_rate); par->channels = channels; par->bits_per_coded_sample = av_get_bits_per_sample(par->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 (!par->sample_rate) { par->sample_rate = avio_rl32(pb); avpriv_set_pts_info(st, 64, 1, par->sample_rate); par->bits_per_coded_sample = avio_r8(pb); par->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 (par->sample_rate <= 0) { av_log(s, AV_LOG_ERROR, "Invalid sample rate %d\n", par->sample_rate); return AVERROR_INVALIDDATA; } if (tmp_codec >= 0) { tmp_codec = ff_codec_get_id(ff_voc_codec_tags, tmp_codec); if (par->codec_id == AV_CODEC_ID_NONE) par->codec_id = tmp_codec; else if (par->codec_id != tmp_codec) av_log(s, AV_LOG_WARNING, "Ignoring mid-stream change in audio codec\n"); if (par->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"); } } par->bit_rate = (int64_t)par->sample_rate * par->channels * par->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_duration2(st->codecpar, size); if (duration > 0 && voc->pts != AV_NOPTS_VALUE) voc->pts += duration; else voc->pts = AV_NOPTS_VALUE; 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 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; }
static int read_header(AVFormatContext *s) { IcoDemuxContext *ico = s->priv_data; AVIOContext *pb = s->pb; int i, codec; avio_skip(pb, 4); ico->nb_images = avio_rl16(pb); ico->images = av_malloc(ico->nb_images * sizeof(IcoImage)); if (!ico->images) return AVERROR(ENOMEM); for (i = 0; i < ico->nb_images; i++) { AVStream *st; int tmp; if (avio_seek(pb, 6 + i * 16, SEEK_SET) < 0) break; st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); st->codec->codec_type = AVMEDIA_TYPE_VIDEO; st->codec->width = avio_r8(pb); st->codec->height = avio_r8(pb); ico->images[i].nb_pal = avio_r8(pb); if (ico->images[i].nb_pal == 255) ico->images[i].nb_pal = 0; avio_skip(pb, 5); ico->images[i].size = avio_rl32(pb); ico->images[i].offset = avio_rl32(pb); if (avio_seek(pb, ico->images[i].offset, SEEK_SET) < 0) break; codec = avio_rl32(pb); switch (codec) { case MKTAG(0x89, 'P', 'N', 'G'): st->codec->codec_id = AV_CODEC_ID_PNG; st->codec->width = 0; st->codec->height = 0; break; case 40: if (ico->images[i].size < 40) return AVERROR_INVALIDDATA; st->codec->codec_id = AV_CODEC_ID_BMP; tmp = avio_rl32(pb); if (tmp) st->codec->width = tmp; tmp = avio_rl32(pb); if (tmp) st->codec->height = tmp / 2; break; default: avpriv_request_sample(s, "codec %d", codec); return AVERROR_INVALIDDATA; } } return 0; }
static int mtv_read_header(AVFormatContext *s) { MTVDemuxContext *mtv = s->priv_data; AVIOContext *pb = s->pb; AVStream *st; unsigned int audio_subsegments; avio_skip(pb, 3); mtv->file_size = avio_rl32(pb); mtv->segments = avio_rl32(pb); avio_skip(pb, 32); mtv->audio_identifier = avio_rl24(pb); mtv->audio_br = avio_rl16(pb); mtv->img_colorfmt = avio_rl24(pb); mtv->img_bpp = avio_r8(pb)>>3; mtv->img_width = avio_rl16(pb); mtv->img_height = avio_rl16(pb); mtv->img_segment_size = avio_rl16(pb); /* Assume 16bpp even if claimed otherwise. * We know its going to be RGBG565/555 anyway */ if (mtv->img_bpp != MTV_IMAGE_DEFAULT_BPP) { av_log (s, AV_LOG_WARNING, "Header claims %dbpp (!= 16). Ignoring\n", mtv->img_bpp); mtv->img_bpp = MTV_IMAGE_DEFAULT_BPP; } /* Calculate width and height if missing from header */ if(!mtv->img_width && mtv->img_height) mtv->img_width=mtv->img_segment_size / (mtv->img_bpp) / mtv->img_height; if(!mtv->img_height && mtv->img_width) mtv->img_height=mtv->img_segment_size / (mtv->img_bpp) / mtv->img_width; if(!mtv->img_height || !mtv->img_width || !mtv->img_segment_size){ av_log(s, AV_LOG_ERROR, "width or height or segment_size is invalid and I cannot calculate them from other information\n"); return AVERROR(EINVAL); } avio_skip(pb, 4); audio_subsegments = avio_rl16(pb); if (audio_subsegments == 0) { avpriv_request_sample(s, "MTV files without audio"); return AVERROR_PATCHWELCOME; } mtv->full_segment_size = audio_subsegments * (MTV_AUDIO_PADDING_SIZE + MTV_ASUBCHUNK_DATA_SIZE) + mtv->img_segment_size; mtv->video_fps = (mtv->audio_br / 4) / audio_subsegments; // FIXME Add sanity check here // all systems go! init decoders // video - raw rgb565 st = avformat_new_stream(s, NULL); if(!st) return AVERROR(ENOMEM); avpriv_set_pts_info(st, 64, 1, mtv->video_fps); st->codec->codec_type = AVMEDIA_TYPE_VIDEO; st->codec->codec_id = AV_CODEC_ID_RAWVIDEO; st->codec->pix_fmt = AV_PIX_FMT_RGB565BE; st->codec->width = mtv->img_width; st->codec->height = mtv->img_height; st->codec->sample_rate = mtv->video_fps; st->codec->extradata = av_strdup("BottomUp"); st->codec->extradata_size = 9; // audio - mp3 st = avformat_new_stream(s, NULL); if(!st) return AVERROR(ENOMEM); avpriv_set_pts_info(st, 64, 1, MTV_AUDIO_SAMPLING_RATE); st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_id = AV_CODEC_ID_MP3; st->codec->bit_rate = mtv->audio_br; st->need_parsing = AVSTREAM_PARSE_FULL; // Jump over header if(avio_seek(pb, MTV_HEADER_SIZE, SEEK_SET) != MTV_HEADER_SIZE) return AVERROR(EIO); return 0; }
static int read_header(AVFormatContext *s) { MviDemuxContext *mvi = s->priv_data; AVIOContext *pb = s->pb; AVStream *ast, *vst; unsigned int version, frames_count, msecs_per_frame, player_version; ast = avformat_new_stream(s, NULL); if (!ast) return AVERROR(ENOMEM); vst = avformat_new_stream(s, NULL); if (!vst) return AVERROR(ENOMEM); vst->codec->extradata_size = 2; vst->codec->extradata = av_mallocz(2 + FF_INPUT_BUFFER_PADDING_SIZE); if (!vst->codec->extradata) return AVERROR(ENOMEM); version = avio_r8(pb); vst->codec->extradata[0] = avio_r8(pb); vst->codec->extradata[1] = avio_r8(pb); frames_count = avio_rl32(pb); msecs_per_frame = avio_rl32(pb); vst->codec->width = avio_rl16(pb); vst->codec->height = avio_rl16(pb); avio_r8(pb); ast->codec->sample_rate = avio_rl16(pb); mvi->audio_data_size = avio_rl32(pb); avio_r8(pb); player_version = avio_rl32(pb); avio_rl16(pb); avio_r8(pb); if (frames_count == 0 || mvi->audio_data_size == 0) return AVERROR_INVALIDDATA; if (version != 7 || player_version > 213) { av_log(s, AV_LOG_ERROR, "unhandled version (%d,%d)\n", version, player_version); return AVERROR_INVALIDDATA; } avpriv_set_pts_info(ast, 64, 1, ast->codec->sample_rate); ast->codec->codec_type = AVMEDIA_TYPE_AUDIO; ast->codec->codec_id = AV_CODEC_ID_PCM_U8; ast->codec->channels = 1; ast->codec->channel_layout = AV_CH_LAYOUT_MONO; ast->codec->bits_per_coded_sample = 8; ast->codec->bit_rate = ast->codec->sample_rate * 8; avpriv_set_pts_info(vst, 64, msecs_per_frame, 1000000); vst->avg_frame_rate = av_inv_q(vst->time_base); vst->codec->codec_type = AVMEDIA_TYPE_VIDEO; vst->codec->codec_id = AV_CODEC_ID_MOTIONPIXELS; mvi->get_int = (vst->codec->width * vst->codec->height < (1 << 16)) ? avio_rl16 : avio_rl24; mvi->audio_frame_size = ((uint64_t)mvi->audio_data_size << MVI_FRAC_BITS) / frames_count; if (!mvi->audio_frame_size) { av_log(s, AV_LOG_ERROR, "audio_frame_size is 0\n"); return AVERROR_INVALIDDATA; } mvi->audio_size_counter = (ast->codec->sample_rate * 830 / mvi->audio_frame_size - 1) * mvi->audio_frame_size; mvi->audio_size_left = mvi->audio_data_size; return 0; }
static int tmv_read_header(AVFormatContext *s) { TMVContext *tmv = s->priv_data; AVIOContext *pb = s->pb; AVStream *vst, *ast; AVRational fps; unsigned comp_method, char_cols, char_rows, features; if (avio_rl32(pb) != TMV_TAG) return -1; if (!(vst = avformat_new_stream(s, NULL))) return AVERROR(ENOMEM); if (!(ast = avformat_new_stream(s, NULL))) return AVERROR(ENOMEM); ast->codec->sample_rate = avio_rl16(pb); if (!ast->codec->sample_rate) { av_log(s, AV_LOG_ERROR, "invalid sample rate\n"); return -1; } tmv->audio_chunk_size = avio_rl16(pb); if (!tmv->audio_chunk_size) { av_log(s, AV_LOG_ERROR, "invalid audio chunk size\n"); return -1; } comp_method = avio_r8(pb); if (comp_method) { av_log(s, AV_LOG_ERROR, "unsupported compression method %d\n", comp_method); return -1; } char_cols = avio_r8(pb); char_rows = avio_r8(pb); tmv->video_chunk_size = char_cols * char_rows * 2; features = avio_r8(pb); if (features & ~(TMV_PADDING | TMV_STEREO)) { av_log(s, AV_LOG_ERROR, "unsupported features 0x%02x\n", features & ~(TMV_PADDING | TMV_STEREO)); return -1; } ast->codec->codec_type = AVMEDIA_TYPE_AUDIO; ast->codec->codec_id = AV_CODEC_ID_PCM_U8; if (features & TMV_STEREO) { ast->codec->channels = 2; ast->codec->channel_layout = AV_CH_LAYOUT_STEREO; } else { ast->codec->channels = 1; ast->codec->channel_layout = AV_CH_LAYOUT_MONO; } ast->codec->bits_per_coded_sample = 8; ast->codec->bit_rate = ast->codec->sample_rate * ast->codec->bits_per_coded_sample; avpriv_set_pts_info(ast, 32, 1, ast->codec->sample_rate); fps.num = ast->codec->sample_rate * ast->codec->channels; fps.den = tmv->audio_chunk_size; av_reduce(&fps.num, &fps.den, fps.num, fps.den, 0xFFFFFFFFLL); vst->codec->codec_type = AVMEDIA_TYPE_VIDEO; vst->codec->codec_id = AV_CODEC_ID_TMV; vst->codec->pix_fmt = AV_PIX_FMT_PAL8; vst->codec->width = char_cols * 8; vst->codec->height = char_rows * 8; avpriv_set_pts_info(vst, 32, fps.den, fps.num); if (features & TMV_PADDING) tmv->padding = ((tmv->video_chunk_size + tmv->audio_chunk_size + 511) & ~511) - (tmv->video_chunk_size + tmv->audio_chunk_size); vst->codec->bit_rate = ((tmv->video_chunk_size + tmv->padding) * fps.num * 8) / fps.den; return 0; }
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 ffm2_read_header(AVFormatContext *s) { FFMContext *ffm = s->priv_data; AVStream *st; AVIOContext *pb = s->pb; AVCodecContext *codec; int ret; int f_main = 0, f_cprv = -1, f_stvi = -1, f_stau = -1; AVCodec *enc; char *buffer; ffm->packet_size = avio_rb32(pb); if (ffm->packet_size != FFM_PACKET_SIZE) { av_log(s, AV_LOG_ERROR, "Invalid packet size %d, expected size was %d\n", ffm->packet_size, FFM_PACKET_SIZE); ret = AVERROR_INVALIDDATA; goto fail; } ffm->write_index = avio_rb64(pb); /* get also filesize */ if (pb->seekable) { ffm->file_size = avio_size(pb); if (ffm->write_index && 0) adjust_write_index(s); } else { ffm->file_size = (UINT64_C(1) << 63) - 1; } while(!avio_feof(pb)) { unsigned id = avio_rb32(pb); unsigned size = avio_rb32(pb); int64_t next = avio_tell(pb) + size; char rc_eq_buf[128]; if(!id) break; switch(id) { case MKBETAG('M', 'A', 'I', 'N'): if (f_main++) { ret = AVERROR(EINVAL); goto fail; } avio_rb32(pb); /* nb_streams */ avio_rb32(pb); /* total bitrate */ break; case MKBETAG('C', 'O', 'M', 'M'): f_cprv = f_stvi = f_stau = 0; st = avformat_new_stream(s, NULL); if (!st) { ret = AVERROR(ENOMEM); goto fail; } avpriv_set_pts_info(st, 64, 1, 1000000); codec = st->codec; /* generic info */ codec->codec_id = avio_rb32(pb); codec->codec_type = avio_r8(pb); codec->bit_rate = avio_rb32(pb); codec->flags = avio_rb32(pb); codec->flags2 = avio_rb32(pb); codec->debug = avio_rb32(pb); if (codec->flags & CODEC_FLAG_GLOBAL_HEADER) { if (ff_get_extradata(codec, pb, avio_rb32(pb)) < 0) return AVERROR(ENOMEM); } break; case MKBETAG('S', 'T', 'V', 'I'): if (f_stvi++) { ret = AVERROR(EINVAL); goto fail; } codec->time_base.num = avio_rb32(pb); codec->time_base.den = avio_rb32(pb); if (codec->time_base.num <= 0 || codec->time_base.den <= 0) { av_log(s, AV_LOG_ERROR, "Invalid time base %d/%d\n", codec->time_base.num, codec->time_base.den); ret = AVERROR_INVALIDDATA; goto fail; } codec->width = avio_rb16(pb); codec->height = avio_rb16(pb); codec->gop_size = avio_rb16(pb); codec->pix_fmt = avio_rb32(pb); codec->qmin = avio_r8(pb); codec->qmax = avio_r8(pb); codec->max_qdiff = avio_r8(pb); codec->qcompress = avio_rb16(pb) / 10000.0; codec->qblur = avio_rb16(pb) / 10000.0; codec->bit_rate_tolerance = avio_rb32(pb); avio_get_str(pb, INT_MAX, rc_eq_buf, sizeof(rc_eq_buf)); codec->rc_eq = av_strdup(rc_eq_buf); codec->rc_max_rate = avio_rb32(pb); codec->rc_min_rate = avio_rb32(pb); codec->rc_buffer_size = avio_rb32(pb); codec->i_quant_factor = av_int2double(avio_rb64(pb)); codec->b_quant_factor = av_int2double(avio_rb64(pb)); codec->i_quant_offset = av_int2double(avio_rb64(pb)); codec->b_quant_offset = av_int2double(avio_rb64(pb)); codec->dct_algo = avio_rb32(pb); codec->strict_std_compliance = avio_rb32(pb); codec->max_b_frames = avio_rb32(pb); codec->mpeg_quant = avio_rb32(pb); codec->intra_dc_precision = avio_rb32(pb); codec->me_method = avio_rb32(pb); codec->mb_decision = avio_rb32(pb); codec->nsse_weight = avio_rb32(pb); codec->frame_skip_cmp = avio_rb32(pb); codec->rc_buffer_aggressivity = av_int2double(avio_rb64(pb)); codec->codec_tag = avio_rb32(pb); codec->thread_count = avio_r8(pb); codec->coder_type = avio_rb32(pb); codec->me_cmp = avio_rb32(pb); codec->me_subpel_quality = avio_rb32(pb); codec->me_range = avio_rb32(pb); codec->keyint_min = avio_rb32(pb); codec->scenechange_threshold = avio_rb32(pb); codec->b_frame_strategy = avio_rb32(pb); codec->qcompress = av_int2double(avio_rb64(pb)); codec->qblur = av_int2double(avio_rb64(pb)); codec->max_qdiff = avio_rb32(pb); codec->refs = avio_rb32(pb); break; case MKBETAG('S', 'T', 'A', 'U'): if (f_stau++) { ret = AVERROR(EINVAL); goto fail; } codec->sample_rate = avio_rb32(pb); codec->channels = avio_rl16(pb); codec->frame_size = avio_rl16(pb); break; case MKBETAG('C', 'P', 'R', 'V'): if (f_cprv++) { ret = AVERROR(EINVAL); goto fail; } enc = avcodec_find_encoder(codec->codec_id); if (enc && enc->priv_data_size && enc->priv_class) { buffer = av_malloc(size + 1); if (!buffer) { ret = AVERROR(ENOMEM); goto fail; } avio_get_str(pb, size, buffer, size + 1); if ((ret = ffm_append_recommended_configuration(st, &buffer)) < 0) goto fail; } break; case MKBETAG('S', '2', 'V', 'I'): if (f_stvi++) { ret = AVERROR(EINVAL); goto fail; } buffer = av_malloc(size); if (!buffer) { ret = AVERROR(ENOMEM); goto fail; } avio_get_str(pb, INT_MAX, buffer, size); av_set_options_string(codec, buffer, "=", ","); if ((ret = ffm_append_recommended_configuration(st, &buffer)) < 0) goto fail; break; case MKBETAG('S', '2', 'A', 'U'): if (f_stau++) { ret = AVERROR(EINVAL); goto fail; } buffer = av_malloc(size); if (!buffer) { ret = AVERROR(ENOMEM); goto fail; } avio_get_str(pb, INT_MAX, buffer, size); av_set_options_string(codec, buffer, "=", ","); if ((ret = ffm_append_recommended_configuration(st, &buffer)) < 0) goto fail; break; } avio_seek(pb, next, SEEK_SET); } /* get until end of block reached */ while ((avio_tell(pb) % ffm->packet_size) != 0 && !pb->eof_reached) avio_r8(pb); /* init packet demux */ ffm->packet_ptr = ffm->packet; ffm->packet_end = ffm->packet; ffm->frame_offset = 0; ffm->dts = 0; ffm->read_state = READ_HEADER; ffm->first_packet = 1; return 0; fail: ffm_close(s); return ret; }
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 = 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 -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 = 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 -1; } 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(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 ffm_read_header(AVFormatContext *s) { FFMContext *ffm = s->priv_data; AVStream *st; AVIOContext *pb = s->pb; AVCodecContext *codec; int i, nb_streams; uint32_t tag; /* header */ tag = avio_rl32(pb); if (tag == MKTAG('F', 'F', 'M', '2')) return ffm2_read_header(s); if (tag != MKTAG('F', 'F', 'M', '1')) goto fail; ffm->packet_size = avio_rb32(pb); if (ffm->packet_size != FFM_PACKET_SIZE) goto fail; ffm->write_index = avio_rb64(pb); /* get also filesize */ if (pb->seekable) { ffm->file_size = avio_size(pb); if (ffm->write_index && 0) adjust_write_index(s); } else { ffm->file_size = (UINT64_C(1) << 63) - 1; } nb_streams = avio_rb32(pb); avio_rb32(pb); /* total bitrate */ /* read each stream */ for(i=0;i<nb_streams;i++) { char rc_eq_buf[128]; st = avformat_new_stream(s, NULL); if (!st) goto fail; avpriv_set_pts_info(st, 64, 1, 1000000); codec = st->codec; /* generic info */ codec->codec_id = avio_rb32(pb); codec->codec_type = avio_r8(pb); /* codec_type */ codec->bit_rate = avio_rb32(pb); codec->flags = avio_rb32(pb); codec->flags2 = avio_rb32(pb); codec->debug = avio_rb32(pb); /* specific info */ switch(codec->codec_type) { case AVMEDIA_TYPE_VIDEO: codec->time_base.num = avio_rb32(pb); codec->time_base.den = avio_rb32(pb); if (codec->time_base.num <= 0 || codec->time_base.den <= 0) { av_log(s, AV_LOG_ERROR, "Invalid time base %d/%d\n", codec->time_base.num, codec->time_base.den); goto fail; } codec->width = avio_rb16(pb); codec->height = avio_rb16(pb); codec->gop_size = avio_rb16(pb); codec->pix_fmt = avio_rb32(pb); codec->qmin = avio_r8(pb); codec->qmax = avio_r8(pb); codec->max_qdiff = avio_r8(pb); codec->qcompress = avio_rb16(pb) / 10000.0; codec->qblur = avio_rb16(pb) / 10000.0; codec->bit_rate_tolerance = avio_rb32(pb); avio_get_str(pb, INT_MAX, rc_eq_buf, sizeof(rc_eq_buf)); codec->rc_eq = av_strdup(rc_eq_buf); codec->rc_max_rate = avio_rb32(pb); codec->rc_min_rate = avio_rb32(pb); codec->rc_buffer_size = avio_rb32(pb); codec->i_quant_factor = av_int2double(avio_rb64(pb)); codec->b_quant_factor = av_int2double(avio_rb64(pb)); codec->i_quant_offset = av_int2double(avio_rb64(pb)); codec->b_quant_offset = av_int2double(avio_rb64(pb)); codec->dct_algo = avio_rb32(pb); codec->strict_std_compliance = avio_rb32(pb); codec->max_b_frames = avio_rb32(pb); codec->mpeg_quant = avio_rb32(pb); codec->intra_dc_precision = avio_rb32(pb); codec->me_method = avio_rb32(pb); codec->mb_decision = avio_rb32(pb); codec->nsse_weight = avio_rb32(pb); codec->frame_skip_cmp = avio_rb32(pb); codec->rc_buffer_aggressivity = av_int2double(avio_rb64(pb)); codec->codec_tag = avio_rb32(pb); codec->thread_count = avio_r8(pb); codec->coder_type = avio_rb32(pb); codec->me_cmp = avio_rb32(pb); codec->me_subpel_quality = avio_rb32(pb); codec->me_range = avio_rb32(pb); codec->keyint_min = avio_rb32(pb); codec->scenechange_threshold = avio_rb32(pb); codec->b_frame_strategy = avio_rb32(pb); codec->qcompress = av_int2double(avio_rb64(pb)); codec->qblur = av_int2double(avio_rb64(pb)); codec->max_qdiff = avio_rb32(pb); codec->refs = avio_rb32(pb); break; case AVMEDIA_TYPE_AUDIO: codec->sample_rate = avio_rb32(pb); codec->channels = avio_rl16(pb); codec->frame_size = avio_rl16(pb); break; default: goto fail; } if (codec->flags & CODEC_FLAG_GLOBAL_HEADER) { if (ff_get_extradata(codec, pb, avio_rb32(pb)) < 0) return AVERROR(ENOMEM); } } /* get until end of block reached */ while ((avio_tell(pb) % ffm->packet_size) != 0 && !pb->eof_reached) avio_r8(pb); /* init packet demux */ ffm->packet_ptr = ffm->packet; ffm->packet_end = ffm->packet; ffm->frame_offset = 0; ffm->dts = 0; ffm->read_state = READ_HEADER; ffm->first_packet = 1; return 0; fail: ffm_close(s); return -1; }
/** * 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_skip(pb,4); /* 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 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; vst = avformat_new_stream(s, NULL); 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_skip(pb, 4); 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); } avpriv_set_pts_info(vst, 64, fps_den, fps_num); vst->codec->codec_type = AVMEDIA_TYPE_VIDEO; vst->codec->codec_id = AV_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_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->codec->codec_type = AVMEDIA_TYPE_AUDIO; ast->codec->codec_tag = 0; ast->codec->sample_rate = avio_rl16(pb); avpriv_set_pts_info(ast, 64, 1, ast->codec->sample_rate); flags = avio_rl16(pb); ast->codec->codec_id = flags & BINK_AUD_USEDCT ? AV_CODEC_ID_BINKAUDIO_DCT : AV_CODEC_ID_BINKAUDIO_RDFT; if (flags & BINK_AUD_STEREO) { ast->codec->channels = 2; ast->codec->channel_layout = AV_CH_LAYOUT_STEREO; } else { ast->codec->channels = 1; ast->codec->channel_layout = AV_CH_LAYOUT_MONO; } ast->codec->extradata = av_mallocz(4 + FF_INPUT_BUFFER_PADDING_SIZE); if (!ast->codec->extradata) return AVERROR(ENOMEM); ast->codec->extradata_size = 4; AV_WL32(ast->codec->extradata, vst->codec->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); } av_add_index_entry(vst, pos, i, next_pos - pos, 0, keyframe ? AVINDEX_KEYFRAME : 0); } avio_skip(pb, 4); bink->current_track = -1; return 0; }
static int wv_read_block_header(AVFormatContext *ctx, AVIOContext *pb, int append) { WVContext *wc = ctx->priv_data; uint32_t tag, ver; int size; int rate, bpp, chan; uint32_t chmask; wc->pos = avio_tell(pb); /* don't return bogus packets with the ape tag data */ if (wc->apetag_start && wc->pos >= wc->apetag_start) return AVERROR_EOF; if (!append) { tag = avio_rl32(pb); if (tag != MKTAG('w', 'v', 'p', 'k')) return AVERROR_INVALIDDATA; size = avio_rl32(pb); if (size < 24 || size > WV_BLOCK_LIMIT) { av_log(ctx, AV_LOG_ERROR, "Incorrect block size %i\n", size); return AVERROR_INVALIDDATA; } wc->blksize = size; ver = avio_rl16(pb); if (ver < 0x402 || ver > 0x410) { av_log(ctx, AV_LOG_ERROR, "Unsupported version %03X\n", ver); return AVERROR_PATCHWELCOME; } avio_r8(pb); // track no avio_r8(pb); // track sub index wc->samples = avio_rl32(pb); // total samples in file wc->soff = avio_rl32(pb); // offset in samples of current block avio_read(pb, wc->extra, WV_EXTRA_SIZE); } else { size = wc->blksize; } wc->flags = AV_RL32(wc->extra + 4); /* Blocks with zero samples don't contain actual audio information * and should be ignored */ if (!AV_RN32(wc->extra)) return 0; // parse flags bpp = ((wc->flags & 3) + 1) << 3; chan = 1 + !(wc->flags & WV_MONO); chmask = wc->flags & WV_MONO ? AV_CH_LAYOUT_MONO : AV_CH_LAYOUT_STEREO; rate = wv_rates[(wc->flags >> 23) & 0xF]; wc->multichannel = !!((wc->flags & WV_SINGLE_BLOCK) != WV_SINGLE_BLOCK); if (wc->multichannel) { chan = wc->chan; chmask = wc->chmask; } if ((rate == -1 || !chan) && !wc->block_parsed) { int64_t block_end = avio_tell(pb) + wc->blksize - 24; if (!pb->seekable) { av_log(ctx, AV_LOG_ERROR, "Cannot determine additional parameters\n"); return AVERROR_INVALIDDATA; } while (avio_tell(pb) < block_end) { int id, size; id = avio_r8(pb); size = (id & 0x80) ? avio_rl24(pb) : avio_r8(pb); size <<= 1; if (id & 0x40) size--; switch (id & 0x3F) { case 0xD: if (size <= 1) { av_log(ctx, AV_LOG_ERROR, "Insufficient channel information\n"); return AVERROR_INVALIDDATA; } chan = avio_r8(pb); switch (size - 2) { case 0: chmask = avio_r8(pb); break; case 1: chmask = avio_rl16(pb); break; case 2: chmask = avio_rl24(pb); break; case 3: chmask = avio_rl32(pb); break; case 5: avio_skip(pb, 1); chan |= (avio_r8(pb) & 0xF) << 8; chmask = avio_rl24(pb); break; default: av_log(ctx, AV_LOG_ERROR, "Invalid channel info size %d\n", size); return AVERROR_INVALIDDATA; } break; case 0x27: rate = avio_rl24(pb); break; default: avio_skip(pb, size); } if (id & 0x40) avio_skip(pb, 1); } if (rate == -1) { av_log(ctx, AV_LOG_ERROR, "Cannot determine custom sampling rate\n"); return AVERROR_INVALIDDATA; } avio_seek(pb, block_end - wc->blksize + 24, SEEK_SET); } if (!wc->bpp) wc->bpp = bpp; if (!wc->chan) wc->chan = chan; if (!wc->chmask) wc->chmask = chmask; if (!wc->rate) wc->rate = rate; if (wc->flags && bpp != wc->bpp) { av_log(ctx, AV_LOG_ERROR, "Bits per sample differ, this block: %i, header block: %i\n", bpp, wc->bpp); return AVERROR_INVALIDDATA; } if (wc->flags && !wc->multichannel && chan != wc->chan) { av_log(ctx, AV_LOG_ERROR, "Channels differ, this block: %i, header block: %i\n", chan, wc->chan); return AVERROR_INVALIDDATA; } if (wc->flags && rate != -1 && rate != wc->rate) { av_log(ctx, AV_LOG_ERROR, "Sampling rate differ, this block: %i, header block: %i\n", rate, wc->rate); return AVERROR_INVALIDDATA; } wc->blksize = size - 24; return 0; }
static int yop_read_header(AVFormatContext *s) { YopDecContext *yop = s->priv_data; AVIOContext *pb = s->pb; AVCodecContext *audio_dec, *video_dec; AVStream *audio_stream, *video_stream; int frame_rate, ret; audio_stream = avformat_new_stream(s, NULL); video_stream = avformat_new_stream(s, NULL); // Extra data that will be passed to the decoder video_stream->codec->extradata_size = 8; video_stream->codec->extradata = av_mallocz(video_stream->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); if (!video_stream->codec->extradata) return AVERROR(ENOMEM); // Audio audio_dec = audio_stream->codec; audio_dec->codec_type = AVMEDIA_TYPE_AUDIO; audio_dec->codec_id = CODEC_ID_ADPCM_IMA_APC; audio_dec->channels = 1; audio_dec->sample_rate = 22050; // Video video_dec = video_stream->codec; video_dec->codec_type = AVMEDIA_TYPE_VIDEO; video_dec->codec_id = CODEC_ID_YOP; avio_skip(pb, 6); frame_rate = avio_r8(pb); yop->frame_size = avio_r8(pb) * 2048; video_dec->width = avio_rl16(pb); video_dec->height = avio_rl16(pb); video_stream->sample_aspect_ratio = (AVRational){1, 2}; ret = avio_read(pb, video_dec->extradata, 8); if (ret < 8) return ret < 0 ? ret : AVERROR_EOF; yop->palette_size = video_dec->extradata[0] * 3 + 4; yop->audio_block_length = AV_RL16(video_dec->extradata + 6); // 1840 samples per frame, 1 nibble per sample; hence 1840/2 = 920 if (yop->audio_block_length < 920 || yop->audio_block_length + yop->palette_size >= yop->frame_size) { av_log(s, AV_LOG_ERROR, "YOP has invalid header\n"); return AVERROR_INVALIDDATA; } avio_seek(pb, 2048, SEEK_SET); avpriv_set_pts_info(video_stream, 32, 1, frame_rate); return 0; }