From d683b008973e88b80ce743ec5f3a592a6a16fd43 Mon Sep 17 00:00:00 2001 From: Alexander Kojevnikov Date: Sat, 10 Jul 2010 12:10:15 +1000 Subject: [PATCH] Use av_malloc to allocate audio buffers libavcodec crashes on Windows when using the usual malloc, av_malloc makes sure the allocated buffer is properly aligned. --- src/spek-audio.c | 10 +++++++--- src/spek-audio.h | 7 +++---- src/spek-pipeline.vala | 6 ++---- vapi/spek-audio.vapi | 4 ++-- 4 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/spek-audio.c b/src/spek-audio.c index 9bf4c65..c3ba688 100644 --- a/src/spek-audio.c +++ b/src/spek-audio.c @@ -77,7 +77,6 @@ SpekAudioContext * spek_audio_open (const char *file_name) { cx->error = _("No audio channels"); return cx; } - cx->buffer_size = (AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2; if (avcodec_open (cx->codec_context, cx->codec) < 0) { cx->error = _("Cannot open decoder"); return cx; @@ -103,6 +102,8 @@ SpekAudioContext * spek_audio_open (const char *file_name) { cx->error = _("Unsupported sample format"); return cx; } + cx->buffer_size = (AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2; + cx->buffer = av_malloc (cx->buffer_size); av_init_packet (&cx->packet); cx->offset = 0; return cx; @@ -116,7 +117,7 @@ void spek_audio_start (SpekAudioContext *cx, gint samples) { cx->error_per_interval = (cx->stream->duration * rate) % cx->error_base; } -gint spek_audio_read (SpekAudioContext *cx, guint8 *buffer) { +gint spek_audio_read (SpekAudioContext *cx) { gint buffer_size; gint len; gint res; @@ -129,7 +130,7 @@ gint spek_audio_read (SpekAudioContext *cx, guint8 *buffer) { while (cx->packet.size > 0) { buffer_size = cx->buffer_size; len = avcodec_decode_audio3 ( - cx->codec_context, (int16_t *) buffer, &buffer_size, &cx->packet); + cx->codec_context, (int16_t *) cx->buffer, &buffer_size, &cx->packet); if (len < 0) { /* Error, skip the frame. */ cx->packet.size = 0; @@ -171,6 +172,9 @@ void spek_audio_close (SpekAudioContext *cx) { if (cx->codec_name != NULL) { g_free (cx->codec_name); } + if (cx->buffer) { + av_free (cx->buffer); + } if (cx->packet.data) { cx->packet.data -= cx->offset; cx->packet.size += cx->offset; diff --git a/src/spek-audio.h b/src/spek-audio.h index 43cd28a..6899a4d 100644 --- a/src/spek-audio.h +++ b/src/spek-audio.h @@ -30,6 +30,7 @@ typedef struct { AVCodecContext *codec_context; AVStream *stream; AVCodec *codec; + gint buffer_size; AVPacket packet; gint offset; @@ -44,7 +45,7 @@ typedef struct { gboolean fp; /* floating-point sample representation */ gint channels; gdouble duration; - gint buffer_size; /* minimum buffer size for spek_audio_read() */ + guint8 *buffer; gint64 frames_per_interval; gint64 error_per_interval; gint64 error_base; @@ -64,10 +65,8 @@ void spek_audio_start (SpekAudioContext *cx, gint samples); /* Read and decode the opened audio stream. * Returns -1 on error, 0 if there's nothing left to read * or the number of bytes decoded into the buffer. - * The buffer must be allocated (and later freed) by the caller, - * minimum size is `buffer_size`. */ -gint spek_audio_read (SpekAudioContext *cx, guint8 *buffer); +gint spek_audio_read (SpekAudioContext *cx); /* Closes the file opened with spek_audio_open, * frees all allocated buffers and the context diff --git a/src/spek-pipeline.vala b/src/spek-pipeline.vala index 3f6f92a..a7995ce 100644 --- a/src/spek-pipeline.vala +++ b/src/spek-pipeline.vala @@ -36,7 +36,6 @@ namespace Spek { private int threshold; private Callback cb; - private uint8[] buffer; private Fft.Plan fft; private int nfft; // Size of the FFT transform. private const int NFFT = 64; // Number of FFTs to pre-fetch. @@ -89,7 +88,6 @@ namespace Spek { } this.sample_rate = cx.sample_rate; - this.buffer = new uint8[cx.buffer_size]; this.nfft = 2 * bands - 2; this.fft = new Fft.Plan (nfft, threshold); this.input_size = nfft * (NFFT * 2 + 1); @@ -140,10 +138,10 @@ namespace Spek { return null; } - while ((size = cx.read (this.buffer)) > 0) { + while ((size = cx.read ()) > 0) { lock (quit) if (quit) break; - uint8 *buffer = (uint8 *) this.buffer; + uint8 *buffer = (uint8 *) cx.buffer; while (size >= block_size) { input[pos] = average_input (buffer); buffer += block_size; diff --git a/vapi/spek-audio.vapi b/vapi/spek-audio.vapi index eec0984..1ec06df 100644 --- a/vapi/spek-audio.vapi +++ b/vapi/spek-audio.vapi @@ -13,7 +13,7 @@ namespace Spek.Audio { public bool fp; public int channels; public double duration; - public int buffer_size; + public uint8 *buffer; public int64 frames_per_interval; public int64 error_per_interval; public int64 error_base; @@ -23,7 +23,7 @@ namespace Spek.Audio { [CCode (cname = "spek_audio_start")] public int start (int samples); [CCode (cname = "spek_audio_read")] - public int read ([CCode (array_length = false)] uint8[] buffer); + public int read (); } public static void init (); }