commit d683b008973e88b80ce743ec5f3a592a6a16fd43
parent 166d31e69398dcfb423980aa408b8f2f6cb53832
Author: Alexander Kojevnikov <alexander@kojevnikov.com>
Date: Sat, 10 Jul 2010 12:10:15 +1000
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.
Diffstat:
4 files changed, 14 insertions(+), 13 deletions(-)
diff --git 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
@@ -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
@@ -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
@@ -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 ();
}