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.
This commit is contained in:
Alexander Kojevnikov 2010-07-10 12:10:15 +10:00
parent 166d31e693
commit d683b00897
4 changed files with 14 additions and 13 deletions

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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 ();
}