summaryrefslogtreecommitdiffstats
path: root/libmpcodecs
diff options
context:
space:
mode:
authorUoti Urpala <uau@mplayer2.org>2011-07-02 09:22:32 +0300
committerUoti Urpala <uau@mplayer2.org>2011-07-02 09:22:32 +0300
commitc8b3088c1831ab5f698924ce75127caa55b50dbb (patch)
tree12ca3b7d7b53ff9458b80f2c83de2cf29d522862 /libmpcodecs
parent746f9b004038e09392b69abb3ba26b1cc32a90d7 (diff)
downloadmpv-c8b3088c1831ab5f698924ce75127caa55b50dbb.tar.bz2
mpv-c8b3088c1831ab5f698924ce75127caa55b50dbb.tar.xz
audio: move ready-for-ao data buffer from decoder to AO
Move the buffer storing audio data ready to be fed to the audio output driver from the audio decoder object to the AO object. This will help encoding code deal with end of input, and may also be useful to improve other general gapless audio behavior (as AOs which do not accept chunks smaller than a certain size may keep them in the buffer while the decoder changes). Less data may be dropped now when changing audio filters or switching timeline parts.
Diffstat (limited to 'libmpcodecs')
-rw-r--r--libmpcodecs/dec_audio.c58
-rw-r--r--libmpcodecs/dec_audio.h6
2 files changed, 30 insertions, 34 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;
}
diff --git a/libmpcodecs/dec_audio.h b/libmpcodecs/dec_audio.h
index c2b92c9818..0d4baf0666 100644
--- a/libmpcodecs/dec_audio.h
+++ b/libmpcodecs/dec_audio.h
@@ -21,11 +21,13 @@
#include "libmpdemux/stheader.h"
+struct bstr;
+
// dec_audio.c:
void afm_help(void);
int init_best_audio_codec(sh_audio_t *sh_audio, char** audio_codec_list, char** audio_fm_list);
-int decode_audio(sh_audio_t *sh_audio, int minlen);
-void decode_audio_prepend_bytes(struct sh_audio *sh, int count, int byte);
+int decode_audio(sh_audio_t *sh_audio, struct bstr *outbuf, int minlen);
+void decode_audio_prepend_bytes(struct bstr *outbuf, int count, int byte);
void resync_audio_stream(sh_audio_t *sh_audio);
void skip_audio_frame(sh_audio_t *sh_audio);
void uninit_audio(sh_audio_t *sh_audio);