/* wav input */ static int wav_read_header(AVFormatContext *s, AVFormatParameters *ap) { int64_t size, av_uninit(data_size); int rf64; unsigned int tag; ByteIOContext *pb = s->pb; AVStream *st; WAVContext *wav = s->priv_data; /* check RIFF header */ tag = get_le32(pb); rf64 = tag == MKTAG('R', 'F', '6', '4'); if (!rf64 && tag != MKTAG('R', 'I', 'F', 'F')) return -1; get_le32(pb); /* file size */ tag = get_le32(pb); if (tag != MKTAG('W', 'A', 'V', 'E')) return -1; if (rf64) { if (get_le32(pb) != MKTAG('d', 's', '6', '4')) return -1; size = get_le32(pb); if (size < 16) return -1; get_le64(pb); /* RIFF size */ data_size = get_le64(pb); url_fskip(pb, size - 16); /* skip rest of ds64 chunk */ } /* parse fmt header */ size = find_tag(pb, MKTAG('f', 'm', 't', ' ')); if (size < 0) return -1; st = av_new_stream(s, 0); if (!st) return AVERROR(ENOMEM); ff_get_wav_header(pb, st->codec, size); st->need_parsing = AVSTREAM_PARSE_FULL; av_set_pts_info(st, 64, 1, st->codec->sample_rate); size = find_tag(pb, MKTAG('d', 'a', 't', 'a')); if (rf64) size = data_size; if (size < 0) return -1; if (!size) { wav->data_end = INT64_MAX; } else wav->data_end= url_ftell(pb) + size; return 0; }
static int w64_read_header(AVFormatContext *s) { int64_t size; AVIOContext *pb = s->pb; WAVDemuxContext *wav = s->priv_data; AVStream *st; uint8_t guid[16]; int ret; avio_read(pb, guid, 16); if (memcmp(guid, guid_riff, 16)) return AVERROR_INVALIDDATA; /* riff + wave + fmt + sizes */ if (avio_rl64(pb) < 16 + 8 + 16 + 8 + 16 + 8) return AVERROR_INVALIDDATA; avio_read(pb, guid, 16); if (memcmp(guid, guid_wave, 16)) { av_log(s, AV_LOG_ERROR, "could not find wave guid\n"); return AVERROR_INVALIDDATA; } size = find_guid(pb, guid_fmt); if (size < 0) { av_log(s, AV_LOG_ERROR, "could not find fmt guid\n"); return AVERROR_INVALIDDATA; } st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); /* subtract chunk header size - normal wav file doesn't count it */ ret = ff_get_wav_header(s, pb, st->codecpar, size - 24); if (ret < 0) return ret; avio_skip(pb, FFALIGN(size, INT64_C(8)) - size); st->need_parsing = AVSTREAM_PARSE_FULL; avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate); size = find_guid(pb, guid_data); if (size < 0) { av_log(s, AV_LOG_ERROR, "could not find data guid\n"); return AVERROR_INVALIDDATA; } wav->data_end = avio_tell(pb) + size - 24; wav->w64 = 1; return 0; }
static int w64_read_header(AVFormatContext *s, AVFormatParameters *ap) { int64_t size; ByteIOContext *pb = s->pb; WAVContext *wav = s->priv_data; AVStream *st; uint8_t guid[16]; get_buffer(pb, guid, 16); if (memcmp(guid, guid_riff, 16)) return -1; if (get_le64(pb) < 16 + 8 + 16 + 8 + 16 + 8) /* riff + wave + fmt + sizes */ return -1; get_buffer(pb, guid, 16); if (memcmp(guid, guid_wave, 16)) { av_log(s, AV_LOG_ERROR, "could not find wave guid\n"); return -1; } size = find_guid(pb, guid_fmt); if (size < 0) { av_log(s, AV_LOG_ERROR, "could not find fmt guid\n"); return -1; } st = av_new_stream(s, 0); if (!st) return AVERROR(ENOMEM); /* subtract chunk header size - normal wav file doesn't count it */ ff_get_wav_header(pb, st->codec, size - 24); url_fskip(pb, FFALIGN(size, INT64_C(8)) - size); st->need_parsing = AVSTREAM_PARSE_FULL; av_set_pts_info(st, 64, 1, st->codec->sample_rate); size = find_guid(pb, guid_data); if (size < 0) { av_log(s, AV_LOG_ERROR, "could not find data guid\n"); return -1; } wav->data_end = url_ftell(pb) + size - 24; wav->w64 = 1; return 0; }
static int read_header(AVFormatContext *s, AVFormatParameters *ap) { ACTContext* ctx = s->priv_data; AVIOContext *pb = s->pb; int size; AVStream* st; int min,sec,msec; st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); avio_skip(pb, 16); size=avio_rl32(pb); ff_get_wav_header(pb, st->codec, size); /* 8000Hz (Fine-rec) file format has 10 bytes long packets with 10ms of sound data in them */ if (st->codec->sample_rate != 8000) { av_log(s, AV_LOG_ERROR, "Sample rate %d is not supported.\n", st->codec->sample_rate); return AVERROR_INVALIDDATA; } st->codec->frame_size=80; st->codec->channels=1; av_set_pts_info(st, 64, 1, 100); st->codec->codec_id=CODEC_ID_G729; avio_seek(pb, 257, SEEK_SET); msec=avio_rl16(pb); sec=avio_r8(pb); min=avio_rl32(pb); st->duration = av_rescale(1000*(min*60+sec)+msec, st->codec->sample_rate, 1000 * st->codec->frame_size); ctx->bytes_left_in_chunk=CHUNK_SIZE; avio_seek(pb, 512, SEEK_SET); return 0; }
static int wav_parse_fmt_tag(AVFormatContext *s, int64_t size, AVStream **st) { AVIOContext *pb = s->pb; int ret; /* parse fmt header */ *st = av_new_stream(s, 0); if (!*st) return AVERROR(ENOMEM); ret = ff_get_wav_header(pb, (*st)->codec, size); if (ret < 0) return ret; (*st)->need_parsing = AVSTREAM_PARSE_FULL; av_set_pts_info(*st, 64, 1, (*st)->codec->sample_rate); return 0; }
/* wav input */ static int wav_read_header(AVFormatContext *s, AVFormatParameters *ap) { int64_t size; unsigned int tag; ByteIOContext *pb = s->pb; AVStream *st; WAVContext *wav = s->priv_data; /* check RIFF header */ tag = get_le32(pb); if (tag != MKTAG('R', 'I', 'F', 'F')) return -1; get_le32(pb); /* file size */ tag = get_le32(pb); if (tag != MKTAG('W', 'A', 'V', 'E')) return -1; /* parse fmt header */ size = find_tag(pb, MKTAG('f', 'm', 't', ' ')); if (size < 0) return -1; st = av_new_stream(s, 0); if (!st) return AVERROR(ENOMEM); ff_get_wav_header(pb, st->codec, size); st->need_parsing = AVSTREAM_PARSE_FULL; av_set_pts_info(st, 64, 1, st->codec->sample_rate); size = find_tag(pb, MKTAG('d', 'a', 't', 'a')); if (size < 0) return -1; wav->data_end= url_ftell(pb) + size; return 0; }
static int dxa_read_header(AVFormatContext *s, AVFormatParameters *ap) { AVIOContext *pb = s->pb; DXAContext *c = s->priv_data; AVStream *st, *ast; uint32_t tag; int32_t fps; int w, h; int num, den; int flags; tag = avio_rl32(pb); if (tag != MKTAG('D', 'E', 'X', 'A')) return -1; flags = avio_r8(pb); c->frames = avio_rb16(pb); if(!c->frames){ av_log(s, AV_LOG_ERROR, "File contains no frames ???\n"); return -1; } fps = avio_rb32(pb); if(fps > 0){ den = 1000; num = fps; }else if (fps < 0){ den = 100000; num = -fps; }else{ den = 10; num = 1; } w = avio_rb16(pb); h = avio_rb16(pb); c->has_sound = 0; st = av_new_stream(s, 0); if (!st) return -1; // Parse WAV data header if(avio_rl32(pb) == MKTAG('W', 'A', 'V', 'E')){ uint32_t size, fsize; c->has_sound = 1; size = avio_rb32(pb); c->vidpos = avio_tell(pb) + size; avio_seek(pb, 16, SEEK_CUR); fsize = avio_rl32(pb); ast = av_new_stream(s, 0); if (!ast) return -1; ff_get_wav_header(pb, ast->codec, fsize); // find 'data' chunk while(avio_tell(pb) < c->vidpos && !url_feof(pb)){ tag = avio_rl32(pb); fsize = avio_rl32(pb); if(tag == MKTAG('d', 'a', 't', 'a')) break; avio_seek(pb, fsize, SEEK_CUR); } c->bpc = (fsize + c->frames - 1) / c->frames; if(ast->codec->block_align) c->bpc = ((c->bpc + ast->codec->block_align - 1) / ast->codec->block_align) * ast->codec->block_align; c->bytes_left = fsize; c->wavpos = avio_tell(pb); avio_seek(pb, c->vidpos, SEEK_SET); } /* now we are ready: build format streams */ st->codec->codec_type = AVMEDIA_TYPE_VIDEO; st->codec->codec_id = CODEC_ID_DXA; st->codec->width = w; st->codec->height = h; av_reduce(&den, &num, den, num, (1UL<<31)-1); av_set_pts_info(st, 33, num, den); /* flags & 0x80 means that image is interlaced, * flags & 0x40 means that image has double height * either way set true height */ if(flags & 0xC0){ st->codec->height >>= 1; }
static int xwma_read_header(AVFormatContext *s) { int64_t size; int ret; uint32_t dpds_table_size = 0; uint32_t *dpds_table = NULL; unsigned int tag; AVIOContext *pb = s->pb; AVStream *st; XWMAContext *xwma = s->priv_data; int i; /* The following code is mostly copied from wav.c, with some * minor alterations. */ /* check RIFF header */ tag = avio_rl32(pb); if (tag != MKTAG('R', 'I', 'F', 'F')) return -1; avio_rl32(pb); /* file size */ tag = avio_rl32(pb); if (tag != MKTAG('X', 'W', 'M', 'A')) return -1; /* parse fmt header */ tag = avio_rl32(pb); if (tag != MKTAG('f', 'm', 't', ' ')) return -1; size = avio_rl32(pb); st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); ret = ff_get_wav_header(pb, st->codec, size); if (ret < 0) return ret; st->need_parsing = AVSTREAM_PARSE_NONE; /* All xWMA files I have seen contained WMAv2 data. If there are files * using WMA Pro or some other codec, then we need to figure out the right * extradata for that. Thus, ask the user for feedback, but try to go on * anyway. */ if (st->codec->codec_id != AV_CODEC_ID_WMAV2) { avpriv_request_sample(s, "Unexpected codec (tag 0x04%x; id %d)", st->codec->codec_tag, st->codec->codec_id); } else { /* In all xWMA files I have seen, there is no extradata. But the WMA * codecs require extradata, so we provide our own fake extradata. * * First, check that there really was no extradata in the header. If * there was, then try to use it, after asking the user to provide a * sample of this unusual file. */ if (st->codec->extradata_size != 0) { /* Surprise, surprise: We *did* get some extradata. No idea * if it will work, but just go on and try it, after asking * the user for a sample. */ avpriv_request_sample(s, "Unexpected extradata (%d bytes)", st->codec->extradata_size); } else { st->codec->extradata_size = 6; st->codec->extradata = av_mallocz(6 + FF_INPUT_BUFFER_PADDING_SIZE); if (!st->codec->extradata) return AVERROR(ENOMEM); /* setup extradata with our experimentally obtained value */ st->codec->extradata[4] = 31; } } if (!st->codec->channels) { av_log(s, AV_LOG_WARNING, "Invalid channel count: %d\n", st->codec->channels); return AVERROR_INVALIDDATA; } if (!st->codec->bits_per_coded_sample) { av_log(s, AV_LOG_WARNING, "Invalid bits_per_coded_sample: %d\n", st->codec->bits_per_coded_sample); return AVERROR_INVALIDDATA; } /* set the sample rate */ avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate); /* parse the remaining RIFF chunks */ for (;;) { if (pb->eof_reached) { ret = AVERROR_EOF; goto end; } /* read next chunk tag */ tag = avio_rl32(pb); size = avio_rl32(pb); if (tag == MKTAG('d', 'a', 't', 'a')) { /* We assume that the data chunk comes last. */ break; } else if (tag == MKTAG('d','p','d','s')) { /* Quoting the MSDN xWMA docs on the dpds chunk: "Contains the * decoded packet cumulative data size array, each element is the * number of bytes accumulated after the corresponding xWMA packet * is decoded in order." * * Each packet has size equal to st->codec->block_align, which in * all cases I saw so far was always 2230. Thus, we can use the * dpds data to compute a seeking index. */ /* Error out if there is more than one dpds chunk. */ if (dpds_table) { av_log(s, AV_LOG_ERROR, "two dpds chunks present\n"); ret = AVERROR_INVALIDDATA; goto end; } /* Compute the number of entries in the dpds chunk. */ if (size & 3) { /* Size should be divisible by four */ av_log(s, AV_LOG_WARNING, "dpds chunk size %"PRId64" not divisible by 4\n", size); } dpds_table_size = size / 4; if (dpds_table_size == 0 || dpds_table_size >= INT_MAX / 4) { av_log(s, AV_LOG_ERROR, "dpds chunk size %"PRId64" invalid\n", size); return AVERROR_INVALIDDATA; } /* Allocate some temporary storage to keep the dpds data around. * for processing later on. */ dpds_table = av_malloc(dpds_table_size * sizeof(uint32_t)); if (!dpds_table) { return AVERROR(ENOMEM); } for (i = 0; i < dpds_table_size; ++i) { dpds_table[i] = avio_rl32(pb); size -= 4; } } avio_skip(pb, size); } /* Determine overall data length */ if (size < 0) { ret = AVERROR_INVALIDDATA; goto end; } if (!size) { xwma->data_end = INT64_MAX; } else xwma->data_end = avio_tell(pb) + size; if (dpds_table && dpds_table_size) { int64_t cur_pos; const uint32_t bytes_per_sample = (st->codec->channels * st->codec->bits_per_coded_sample) >> 3; /* Estimate the duration from the total number of output bytes. */ const uint64_t total_decoded_bytes = dpds_table[dpds_table_size - 1]; if (!bytes_per_sample) { av_log(s, AV_LOG_ERROR, "Invalid bits_per_coded_sample %d for %d channels\n", st->codec->bits_per_coded_sample, st->codec->channels); ret = AVERROR_INVALIDDATA; goto end; } st->duration = total_decoded_bytes / bytes_per_sample; /* Use the dpds data to build a seek table. We can only do this after * we know the offset to the data chunk, as we need that to determine * the actual offset to each input block. * Note: If we allowed ourselves to assume that the data chunk always * follows immediately after the dpds block, we could of course guess * the data block's start offset already while reading the dpds chunk. * I decided against that, just in case other chunks ever are * discovered. */ cur_pos = avio_tell(pb); for (i = 0; i < dpds_table_size; ++i) { /* From the number of output bytes that would accumulate in the * output buffer after decoding the first (i+1) packets, we compute * an offset / timestamp pair. */ av_add_index_entry(st, cur_pos + (i+1) * st->codec->block_align, /* pos */ dpds_table[i] / bytes_per_sample, /* timestamp */ st->codec->block_align, /* size */ 0, /* duration */ AVINDEX_KEYFRAME); } } else if (st->codec->bit_rate) {
static int w64_read_header(AVFormatContext *s) { int64_t size, data_ofs = 0; AVIOContext *pb = s->pb; WAVDemuxContext *wav = s->priv_data; AVStream *st; uint8_t guid[16]; int ret; avio_read(pb, guid, 16); if (memcmp(guid, ff_w64_guid_riff, 16)) return AVERROR_INVALIDDATA; /* riff + wave + fmt + sizes */ if (avio_rl64(pb) < 16 + 8 + 16 + 8 + 16 + 8) return AVERROR_INVALIDDATA; avio_read(pb, guid, 16); if (memcmp(guid, ff_w64_guid_wave, 16)) { av_log(s, AV_LOG_ERROR, "could not find wave guid\n"); return AVERROR_INVALIDDATA; } wav->w64 = 1; st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); while (!url_feof(pb)) { if (avio_read(pb, guid, 16) != 16) break; size = avio_rl64(pb); if (size <= 24 || INT64_MAX - size < avio_tell(pb)) return AVERROR_INVALIDDATA; if (!memcmp(guid, ff_w64_guid_fmt, 16)) { /* subtract chunk header size - normal wav file doesn't count it */ ret = ff_get_wav_header(pb, st->codec, size - 24); if (ret < 0) return ret; avio_skip(pb, FFALIGN(size, INT64_C(8)) - size); avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate); } else if (!memcmp(guid, ff_w64_guid_fact, 16)) { int64_t samples; samples = avio_rl64(pb); if (samples > 0) st->duration = samples; } else if (!memcmp(guid, ff_w64_guid_data, 16)) { wav->data_end = avio_tell(pb) + size - 24; data_ofs = avio_tell(pb); if (!pb->seekable) break; avio_skip(pb, size - 24); } else if (!memcmp(guid, ff_w64_guid_summarylist, 16)) { int64_t start, end, cur; uint32_t count, chunk_size, i; start = avio_tell(pb); end = start + size; count = avio_rl32(pb); for (i = 0; i < count; i++) { char chunk_key[5], *value; if (url_feof(pb) || (cur = avio_tell(pb)) < 0 || cur > end - 8 /* = tag + size */) break; chunk_key[4] = 0; avio_read(pb, chunk_key, 4); chunk_size = avio_rl32(pb); value = av_mallocz(chunk_size + 1); if (!value) return AVERROR(ENOMEM); ret = avio_get_str16le(pb, chunk_size, value, chunk_size); avio_skip(pb, chunk_size - ret); av_dict_set(&s->metadata, chunk_key, value, AV_DICT_DONT_STRDUP_VAL); } avio_skip(pb, end - avio_tell(pb)); } else { av_log(s, AV_LOG_DEBUG, "unknown guid: "FF_PRI_GUID"\n", FF_ARG_GUID(guid)); avio_skip(pb, size - 24); } } if (!data_ofs) return AVERROR_EOF; ff_metadata_conv_ctx(s, NULL, wav_metadata_conv); ff_metadata_conv_ctx(s, NULL, ff_riff_info_conv); handle_stream_probing(st); st->need_parsing = AVSTREAM_PARSE_FULL_RAW; avio_seek(pb, data_ofs, SEEK_SET); return 0; }
/* wav input */ static int wav_read_header(AVFormatContext *s, AVFormatParameters *ap) { int64_t size, av_uninit(data_size); int64_t sample_count=0; int rf64; unsigned int tag; AVIOContext *pb = s->pb; AVStream *st; WAVContext *wav = s->priv_data; /* check RIFF header */ tag = avio_rl32(pb); rf64 = tag == MKTAG('R', 'F', '6', '4'); if (!rf64 && tag != MKTAG('R', 'I', 'F', 'F')) return -1; avio_rl32(pb); /* file size */ tag = avio_rl32(pb); if (tag != MKTAG('W', 'A', 'V', 'E')) return -1; if (rf64) { if (avio_rl32(pb) != MKTAG('d', 's', '6', '4')) return -1; size = avio_rl32(pb); if (size < 16) return -1; avio_rl64(pb); /* RIFF size */ data_size = avio_rl64(pb); sample_count = avio_rl64(pb); avio_seek(pb, size - 16, SEEK_CUR); /* skip rest of ds64 chunk */ } /* parse fmt header */ size = find_tag(pb, MKTAG('f', 'm', 't', ' ')); if (size < 0) return -1; st = av_new_stream(s, 0); if (!st) return AVERROR(ENOMEM); ff_get_wav_header(pb, st->codec, size); st->need_parsing = AVSTREAM_PARSE_FULL; av_set_pts_info(st, 64, 1, st->codec->sample_rate); for (;;) { if (url_feof(pb)) return -1; size = next_tag(pb, &tag); if (tag == MKTAG('d', 'a', 't', 'a')){ break; }else if (tag == MKTAG('f','a','c','t') && !sample_count){ sample_count = avio_rl32(pb); size -= 4; } avio_seek(pb, size, SEEK_CUR); } if (rf64) size = data_size; if (size < 0) return -1; if (!size) { wav->data_end = INT64_MAX; } else wav->data_end= avio_tell(pb) + size; if (!sample_count && st->codec->channels && av_get_bits_per_sample(st->codec->codec_id)) sample_count = (size<<3) / (st->codec->channels * (uint64_t)av_get_bits_per_sample(st->codec->codec_id)); if (sample_count) st->duration = sample_count; return 0; }