summaryrefslogtreecommitdiffstats
path: root/libmpcodecs/dec_audio.c
diff options
context:
space:
mode:
Diffstat (limited to 'libmpcodecs/dec_audio.c')
-rw-r--r--libmpcodecs/dec_audio.c58
1 files changed, 26 insertions, 32 deletions
diff --git a/libmpcodecs/dec_audio.c b/libmpcodecs/dec_audio.c
index 00c66287ed..0541947f60 100644
--- a/libmpcodecs/dec_audio.c
+++ b/libmpcodecs/dec_audio.c
@@ -23,6 +23,7 @@
#include "config.h"
#include "mp_msg.h"
+#include "bstr.h"
#include "stream/stream.h"
#include "libmpdemux/demuxer.h"
@@ -134,10 +135,6 @@ static int init_audio_codec(sh_audio_t *sh_audio)
"ID_AUDIO_BITRATE=%d\nID_AUDIO_RATE=%d\n" "ID_AUDIO_NCH=%d\n",
sh_audio->i_bps * 8, sh_audio->samplerate, sh_audio->channels);
- sh_audio->a_out_buffer_size = 0;
- sh_audio->a_out_buffer = NULL;
- sh_audio->a_out_buffer_len = 0;
-
return 1;
}
@@ -317,9 +314,6 @@ void uninit_audio(sh_audio_t *sh_audio)
#endif
sh_audio->initialized = 0;
}
- free(sh_audio->a_out_buffer);
- sh_audio->a_out_buffer = NULL;
- sh_audio->a_out_buffer_size = 0;
av_freep(&sh_audio->a_buffer);
av_freep(&sh_audio->a_in_buffer);
}
@@ -364,24 +358,23 @@ int init_audio_filters(sh_audio_t *sh_audio, int in_samplerate,
*out_channels = afs->output.nch;
*out_format = afs->output.format;
- sh_audio->a_out_buffer_len = 0;
-
// ok!
sh_audio->afilter = (void *) afs;
return 1;
}
-static void set_min_out_buffer_size(struct sh_audio *sh, int len)
+static void set_min_out_buffer_size(struct bstr *outbuf, int len)
{
- if (sh->a_out_buffer_size < len) {
+ size_t oldlen = talloc_get_size(outbuf->start);
+ if (oldlen < len) {
+ assert(outbuf->start); // talloc context should be already set
mp_msg(MSGT_DECAUDIO, MSGL_V, "Increasing filtered audio buffer size "
- "from %d to %d\n", sh->a_out_buffer_size, len);
- sh->a_out_buffer = realloc(sh->a_out_buffer, len);
- sh->a_out_buffer_size = len;
+ "from %zd to %d\n", oldlen, len);
+ outbuf->start = talloc_realloc_size(NULL, outbuf->start, len);
}
}
-static int filter_n_bytes(sh_audio_t *sh, int len)
+static int filter_n_bytes(sh_audio_t *sh, struct bstr *outbuf, int len)
{
assert(len-1 + sh->audio_out_minsize <= sh->a_buffer_size);
@@ -420,10 +413,10 @@ static int filter_n_bytes(sh_audio_t *sh, int len)
af_data_t *filter_output = af_play(sh->afilter, &filter_input);
if (!filter_output)
return -1;
- set_min_out_buffer_size(sh, sh->a_out_buffer_len + filter_output->len);
- memcpy(sh->a_out_buffer + sh->a_out_buffer_len, filter_output->audio,
- filter_output->len);
- sh->a_out_buffer_len += filter_output->len;
+ set_min_out_buffer_size(outbuf, outbuf->len + filter_output->len);
+ memcpy(outbuf->start + outbuf->len, filter_output->audio,
+ filter_output->len);
+ outbuf->len += filter_output->len;
// remove processed data from decoder buffer:
sh->a_buffer_len -= len;
@@ -432,13 +425,14 @@ static int filter_n_bytes(sh_audio_t *sh, int len)
return error;
}
-/* Try to get at least minlen decoded+filtered bytes in sh_audio->a_out_buffer
+/* Try to get at least minlen decoded+filtered bytes in outbuf
* (total length including possible existing data).
* Return 0 on success, -1 on error/EOF (not distinguished).
- * In the former case sh_audio->a_out_buffer_len is always >= minlen
- * on return. In case of EOF/error it might or might not be.
- * Can reallocate sh_audio->a_out_buffer if needed to fit all filter output. */
-int decode_audio(sh_audio_t *sh_audio, int minlen)
+ * In the former case outbuf->len is always >= minlen on return.
+ * In case of EOF/error it might or might not be.
+ * Outbuf.start must be talloc-allocated, and will be reallocated
+ * if needed to fit all filter output. */
+int decode_audio(sh_audio_t *sh_audio, struct bstr *outbuf, int minlen)
{
// Indicates that a filter seems to be buffering large amounts of data
int huge_filter_buffer = 0;
@@ -458,8 +452,8 @@ int decode_audio(sh_audio_t *sh_audio, int minlen)
int max_decode_len = sh_audio->a_buffer_size - sh_audio->audio_out_minsize;
max_decode_len -= max_decode_len % unitsize;
- while (sh_audio->a_out_buffer_len < minlen) {
- int declen = (minlen - sh_audio->a_out_buffer_len) / filter_multiplier
+ while (outbuf->len < minlen) {
+ int declen = (minlen - outbuf->len) / filter_multiplier
+ (unitsize << 5); // some extra for possible filter buffering
if (huge_filter_buffer)
/* Some filter must be doing significant buffering if the estimated
@@ -478,19 +472,19 @@ int decode_audio(sh_audio_t *sh_audio, int minlen)
/* if this iteration does not fill buffer, we must have lots
* of buffering in filters */
huge_filter_buffer = 1;
- int res = filter_n_bytes(sh_audio, declen);
+ int res = filter_n_bytes(sh_audio, outbuf, declen);
if (res < 0)
return res;
}
return 0;
}
-void decode_audio_prepend_bytes(struct sh_audio *sh, int count, int byte)
+void decode_audio_prepend_bytes(struct bstr *outbuf, int count, int byte)
{
- set_min_out_buffer_size(sh, sh->a_out_buffer_len + count);
- memmove(sh->a_out_buffer + count, sh->a_out_buffer, sh->a_out_buffer_len);
- memset(sh->a_out_buffer, byte, count);
- sh->a_out_buffer_len += count;
+ set_min_out_buffer_size(outbuf, outbuf->len + count);
+ memmove(outbuf->start + count, outbuf->start, outbuf->len);
+ memset(outbuf->start, byte, count);
+ outbuf->len += count;
}