uint32_t size, asize, start = 0;
AVStream *st;
int ret = AVERROR_EOF;
+ int loop = 0;
int bfstm = !strcmp("bfstm", s->iformat->name);
st = avformat_new_stream(s, NULL);
if (avio_rl32(s->pb) != MKTAG('H','E','A','D'))
return AVERROR_INVALIDDATA;
} else {
- uint32_t info_offset = 0, info_size;
+ uint32_t info_offset = 0;
uint16_t section_count, header_size, i;
header_size = read16(s); // 6
switch (flag) {
case 0x4000:
info_offset = read32(s);
- info_size = read32(s);
+ /*info_size =*/ read32(s);
break;
case 0x4001:
avio_skip(s->pb, 4); // seek offset
return AVERROR_PATCHWELCOME;
}
- avio_skip(s->pb, 1); // loop flag
+ loop = avio_r8(s->pb); // loop flag
st->codec->codec_id = codec;
st->codec->channels = avio_r8(s->pb);
if (!st->codec->channels)
if (!bfstm)
avio_skip(s->pb, 2); // padding
- avio_skip(s->pb, 4); // loop start sample
+
+ if (loop) {
+ if (av_dict_set_int(&s->metadata, "loop_start",
+ av_rescale(read32(s), AV_TIME_BASE,
+ st->codec->sample_rate),
+ 0) < 0)
+ return AVERROR(ENOMEM);
+ } else {
+ avio_skip(s->pb, 4);
+ }
+
st->start_time = 0;
st->duration = read32(s);
avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
b->data_start = avio_tell(s->pb);
- if ((major != 1 || minor) && !bfstm)
+ if (!bfstm && (major != 1 || minor))
avpriv_request_sample(s, "Version %d.%d", major, minor);
return 0;
size = b->last_block_used_bytes;
samples = b->last_block_samples;
skip = b->last_block_size - b->last_block_used_bytes;
+
+ if (samples < size * 14 / 8) {
+ uint32_t adjusted_size = samples / 14 * 8;
+ if (samples % 14)
+ adjusted_size += (samples % 14 + 1) / 2 + 1;
+
+ skip += size - adjusted_size;
+ size = adjusted_size;
+ }
} else if (b->current_block < b->block_count) {
size = b->block_size;
samples = b->samples_per_block;