X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavformat%2Fvividas.c;h=36c007b0d269b115b27205906f1c5d8f370439f9;hb=2a19232c1996fee52a3f4201fa379001627dcc89;hp=ab3947815a5ca92b238fae65d0b0e9929d88476d;hpb=114ddf64300fa78663ef35decbee89b5492abb1d;p=ffmpeg diff --git a/libavformat/vividas.c b/libavformat/vividas.c index ab3947815a5..36c007b0d26 100644 --- a/libavformat/vividas.c +++ b/libavformat/vividas.c @@ -52,6 +52,7 @@ typedef struct VIV_AudioSubpacket { typedef struct VividasDemuxContext { int n_sb_blocks; VIV_SB_block *sb_blocks; + int num_audio; uint32_t sb_key; int64_t sb_offset; @@ -277,15 +278,13 @@ static uint8_t *read_sb_block(AVIOContext *src, unsigned *size, static int track_header(VividasDemuxContext *viv, AVFormatContext *s, uint8_t *buf, int size) { - int i,j; + int i, j, ret; int64_t off; int val_1; - int num_video, num_audio; - AVIOContext *pb; + int num_video; + AVIOContext pb0, *pb = &pb0; - pb = avio_alloc_context(buf, size, 0, NULL, NULL, NULL, NULL); - if (!pb) - return AVERROR(ENOMEM); + ffio_init_context(pb, buf, size, 0, NULL, NULL, NULL, NULL); ffio_read_varlen(pb); // track_header_len avio_r8(pb); // '1' @@ -295,6 +294,8 @@ static int track_header(VividasDemuxContext *viv, AVFormatContext *s, uint8_t * for (i=0;iid = i; @@ -338,15 +343,17 @@ static int track_header(VividasDemuxContext *viv, AVFormatContext *s, uint8_t * off = avio_tell(pb); off += ffio_read_varlen(pb); // val_10 avio_r8(pb); // '4' - num_audio = avio_r8(pb); + viv->num_audio = avio_r8(pb); avio_seek(pb, off, SEEK_SET); - if (num_audio != 1) - av_log(s, AV_LOG_WARNING, "number of audio tracks %d is not 1\n", num_audio); + if (viv->num_audio != 1) + av_log(s, AV_LOG_WARNING, "number of audio tracks %d is not 1\n", viv->num_audio); - for(i=0;inum_audio;i++) { int q; AVStream *st = avformat_new_stream(s, NULL); + if (!st) + return AVERROR(ENOMEM); st->id = num_video + i; @@ -378,18 +385,15 @@ static int track_header(VividasDemuxContext *viv, AVFormatContext *s, uint8_t * for (j = 0; j < num_data; j++) { uint64_t len = ffio_read_varlen(pb); if (len > INT_MAX/2 - xd_size) { - av_free(pb); return AVERROR_INVALIDDATA; } data_len[j] = len; xd_size += len; } - st->codecpar->extradata_size = 64 + xd_size + xd_size / 255; - if (ff_alloc_extradata(st->codecpar, st->codecpar->extradata_size)) { - av_free(pb); - return AVERROR(ENOMEM); - } + ret = ff_alloc_extradata(st->codecpar, 64 + xd_size + xd_size / 255); + if (ret < 0) + return ret; p = st->codecpar->extradata; p[0] = 2; @@ -397,7 +401,6 @@ static int track_header(VividasDemuxContext *viv, AVFormatContext *s, uint8_t * for (j = 0; j < num_data - 1; j++) { unsigned delta = av_xiphlacing(&p[offset], data_len[j]); if (delta > data_len[j]) { - av_free(pb); return AVERROR_INVALIDDATA; } offset += delta; @@ -418,7 +421,6 @@ static int track_header(VividasDemuxContext *viv, AVFormatContext *s, uint8_t * } } - av_free(pb); return 0; } @@ -427,25 +429,23 @@ static int track_index(VividasDemuxContext *viv, AVFormatContext *s, uint8_t *bu int64_t off; int64_t poff; int maxnp=0; - AVIOContext *pb; + AVIOContext pb0, *pb = &pb0; int i; int64_t filesize = avio_size(s->pb); + uint64_t n_sb_blocks_tmp; - pb = avio_alloc_context(buf, size, 0, NULL, NULL, NULL, NULL); - if (!pb) - return AVERROR(ENOMEM); + ffio_init_context(pb, buf, size, 0, NULL, NULL, NULL, NULL); ffio_read_varlen(pb); // track_index_len avio_r8(pb); // 'c' - viv->n_sb_blocks = ffio_read_varlen(pb); - if (viv->n_sb_blocks < 0 || viv->n_sb_blocks > size / 2) - goto error; - viv->sb_blocks = av_calloc(viv->n_sb_blocks, sizeof(VIV_SB_block)); + n_sb_blocks_tmp = ffio_read_varlen(pb); + if (n_sb_blocks_tmp > size / 2) + return AVERROR_INVALIDDATA; + viv->sb_blocks = av_calloc(n_sb_blocks_tmp, sizeof(*viv->sb_blocks)); if (!viv->sb_blocks) { - viv->n_sb_blocks = 0; - av_free(pb); return AVERROR(ENOMEM); } + viv->n_sb_blocks = n_sb_blocks_tmp; off = 0; poff = 0; @@ -455,7 +455,7 @@ static int track_index(VividasDemuxContext *viv, AVFormatContext *s, uint8_t *bu uint64_t n_packets_tmp = ffio_read_varlen(pb); if (size_tmp > INT_MAX || n_packets_tmp > INT_MAX) - goto error; + return AVERROR_INVALIDDATA; viv->sb_blocks[i].byte_offset = off; viv->sb_blocks[i].packet_offset = poff; @@ -471,17 +471,13 @@ static int track_index(VividasDemuxContext *viv, AVFormatContext *s, uint8_t *bu } if (filesize > 0 && poff > filesize) - goto error; + return AVERROR_INVALIDDATA; viv->sb_entries = av_calloc(maxnp, sizeof(VIV_SB_entry)); - av_free(pb); + if (!viv->sb_entries) + return AVERROR(ENOMEM); return 0; -error: - av_free(pb); - viv->n_sb_blocks = 0; - av_freep(&viv->sb_blocks); - return AVERROR_INVALIDDATA; } static void load_sb_block(AVFormatContext *s, VividasDemuxContext *viv, unsigned expected_size) @@ -610,7 +606,7 @@ static int viv_read_header(AVFormatContext *s) ret = track_index(viv, s, buf, v); av_free(buf); if (ret < 0) - return ret; + goto fail; viv->sb_offset = avio_tell(pb); if (viv->n_sb_blocks > 0) { @@ -621,6 +617,9 @@ static int viv_read_header(AVFormatContext *s) } return 0; +fail: + av_freep(&viv->sb_blocks); + return ret; } static int viv_read_packet(AVFormatContext *s, @@ -649,7 +648,7 @@ static int viv_read_packet(AVFormatContext *s, pkt->stream_index = 1; astream = s->streams[pkt->stream_index]; - pkt->pts = av_rescale(viv->audio_sample, astream->time_base.den, astream->time_base.num) / astream->codecpar->sample_rate; + pkt->pts = av_rescale_q(viv->audio_sample, av_make_q(1, astream->codecpar->sample_rate), astream->time_base); viv->audio_sample += viv->audio_subpackets[viv->current_audio_subpacket].pcm_bytes / 2 / astream->codecpar->channels; pkt->flags |= AV_PKT_FLAG_KEY; viv->current_audio_subpacket++; @@ -674,6 +673,9 @@ static int viv_read_packet(AVFormatContext *s, if (viv->sb_entries[viv->current_sb_entry].flag == 0) { uint64_t v_size = ffio_read_varlen(pb); + if (!viv->num_audio) + return AVERROR_INVALIDDATA; + ffio_read_varlen(pb); if (v_size > INT_MAX) return AVERROR_INVALIDDATA;