summaryrefslogtreecommitdiff
path: root/libavformat/wavenc.c
diff options
context:
space:
mode:
Diffstat (limited to 'libavformat/wavenc.c')
-rw-r--r--libavformat/wavenc.c53
1 files changed, 29 insertions, 24 deletions
diff --git a/libavformat/wavenc.c b/libavformat/wavenc.c
index 078b7fcd9a..563a30d005 100644
--- a/libavformat/wavenc.c
+++ b/libavformat/wavenc.c
@@ -50,8 +50,6 @@
#define RF64_NEVER 0
#define RF64_ALWAYS 1
-#define PEAK_BUFFER_SIZE 1024
-
typedef enum {
PEAK_OFF = 0,
PEAK_ON,
@@ -72,8 +70,9 @@ typedef struct WAVMuxContext {
int64_t maxpts;
int16_t *peak_maxpos, *peak_maxneg;
uint32_t peak_num_frames;
- uint32_t peak_outbuf_size;
+ unsigned peak_outbuf_size;
uint32_t peak_outbuf_bytes;
+ unsigned size_increment;
uint8_t *peak_output;
int last_duration;
int write_bext;
@@ -171,15 +170,15 @@ static av_cold int peak_init_writer(AVFormatContext *s)
"Writing 16 bit peak for 8 bit audio does not make sense\n");
return AVERROR(EINVAL);
}
+ if (par->channels > INT_MAX / (wav->peak_bps * wav->peak_ppv))
+ return AVERROR(ERANGE);
+ wav->size_increment = par->channels * wav->peak_bps * wav->peak_ppv;
wav->peak_maxpos = av_mallocz_array(par->channels, sizeof(*wav->peak_maxpos));
wav->peak_maxneg = av_mallocz_array(par->channels, sizeof(*wav->peak_maxneg));
- wav->peak_output = av_malloc(PEAK_BUFFER_SIZE);
- if (!wav->peak_maxpos || !wav->peak_maxneg || !wav->peak_output)
+ if (!wav->peak_maxpos || !wav->peak_maxneg)
goto nomem;
- wav->peak_outbuf_size = PEAK_BUFFER_SIZE;
-
return 0;
nomem:
@@ -187,14 +186,24 @@ nomem:
return AVERROR(ENOMEM);
}
-static void peak_write_frame(AVFormatContext *s)
+static int peak_write_frame(AVFormatContext *s)
{
WAVMuxContext *wav = s->priv_data;
AVCodecParameters *par = s->streams[0]->codecpar;
+ unsigned new_size = wav->peak_outbuf_bytes + wav->size_increment;
+ uint8_t *tmp;
int c;
- if (!wav->peak_output)
- return;
+ if (new_size > INT_MAX) {
+ wav->write_peak = PEAK_OFF;
+ return AVERROR(ERANGE);
+ }
+ tmp = av_fast_realloc(wav->peak_output, &wav->peak_outbuf_size, new_size);
+ if (!tmp) {
+ wav->write_peak = PEAK_OFF;
+ return AVERROR(ENOMEM);
+ }
+ wav->peak_output = tmp;
for (c = 0; c < par->channels; c++) {
wav->peak_maxneg[c] = -wav->peak_maxneg[c];
@@ -208,17 +217,6 @@ static void peak_write_frame(AVFormatContext *s)
wav->peak_maxpos[c] =
FFMAX(wav->peak_maxpos[c], wav->peak_maxneg[c]);
- if (wav->peak_outbuf_size - wav->peak_outbuf_bytes <
- wav->peak_format * wav->peak_ppv) {
- wav->peak_outbuf_size += PEAK_BUFFER_SIZE;
- wav->peak_output = av_realloc(wav->peak_output,
- wav->peak_outbuf_size);
- if (!wav->peak_output) {
- av_log(s, AV_LOG_ERROR, "No memory for peak data\n");
- return;
- }
- }
-
if (wav->peak_format == PEAK_FORMAT_UINT8) {
wav->peak_output[wav->peak_outbuf_bytes++] =
wav->peak_maxpos[c];
@@ -240,6 +238,8 @@ static void peak_write_frame(AVFormatContext *s)
wav->peak_maxneg[c] = 0;
}
wav->peak_num_frames++;
+
+ return 0;
}
static int peak_write_chunk(AVFormatContext *s)
@@ -253,8 +253,11 @@ static int peak_write_chunk(AVFormatContext *s)
char timestamp[28];
/* Peak frame of incomplete block at end */
- if (wav->peak_block_pos)
- peak_write_frame(s);
+ if (wav->peak_block_pos) {
+ int ret = peak_write_frame(s);
+ if (ret < 0)
+ return ret;
+ }
memset(timestamp, 0, sizeof(timestamp));
if (!(s->flags & AVFMT_FLAG_BITEXACT)) {
@@ -384,7 +387,9 @@ static int wav_write_packet(AVFormatContext *s, AVPacket *pkt)
if (++c == s->streams[0]->codecpar->channels) {
c = 0;
if (++wav->peak_block_pos == wav->peak_block_size) {
- peak_write_frame(s);
+ int ret = peak_write_frame(s);
+ if (ret < 0)
+ return ret;
wav->peak_block_pos = 0;
}
}