* @sa http://wiki.multimedia.cx/index.php?title=Vividas_VIV
*/
+#include "libavutil/avassert.h"
#include "libavutil/intreadwrite.h"
#include "avio_internal.h"
#include "avformat.h"
*size = n;
n -= 8;
- if (avio_read(src, buf+8, n) < n) {
+ if (avio_read(src, buf+8, n) != n) {
av_free(buf);
return NULL;
}
avio_rl16(pb); //codec_subid
st->codecpar->channels = avio_rl16(pb); // channels
st->codecpar->sample_rate = avio_rl32(pb); // sample_rate
+ if (st->codecpar->sample_rate <= 0 || st->codecpar->channels <= 0)
+ return AVERROR_INVALIDDATA;
avio_seek(pb, 10, SEEK_CUR); // data_1
q = avio_r8(pb);
avio_seek(pb, q, SEEK_CUR); // data_2
if (avio_tell(pb) < off) {
int num_data;
- int xd_size = 0;
+ int xd_size = 1;
int data_len[256];
int offset = 1;
uint8_t *p;
ffio_read_varlen(pb); // len_3
num_data = avio_r8(pb);
for (j = 0; j < num_data; j++) {
- uint64_t len = ffio_read_varlen(pb);
- if (len > INT_MAX/2 - xd_size) {
+ int64_t len = ffio_read_varlen(pb);
+ if (len < 0 || len > INT_MAX/2 - xd_size) {
return AVERROR_INVALIDDATA;
}
data_len[j] = len;
- xd_size += len;
+ xd_size += len + 1 + len/255;
}
- ret = ff_alloc_extradata(st->codecpar, 64 + xd_size + xd_size / 255);
+ ret = ff_alloc_extradata(st->codecpar, xd_size);
if (ret < 0)
return ret;
for (j = 0; j < num_data - 1; j++) {
unsigned delta = av_xiphlacing(&p[offset], data_len[j]);
- if (delta > data_len[j]) {
- return AVERROR_INVALIDDATA;
- }
+ av_assert0(delta <= xd_size - offset);
offset += delta;
}
av_freep(&st->codecpar->extradata);
break;
}
+ av_assert0(data_len[j] <= xd_size - offset);
offset += data_len[j];
}
for (int i = 0; i < viv->n_sb_blocks; i++) {
if (frame >= viv->sb_blocks[i].packet_offset && frame < viv->sb_blocks[i].packet_offset + viv->sb_blocks[i].n_packets) {
- // flush audio packet queue
- viv->current_audio_subpacket = 0;
- viv->n_audio_subpackets = 0;
viv->current_sb = i;
// seek to ith sb block
avio_seek(s->pb, viv->sb_offset + viv->sb_blocks[i].byte_offset, SEEK_SET);
// load the block
load_sb_block(s, viv, 0);
- // most problematic part: guess audio offset
- viv->audio_sample = av_rescale_q(viv->sb_blocks[i].packet_offset, av_make_q(s->streams[1]->codecpar->sample_rate, 1), av_inv_q(s->streams[0]->time_base));
- // hand-tuned 1.s a/v offset
- viv->audio_sample += s->streams[1]->codecpar->sample_rate;
+ if (viv->num_audio) {
+ const AVCodecParameters *par = s->streams[1]->codecpar;
+ // flush audio packet queue
+ viv->current_audio_subpacket = 0;
+ viv->n_audio_subpackets = 0;
+ // most problematic part: guess audio offset
+ viv->audio_sample = av_rescale_q(viv->sb_blocks[i].packet_offset,
+ av_make_q(par->sample_rate, 1),
+ av_inv_q(s->streams[0]->time_base));
+ // hand-tuned 1.s a/v offset
+ viv->audio_sample += par->sample_rate;
+ }
viv->current_sb_entry = 0;
return 1;
}