]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/utils.c
Add and use av_fast_padded_malloc.
[ffmpeg] / libavcodec / utils.c
index 7ea9c54f31a2b5cee866fd726aa3700716af944e..ccccd54accb4da3f40ef57a9e4d5e61f9f6fd390 100644 (file)
@@ -69,16 +69,34 @@ void *av_fast_realloc(void *ptr, unsigned int *size, size_t min_size)
     return ptr;
 }
 
-void av_fast_malloc(void *ptr, unsigned int *size, size_t min_size)
+static inline int ff_fast_malloc(void *ptr, unsigned int *size, size_t min_size, int zero_realloc)
 {
     void **p = ptr;
     if (min_size < *size)
-        return;
+        return 0;
     min_size= FFMAX(17*min_size/16 + 32, min_size);
     av_free(*p);
-    *p = av_malloc(min_size);
+    *p = zero_realloc ? av_mallocz(min_size) : av_malloc(min_size);
     if (!*p) min_size = 0;
     *size= min_size;
+    return 1;
+}
+
+void av_fast_malloc(void *ptr, unsigned int *size, size_t min_size)
+{
+    ff_fast_malloc(ptr, size, min_size, 0);
+}
+
+void av_fast_padded_malloc(void *ptr, unsigned int *size, size_t min_size)
+{
+    uint8_t **p = ptr;
+    if (min_size > SIZE_MAX - FF_INPUT_BUFFER_PADDING_SIZE) {
+        *p = NULL;
+        *size = 0;
+        return;
+    }
+    if (!ff_fast_malloc(p, size, min_size + FF_INPUT_BUFFER_PADDING_SIZE, 1))
+        memset(*p + min_size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
 }
 
 /* encoder management */
@@ -296,7 +314,7 @@ int avcodec_fill_audio_frame(AVFrame *frame, int nb_channels,
                                       buf, nb_channels, frame->nb_samples,
                                       sample_fmt, align)) < 0) {
         if (frame->extended_data != frame->data)
-            av_free(frame->extended_data);
+            av_freep(&frame->extended_data);
         return ret;
     }
     if (frame->extended_data != frame->data) {
@@ -334,7 +352,7 @@ static int audio_get_buffer(AVCodecContext *avctx, AVFrame *frame)
         if (buf->extended_data[0] && buf_size > buf->audio_data_size) {
             av_free(buf->extended_data[0]);
             if (buf->extended_data != buf->data)
-                av_free(&buf->extended_data);
+                av_freep(&buf->extended_data);
             buf->extended_data = NULL;
             buf->data[0] = NULL;
         }
@@ -968,6 +986,8 @@ int attribute_align_arg avcodec_encode_audio2(AVCodecContext *avctx,
         if (!user_packet) {
             if (avctx->codec->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE) {
                 av_assert0(av_get_bits_per_sample(avctx->codec_id) != 0);
+                if (!frame)
+                    return AVERROR(EINVAL);
                 buf_size = nb_samples * avctx->channels *
                            av_get_bits_per_sample(avctx->codec_id) / 8;
             } else {
@@ -1110,7 +1130,7 @@ int attribute_align_arg avcodec_encode_audio(AVCodecContext *avctx,
     }
 
     if (frame && frame->extended_data != frame->data)
-        av_free(frame->extended_data);
+        av_freep(&frame->extended_data);
 
     return ret ? ret : pkt.size;
 }
@@ -1733,7 +1753,7 @@ static void audio_free_buffers(AVCodecContext *avctx)
     if (buf->extended_data) {
         av_free(buf->extended_data[0]);
         if (buf->extended_data != buf->data)
-            av_free(buf->extended_data);
+            av_freep(&buf->extended_data);
     }
     av_freep(&avci->buffer);
 }