static int mpc_read_header(AVFormatContext *s, AVFormatParameters *ap) { MPCContext *c = s->priv_data; AVStream *st; if(avio_rl24(s->pb) != MKTAG('M', 'P', '+', 0)) { av_log(s, AV_LOG_ERROR, "Not a Musepack file\n"); return -1; } c->ver = avio_r8(s->pb); if(c->ver != 0x07 && c->ver != 0x17) { av_log(s, AV_LOG_ERROR, "Can demux Musepack SV7, got version %02X\n", c->ver); return -1; } c->fcount = avio_rl32(s->pb); if((int64_t)c->fcount * sizeof(MPCFrame) >= UINT_MAX) { av_log(s, AV_LOG_ERROR, "Too many frames, seeking is not possible\n"); return -1; } c->frames = av_malloc(c->fcount * sizeof(MPCFrame)); c->curframe = 0; c->lastframe = -1; c->curbits = 8; c->frames_noted = 0; st = av_new_stream(s, 0); if (!st) return AVERROR(ENOMEM); st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_id = CODEC_ID_MUSEPACK7; st->codec->channels = 2; st->codec->bits_per_coded_sample = 16; st->codec->extradata_size = 16; st->codec->extradata = av_mallocz(st->codec->extradata_size+FF_INPUT_BUFFER_PADDING_SIZE); avio_read(s->pb, st->codec->extradata, 16); st->codec->sample_rate = mpc_rate[st->codec->extradata[2] & 3]; av_set_pts_info(st, 32, MPC_FRAMESIZE, st->codec->sample_rate); /* scan for seekpoints */ st->start_time = 0; st->duration = c->fcount; /* try to read APE tags */ if (s->pb->seekable) { int64_t pos = avio_tell(s->pb); ff_ape_parse_tag(s); if (!av_metadata_get(s->metadata, "", NULL, AV_METADATA_IGNORE_SUFFIX)) ff_id3v1_read(s); avio_seek(s->pb, pos, SEEK_SET); } return 0; }
static int bmv_read_packet(AVFormatContext *s, AVPacket *pkt) { BMVContext *c = s->priv_data; int type; void *tmp; while (c->get_next) { if (s->pb->eof_reached) return AVERROR_EOF; type = avio_r8(s->pb); if (type == BMV_NOP) continue; if (type == BMV_END) return AVERROR_EOF; c->size = avio_rl24(s->pb); if (!c->size) return AVERROR_INVALIDDATA; tmp = av_realloc(c->packet, c->size + 1); if (!tmp) return AVERROR(ENOMEM); c->packet = tmp; c->packet[0] = type; if (avio_read(s->pb, c->packet + 1, c->size) != c->size) return AVERROR(EIO); if (type & BMV_AUDIO) { int audio_size = c->packet[1] * 65 + 1; if (audio_size >= c->size) { av_log(s, AV_LOG_ERROR, "Reported audio size %d is bigger than packet size (%d)\n", audio_size, c->size); return AVERROR_INVALIDDATA; } if (av_new_packet(pkt, audio_size) < 0) return AVERROR(ENOMEM); memcpy(pkt->data, c->packet + 1, pkt->size); pkt->stream_index = 1; pkt->pts = c->audio_pos; pkt->duration = c->packet[1] * 32; c->audio_pos += pkt->duration; c->get_next = 0; return pkt->size; } else break; } if (av_new_packet(pkt, c->size + 1) < 0) return AVERROR(ENOMEM); pkt->stream_index = 0; c->get_next = 1; memcpy(pkt->data, c->packet, pkt->size); return pkt->size; }
static int sds_read_header(AVFormatContext *ctx) { SDSContext *s = ctx->priv_data; unsigned sample_period; AVIOContext *pb = ctx->pb; AVStream *st; st = avformat_new_stream(ctx, NULL); if (!st) return AVERROR(ENOMEM); avio_skip(pb, 4); avio_skip(pb, 2); s->bit_depth = avio_r8(pb); if (s->bit_depth < 8 || s->bit_depth > 28) return AVERROR_INVALIDDATA; if (s->bit_depth < 14) { s->read_block = byte2_read; s->size = 60 * 4; } else if (s->bit_depth < 21) { s->read_block = byte3_read; s->size = 40 * 4; } else { s->read_block = byte4_read; s->size = 30 * 4; } st->codecpar->codec_id = AV_CODEC_ID_PCM_U32LE; sample_period = avio_rl24(pb); sample_period = SDS_3BYTE_TO_INT_DECODE(sample_period); avio_skip(pb, 11); st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO; st->codecpar->channels = 1; st->codecpar->sample_rate = sample_period ? 1000000000 / sample_period : 16000; st->duration = (avio_size(pb) - 21) / (127) * s->size / 4; avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate); return 0; }
static int vc1t_read_header(AVFormatContext *s, AVFormatParameters *ap) { AVIOContext *pb = s->pb; AVStream *st; int frames; uint32_t fps; frames = avio_rl24(pb); if(avio_r8(pb) != 0xC5 || avio_rl32(pb) != 4) return -1; /* init video codec */ st = av_new_stream(s, 0); if (!st) return -1; st->codec->codec_type = AVMEDIA_TYPE_VIDEO; st->codec->codec_id = CODEC_ID_WMV3; st->codec->extradata = av_malloc(VC1_EXTRADATA_SIZE); st->codec->extradata_size = VC1_EXTRADATA_SIZE; avio_read(pb, st->codec->extradata, VC1_EXTRADATA_SIZE); st->codec->height = avio_rl32(pb); st->codec->width = avio_rl32(pb); if(avio_rl32(pb) != 0xC) return -1; avio_skip(pb, 8); fps = avio_rl32(pb); if(fps == 0xFFFFFFFF) av_set_pts_info(st, 32, 1, 1000); else{ if (!fps) { av_log(s, AV_LOG_ERROR, "Zero FPS specified, defaulting to 1 FPS\n"); fps = 1; } av_set_pts_info(st, 24, 1, fps); st->duration = frames; } return 0; }
static int vc1t_read_header(AVFormatContext *s) { AVIOContext *pb = s->pb; AVStream *st; int frames; uint32_t fps; frames = avio_rl24(pb); if(avio_r8(pb) != 0xC5 || avio_rl32(pb) != 4) return AVERROR_INVALIDDATA; /* init video codec */ st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO; st->codecpar->codec_id = AV_CODEC_ID_WMV3; if (ff_get_extradata(s, st->codecpar, pb, VC1_EXTRADATA_SIZE) < 0) return AVERROR(ENOMEM); st->codecpar->height = avio_rl32(pb); st->codecpar->width = avio_rl32(pb); if(avio_rl32(pb) != 0xC) return AVERROR_INVALIDDATA; avio_skip(pb, 8); fps = avio_rl32(pb); if(fps == 0xFFFFFFFF) avpriv_set_pts_info(st, 32, 1, 1000); else { if (!fps) { av_log(s, AV_LOG_ERROR, "Zero FPS specified, defaulting to 1 FPS\n"); fps = 1; } avpriv_set_pts_info(st, 24, 1, fps); st->duration = frames; } return 0; }
static int vc1t_read_packet(AVFormatContext *s, AVPacket *pkt) { AVIOContext *pb = s->pb; int frame_size; int keyframe = 0; uint32_t pts; if(url_feof(pb)) return AVERROR(EIO); frame_size = avio_rl24(pb); if(avio_r8(pb) & 0x80) keyframe = 1; pts = avio_rl32(pb); if(av_get_packet(pb, pkt, frame_size) < 0) return AVERROR(EIO); if(s->streams[0]->time_base.den == 1000) pkt->pts = pts; pkt->flags |= keyframe ? AV_PKT_FLAG_KEY : 0; pkt->pos -= 8; return pkt->size; }
static int smacker_read_header(AVFormatContext *s, AVFormatParameters *ap) { AVIOContext *pb = s->pb; SmackerContext *smk = s->priv_data; AVStream *st, *ast[7]; int i, ret; int tbase; /* read and check header */ smk->magic = avio_rl32(pb); if (smk->magic != MKTAG('S', 'M', 'K', '2') && smk->magic != MKTAG('S', 'M', 'K', '4')) return -1; smk->width = avio_rl32(pb); smk->height = avio_rl32(pb); smk->frames = avio_rl32(pb); smk->pts_inc = (int32_t)avio_rl32(pb); smk->flags = avio_rl32(pb); if(smk->flags & SMACKER_FLAG_RING_FRAME) smk->frames++; for(i = 0; i < 7; i++) smk->audio[i] = avio_rl32(pb); smk->treesize = avio_rl32(pb); if(smk->treesize >= UINT_MAX/4){ // smk->treesize + 16 must not overflow (this check is probably redundant) av_log(s, AV_LOG_ERROR, "treesize too large\n"); return -1; } //FIXME remove extradata "rebuilding" smk->mmap_size = avio_rl32(pb); smk->mclr_size = avio_rl32(pb); smk->full_size = avio_rl32(pb); smk->type_size = avio_rl32(pb); for(i = 0; i < 7; i++) { smk->rates[i] = avio_rl24(pb); smk->aflags[i] = avio_r8(pb); } smk->pad = avio_rl32(pb); /* setup data */ if(smk->frames > 0xFFFFFF) { av_log(s, AV_LOG_ERROR, "Too many frames: %i\n", smk->frames); return -1; } smk->frm_size = av_malloc(smk->frames * 4); smk->frm_flags = av_malloc(smk->frames); smk->is_ver4 = (smk->magic != MKTAG('S', 'M', 'K', '2')); /* read frame info */ for(i = 0; i < smk->frames; i++) { smk->frm_size[i] = avio_rl32(pb); } for(i = 0; i < smk->frames; i++) { smk->frm_flags[i] = avio_r8(pb); } /* init video codec */ st = avformat_new_stream(s, NULL); if (!st) return -1; smk->videoindex = st->index; st->codec->width = smk->width; st->codec->height = smk->height; st->codec->pix_fmt = PIX_FMT_PAL8; st->codec->codec_type = AVMEDIA_TYPE_VIDEO; st->codec->codec_id = CODEC_ID_SMACKVIDEO; st->codec->codec_tag = smk->magic; /* Smacker uses 100000 as internal timebase */ if(smk->pts_inc < 0) smk->pts_inc = -smk->pts_inc; else smk->pts_inc *= 100; tbase = 100000; av_reduce(&tbase, &smk->pts_inc, tbase, smk->pts_inc, (1UL<<31)-1); avpriv_set_pts_info(st, 33, smk->pts_inc, tbase); st->duration = smk->frames; /* handle possible audio streams */ for(i = 0; i < 7; i++) { smk->indexes[i] = -1; if (smk->rates[i]) { ast[i] = avformat_new_stream(s, NULL); smk->indexes[i] = ast[i]->index; ast[i]->codec->codec_type = AVMEDIA_TYPE_AUDIO; if (smk->aflags[i] & SMK_AUD_BINKAUD) { ast[i]->codec->codec_id = CODEC_ID_BINKAUDIO_RDFT; } else if (smk->aflags[i] & SMK_AUD_USEDCT) { ast[i]->codec->codec_id = CODEC_ID_BINKAUDIO_DCT; } else if (smk->aflags[i] & SMK_AUD_PACKED){ ast[i]->codec->codec_id = CODEC_ID_SMACKAUDIO; ast[i]->codec->codec_tag = MKTAG('S', 'M', 'K', 'A'); } else { ast[i]->codec->codec_id = CODEC_ID_PCM_U8; } ast[i]->codec->channels = (smk->aflags[i] & SMK_AUD_STEREO) ? 2 : 1; ast[i]->codec->sample_rate = smk->rates[i]; ast[i]->codec->bits_per_coded_sample = (smk->aflags[i] & SMK_AUD_16BITS) ? 16 : 8; if(ast[i]->codec->bits_per_coded_sample == 16 && ast[i]->codec->codec_id == CODEC_ID_PCM_U8) ast[i]->codec->codec_id = CODEC_ID_PCM_S16LE; avpriv_set_pts_info(ast[i], 64, 1, ast[i]->codec->sample_rate * ast[i]->codec->channels * ast[i]->codec->bits_per_coded_sample / 8); } } /* load trees to extradata, they will be unpacked by decoder */ st->codec->extradata = av_malloc(smk->treesize + 16); st->codec->extradata_size = smk->treesize + 16; if(!st->codec->extradata){ av_log(s, AV_LOG_ERROR, "Cannot allocate %i bytes of extradata\n", smk->treesize + 16); av_free(smk->frm_size); av_free(smk->frm_flags); return -1; } ret = avio_read(pb, st->codec->extradata + 16, st->codec->extradata_size - 16); if(ret != st->codec->extradata_size - 16){ av_free(smk->frm_size); av_free(smk->frm_flags); return AVERROR(EIO); } ((int32_t*)st->codec->extradata)[0] = av_le2ne32(smk->mmap_size); ((int32_t*)st->codec->extradata)[1] = av_le2ne32(smk->mclr_size); ((int32_t*)st->codec->extradata)[2] = av_le2ne32(smk->full_size); ((int32_t*)st->codec->extradata)[3] = av_le2ne32(smk->type_size); smk->curstream = -1; smk->nextpos = avio_tell(pb); 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); 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; }
int 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; while (!voc->remaining_size) { type = avio_r8(pb); if (type == VOC_TYPE_EOF) return AVERROR(EIO); 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: dec->sample_rate = 1000000 / (256 - avio_r8(pb)); if (sample_rate) dec->sample_rate = sample_rate; dec->channels = channels; tmp_codec = avio_r8(pb); dec->bits_per_coded_sample = av_get_bits_per_sample(dec->codec_id); 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: dec->sample_rate = avio_rl32(pb); dec->bits_per_coded_sample = avio_r8(pb); dec->channels = avio_r8(pb); 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 == 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 == CODEC_ID_NONE) { if (s->audio_codec_id == 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->bits_per_coded_sample; if (max_size <= 0) max_size = 2048; size = FFMIN(voc->remaining_size, max_size); voc->remaining_size -= size; return av_get_packet(pb, pkt, size); }
static int mpc_read_header(AVFormatContext *s) { MPCContext *c = s->priv_data; AVStream *st; if(avio_rl24(s->pb) != MKTAG('M', 'P', '+', 0)){ av_log(s, AV_LOG_ERROR, "Not a Musepack file\n"); return AVERROR_INVALIDDATA; } c->ver = avio_r8(s->pb); if(c->ver != 0x07 && c->ver != 0x17){ av_log(s, AV_LOG_ERROR, "Can demux Musepack SV7, got version %02X\n", c->ver); return AVERROR_INVALIDDATA; } c->fcount = avio_rl32(s->pb); if((int64_t)c->fcount * sizeof(MPCFrame) >= UINT_MAX){ av_log(s, AV_LOG_ERROR, "Too many frames, seeking is not possible\n"); return AVERROR_INVALIDDATA; } if(c->fcount){ c->frames = av_malloc(c->fcount * sizeof(MPCFrame)); if(!c->frames){ av_log(s, AV_LOG_ERROR, "Cannot allocate seektable\n"); return AVERROR(ENOMEM); } }else{ av_log(s, AV_LOG_WARNING, "Container reports no frames\n"); } c->curframe = 0; c->lastframe = -1; c->curbits = 8; c->frames_noted = 0; st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_id = AV_CODEC_ID_MUSEPACK7; st->codec->channels = 2; st->codec->channel_layout = AV_CH_LAYOUT_STEREO; st->codec->bits_per_coded_sample = 16; if (ff_get_extradata(st->codec, s->pb, 16) < 0) return AVERROR(ENOMEM); st->codec->sample_rate = mpc_rate[st->codec->extradata[2] & 3]; avpriv_set_pts_info(st, 32, MPC_FRAMESIZE, st->codec->sample_rate); /* scan for seekpoints */ st->start_time = 0; st->duration = c->fcount; /* try to read APE tags */ if (s->pb->seekable) { int64_t pos = avio_tell(s->pb); ff_ape_parse_tag(s); if (!av_dict_get(s->metadata, "", NULL, AV_DICT_IGNORE_SUFFIX)) ff_id3v1_read(s); avio_seek(s->pb, pos, SEEK_SET); } return 0; }
static int wav_read_packet(AVFormatContext *s, AVPacket *pkt) { int ret, size; int64_t left; AVStream *st; WAVDemuxContext *wav = s->priv_data; if (CONFIG_SPDIF_DEMUXER && wav->spdif == 0 && s->streams[0]->codec->codec_tag == 1) { enum AVCodecID codec; ret = ff_spdif_probe(s->pb->buffer, s->pb->buf_end - s->pb->buffer, &codec); if (ret > AVPROBE_SCORE_EXTENSION) { s->streams[0]->codec->codec_id = codec; wav->spdif = 1; } else { wav->spdif = -1; } } if (CONFIG_SPDIF_DEMUXER && wav->spdif == 1) return ff_spdif_read_packet(s, pkt); if (wav->smv_data_ofs > 0) { int64_t audio_dts, video_dts; smv_retry: audio_dts = s->streams[0]->cur_dts; video_dts = s->streams[1]->cur_dts; if (audio_dts != AV_NOPTS_VALUE && video_dts != AV_NOPTS_VALUE) { /*We always return a video frame first to get the pixel format first*/ wav->smv_last_stream = wav->smv_given_first ? av_compare_ts(video_dts, s->streams[1]->time_base, audio_dts, s->streams[0]->time_base) > 0 : 0; wav->smv_given_first = 1; } wav->smv_last_stream = !wav->smv_last_stream; wav->smv_last_stream |= wav->audio_eof; wav->smv_last_stream &= !wav->smv_eof; if (wav->smv_last_stream) { uint64_t old_pos = avio_tell(s->pb); uint64_t new_pos = wav->smv_data_ofs + wav->smv_block * wav->smv_block_size; if (avio_seek(s->pb, new_pos, SEEK_SET) < 0) { ret = AVERROR_EOF; goto smv_out; } size = avio_rl24(s->pb); ret = av_get_packet(s->pb, pkt, size); if (ret < 0) goto smv_out; pkt->pos -= 3; pkt->pts = wav->smv_block * wav->smv_frames_per_jpeg + wav->smv_cur_pt; wav->smv_cur_pt++; if (wav->smv_frames_per_jpeg > 0) wav->smv_cur_pt %= wav->smv_frames_per_jpeg; if (!wav->smv_cur_pt) wav->smv_block++; pkt->stream_index = 1; smv_out: avio_seek(s->pb, old_pos, SEEK_SET); if (ret == AVERROR_EOF) { wav->smv_eof = 1; goto smv_retry; } return ret; } } st = s->streams[0]; left = wav->data_end - avio_tell(s->pb); if (wav->ignore_length) left = INT_MAX; if (left <= 0) { if (CONFIG_W64_DEMUXER && wav->w64) left = find_guid(s->pb, ff_w64_guid_data) - 24; else left = find_tag(s->pb, MKTAG('d', 'a', 't', 'a')); if (left < 0) { wav->audio_eof = 1; if (wav->smv_data_ofs > 0 && !wav->smv_eof) goto smv_retry; return AVERROR_EOF; } wav->data_end = avio_tell(s->pb) + left; } size = MAX_SIZE; if (st->codec->block_align > 1) { if (size < st->codec->block_align) size = st->codec->block_align; size = (size / st->codec->block_align) * st->codec->block_align; } size = FFMIN(size, left); ret = av_get_packet(s->pb, pkt, size); if (ret < 0) return ret; pkt->stream_index = 0; return ret; }
/* wav input */ static int wav_read_header(AVFormatContext *s) { int64_t size, av_uninit(data_size); int64_t sample_count = 0; int rf64; uint32_t tag; AVIOContext *pb = s->pb; AVStream *st = NULL; WAVDemuxContext *wav = s->priv_data; int ret, got_fmt = 0; int64_t next_tag_ofs, data_ofs = -1; wav->smv_data_ofs = -1; /* check RIFF header */ tag = avio_rl32(pb); rf64 = tag == MKTAG('R', 'F', '6', '4'); if (!rf64 && tag != MKTAG('R', 'I', 'F', 'F')) return AVERROR_INVALIDDATA; avio_rl32(pb); /* file size */ tag = avio_rl32(pb); if (tag != MKTAG('W', 'A', 'V', 'E')) return AVERROR_INVALIDDATA; if (rf64) { if (avio_rl32(pb) != MKTAG('d', 's', '6', '4')) return AVERROR_INVALIDDATA; size = avio_rl32(pb); if (size < 24) return AVERROR_INVALIDDATA; avio_rl64(pb); /* RIFF size */ data_size = avio_rl64(pb); sample_count = avio_rl64(pb); if (data_size < 0 || sample_count < 0) { av_log(s, AV_LOG_ERROR, "negative data_size and/or sample_count in " "ds64: data_size = %"PRId64", sample_count = %"PRId64"\n", data_size, sample_count); return AVERROR_INVALIDDATA; } avio_skip(pb, size - 24); /* skip rest of ds64 chunk */ } for (;;) { AVStream *vst; size = next_tag(pb, &tag); next_tag_ofs = avio_tell(pb) + size; if (url_feof(pb)) break; switch (tag) { case MKTAG('f', 'm', 't', ' '): /* only parse the first 'fmt ' tag found */ if (!got_fmt && (ret = wav_parse_fmt_tag(s, size, &st)) < 0) { return ret; } else if (got_fmt) av_log(s, AV_LOG_WARNING, "found more than one 'fmt ' tag\n"); got_fmt = 1; break; case MKTAG('d', 'a', 't', 'a'): if (!got_fmt) { av_log(s, AV_LOG_ERROR, "found no 'fmt ' tag before the 'data' tag\n"); return AVERROR_INVALIDDATA; } if (rf64) { next_tag_ofs = wav->data_end = avio_tell(pb) + data_size; } else { data_size = size; next_tag_ofs = wav->data_end = size ? next_tag_ofs : INT64_MAX; } data_ofs = avio_tell(pb); /* don't look for footer metadata if we can't seek or if we don't * know where the data tag ends */ if (!pb->seekable || (!rf64 && !size)) goto break_loop; break; case MKTAG('f', 'a', 'c', 't'): if (!sample_count) sample_count = avio_rl32(pb); break; case MKTAG('b', 'e', 'x', 't'): if ((ret = wav_parse_bext_tag(s, size)) < 0) return ret; break; case MKTAG('S','M','V','0'): if (!got_fmt) { av_log(s, AV_LOG_ERROR, "found no 'fmt ' tag before the 'SMV0' tag\n"); return AVERROR_INVALIDDATA; } // SMV file, a wav file with video appended. if (size != MKTAG('0','2','0','0')) { av_log(s, AV_LOG_ERROR, "Unknown SMV version found\n"); goto break_loop; } av_log(s, AV_LOG_DEBUG, "Found SMV data\n"); wav->smv_given_first = 0; vst = avformat_new_stream(s, NULL); if (!vst) return AVERROR(ENOMEM); avio_r8(pb); vst->id = 1; vst->codec->codec_type = AVMEDIA_TYPE_VIDEO; vst->codec->codec_id = AV_CODEC_ID_SMVJPEG; vst->codec->width = avio_rl24(pb); vst->codec->height = avio_rl24(pb); vst->codec->extradata_size = 4; vst->codec->extradata = av_malloc(vst->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); if (!vst->codec->extradata) { av_log(s, AV_LOG_ERROR, "Could not allocate extradata.\n"); return AVERROR(ENOMEM); } size = avio_rl24(pb); wav->smv_data_ofs = avio_tell(pb) + (size - 5) * 3; avio_rl24(pb); wav->smv_block_size = avio_rl24(pb); avpriv_set_pts_info(vst, 32, 1, avio_rl24(pb)); vst->duration = avio_rl24(pb); avio_rl24(pb); avio_rl24(pb); wav->smv_frames_per_jpeg = avio_rl24(pb); AV_WL32(vst->codec->extradata, wav->smv_frames_per_jpeg); wav->smv_cur_pt = 0; goto break_loop; case MKTAG('L', 'I', 'S', 'T'): if (size < 4) { av_log(s, AV_LOG_ERROR, "too short LIST tag\n"); return AVERROR_INVALIDDATA; } switch (avio_rl32(pb)) { case MKTAG('I', 'N', 'F', 'O'): ff_read_riff_info(s, size - 4); } break; } /* seek to next tag unless we know that we'll run into EOF */ if ((avio_size(pb) > 0 && next_tag_ofs >= avio_size(pb)) || wav_seek_tag(pb, next_tag_ofs, SEEK_SET) < 0) { break; } } break_loop: if (data_ofs < 0) { av_log(s, AV_LOG_ERROR, "no 'data' tag found\n"); return AVERROR_INVALIDDATA; } avio_seek(pb, data_ofs, SEEK_SET); if (!sample_count && st->codec->channels && av_get_bits_per_sample(st->codec->codec_id) && wav->data_end <= avio_size(pb)) sample_count = (data_size << 3) / (st->codec->channels * (uint64_t)av_get_bits_per_sample(st->codec->codec_id)); if (sample_count) st->duration = sample_count; ff_metadata_conv_ctx(s, NULL, wav_metadata_conv); ff_metadata_conv_ctx(s, NULL, ff_riff_info_conv); 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; }
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; }
static int tak_read_header(AVFormatContext *s) { TAKDemuxContext *tc = s->priv_data; AVIOContext *pb = s->pb; GetBitContext gb; AVStream *st; uint8_t *buffer = NULL; int ret; st = avformat_new_stream(s, 0); if (!st) return AVERROR(ENOMEM); st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_id = AV_CODEC_ID_TAK; st->need_parsing = AVSTREAM_PARSE_FULL_RAW; tc->mlast_frame = 0; if (avio_rl32(pb) != MKTAG('t', 'B', 'a', 'K')) { avio_seek(pb, -4, SEEK_CUR); return 0; } while (!avio_feof(pb)) { enum TAKMetaDataType type; int size; type = avio_r8(pb) & 0x7f; size = avio_rl24(pb); switch (type) { case TAK_METADATA_STREAMINFO: case TAK_METADATA_LAST_FRAME: case TAK_METADATA_ENCODER: if (size <= 3) return AVERROR_INVALIDDATA; buffer = av_malloc(size - 3 + FF_INPUT_BUFFER_PADDING_SIZE); if (!buffer) return AVERROR(ENOMEM); memset(buffer + size - 3, 0, FF_INPUT_BUFFER_PADDING_SIZE); ffio_init_checksum(pb, tak_check_crc, 0xCE04B7U); if (avio_read(pb, buffer, size - 3) != size - 3) { av_freep(&buffer); return AVERROR(EIO); } if (ffio_get_checksum(s->pb) != avio_rb24(pb)) { av_log(s, AV_LOG_ERROR, "%d metadata block CRC error.\n", type); if (s->error_recognition & AV_EF_EXPLODE) { av_freep(&buffer); return AVERROR_INVALIDDATA; } } init_get_bits8(&gb, buffer, size - 3); break; case TAK_METADATA_MD5: { uint8_t md5[16]; int i; if (size != 19) return AVERROR_INVALIDDATA; ffio_init_checksum(pb, tak_check_crc, 0xCE04B7U); avio_read(pb, md5, 16); if (ffio_get_checksum(s->pb) != avio_rb24(pb)) { av_log(s, AV_LOG_ERROR, "MD5 metadata block CRC error.\n"); if (s->error_recognition & AV_EF_EXPLODE) return AVERROR_INVALIDDATA; } av_log(s, AV_LOG_VERBOSE, "MD5="); for (i = 0; i < 16; i++) av_log(s, AV_LOG_VERBOSE, "%02x", md5[i]); av_log(s, AV_LOG_VERBOSE, "\n"); break; } case TAK_METADATA_END: { int64_t curpos = avio_tell(pb); if (pb->seekable) { ff_ape_parse_tag(s); avio_seek(pb, curpos, SEEK_SET); } tc->data_end += curpos; return 0; } default: ret = avio_skip(pb, size); if (ret < 0) return ret; } if (type == TAK_METADATA_STREAMINFO) { TAKStreamInfo ti; avpriv_tak_parse_streaminfo(&gb, &ti); if (ti.samples > 0) st->duration = ti.samples; st->codec->bits_per_coded_sample = ti.bps; if (ti.ch_layout) st->codec->channel_layout = ti.ch_layout; st->codec->sample_rate = ti.sample_rate; st->codec->channels = ti.channels; st->start_time = 0; avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate); st->codec->extradata = buffer; st->codec->extradata_size = size - 3; buffer = NULL; } else if (type == TAK_METADATA_LAST_FRAME) { if (size != 11) return AVERROR_INVALIDDATA; tc->mlast_frame = 1; tc->data_end = get_bits64(&gb, TAK_LAST_FRAME_POS_BITS) + get_bits(&gb, TAK_LAST_FRAME_SIZE_BITS); av_freep(&buffer); } else if (type == TAK_METADATA_ENCODER) { av_log(s, AV_LOG_VERBOSE, "encoder version: %0X\n", get_bits_long(&gb, TAK_ENCODER_VERSION_BITS)); av_freep(&buffer); } } return AVERROR_EOF; }
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 wav_read_packet(AVFormatContext *s, AVPacket *pkt) { int ret, size; int64_t left; AVStream *st; WAVDemuxContext *wav = s->priv_data; if (wav->smv_data_ofs > 0) { int64_t audio_dts, video_dts; smv_retry: audio_dts = s->streams[0]->cur_dts; video_dts = s->streams[1]->cur_dts; if (audio_dts != AV_NOPTS_VALUE && video_dts != AV_NOPTS_VALUE) { audio_dts = av_rescale_q(audio_dts, s->streams[0]->time_base, AV_TIME_BASE_Q); video_dts = av_rescale_q(video_dts, s->streams[1]->time_base, AV_TIME_BASE_Q); wav->smv_last_stream = video_dts >= audio_dts; } wav->smv_last_stream = !wav->smv_last_stream; wav->smv_last_stream |= wav->audio_eof; wav->smv_last_stream &= !wav->smv_eof; if (wav->smv_last_stream) { uint64_t old_pos = avio_tell(s->pb); uint64_t new_pos = wav->smv_data_ofs + wav->smv_block * wav->smv_block_size; if (avio_seek(s->pb, new_pos, SEEK_SET) < 0) { ret = AVERROR_EOF; goto smv_out; } size = avio_rl24(s->pb); ret = av_get_packet(s->pb, pkt, size); if (ret < 0) goto smv_out; pkt->pos -= 3; pkt->pts = wav->smv_block * wav->smv_frames_per_jpeg; wav->smv_block++; pkt->stream_index = 1; smv_out: avio_seek(s->pb, old_pos, SEEK_SET); if (ret == AVERROR_EOF) { wav->smv_eof = 1; goto smv_retry; } return ret; } } st = s->streams[0]; left = wav->data_end - avio_tell(s->pb); if (wav->ignore_length) left= INT_MAX; if (left <= 0) { if (CONFIG_W64_DEMUXER && wav->w64) left = find_guid(s->pb, guid_data) - 24; else left = find_tag(s->pb, MKTAG('d', 'a', 't', 'a')); if (left < 0) { wav->audio_eof = 1; if (wav->smv_data_ofs > 0 && !wav->smv_eof) goto smv_retry; return AVERROR_EOF; } wav->data_end= avio_tell(s->pb) + left; } size = MAX_SIZE; if (st->codec->block_align > 1) { if (size < st->codec->block_align) size = st->codec->block_align; size = (size / st->codec->block_align) * st->codec->block_align; } size = FFMIN(size, left); ret = av_get_packet(s->pb, pkt, size); if (ret < 0) return ret; pkt->stream_index = 0; return ret; }