summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUoti Urpala <uau@symbol.nonexistent.invalid>2008-08-03 21:14:11 +0300
committerUoti Urpala <uau@symbol.nonexistent.invalid>2008-08-03 21:25:48 +0300
commit2ba9df3df3d61a7cc1bde9f897bc77eaaf14b383 (patch)
treeba2664cf554237fde25eac4718fb17ed63c37b08
parent6cce822505c0a76ac520909a895021b8f5b7e5ab (diff)
downloadmpv-2ba9df3df3d61a7cc1bde9f897bc77eaaf14b383.tar.bz2
mpv-2ba9df3df3d61a7cc1bde9f897bc77eaaf14b383.tar.xz
ad_pcm: Track pts explicitly
ad_pcm used the old audio timestamp tracking system that calculated timestamp at end of decoder output as last_timestamp_in_input_decoder_has_read + bytes_read_after_that_timestamp / input_bitrate. For PCM this can be accurate as input bitrate is constant. However it relies on input bitrate being known and actually set. At least in some case with .mov input and libavformat demuxer it wasn't set. Instead of special-casing PCM to make sure input bitrate is set (in general it may not be known or constant at all) change ad_pcm to explicitly set the pts information on the decoder output side.
-rw-r--r--libmpcodecs/ad_pcm.c39
1 files changed, 36 insertions, 3 deletions
diff --git a/libmpcodecs/ad_pcm.c b/libmpcodecs/ad_pcm.c
index 1c2ef53813..058f6c25cb 100644
--- a/libmpcodecs/ad_pcm.c
+++ b/libmpcodecs/ad_pcm.c
@@ -2,6 +2,7 @@
#include <stdlib.h>
#include <unistd.h>
+#include "talloc.h"
#include "config.h"
#include "ad_internal.h"
#include "libaf/af_format.h"
@@ -16,6 +17,11 @@ static const ad_info_t info =
""
};
+struct ad_pcm_context {
+ unsigned char *packet_ptr;
+ int packet_len;
+};
+
LIBAD_EXTERN(pcm)
static int init(sh_audio_t *sh_audio)
@@ -91,6 +97,7 @@ static int init(sh_audio_t *sh_audio)
}
if (!sh_audio->samplesize) // this would cause MPlayer to hang later
sh_audio->samplesize = 2;
+ sh_audio->context = talloc_zero(NULL, struct ad_pcm_context);
return 1;
}
@@ -102,6 +109,7 @@ static int preinit(sh_audio_t *sh)
static void uninit(sh_audio_t *sh)
{
+ talloc_free(sh->context);
}
static int control(sh_audio_t *sh,int cmd,void* arg, ...)
@@ -121,12 +129,37 @@ static int control(sh_audio_t *sh,int cmd,void* arg, ...)
static int decode_audio(sh_audio_t *sh_audio,unsigned char *buf,int minlen,int maxlen)
{
unsigned len = sh_audio->channels*sh_audio->samplesize;
- len = (minlen + len - 1) / len * len;
- if (len > maxlen)
+ minlen = (minlen + len - 1) / len * len;
+ if (minlen > maxlen)
// if someone needs hundreds of channels adjust audio_out_minsize
// based on channels in preinit()
return -1;
- len=demux_read_data(sh_audio->ds,buf,len);
+
+ len = 0;
+ struct ad_pcm_context *ctx = sh_audio->context;
+ while (len < minlen) {
+ if (ctx->packet_len == 0) {
+ double pts;
+ int plen = ds_get_packet_pts(sh_audio->ds, &ctx->packet_ptr, &pts);
+ if (plen < 0)
+ break;
+ ctx->packet_len = plen;
+ if (pts != MP_NOPTS_VALUE) {
+ sh_audio->pts = pts;
+ sh_audio->pts_bytes = 0;
+ }
+ }
+ int from_stored = ctx->packet_len;
+ if (from_stored > minlen - len)
+ from_stored = minlen - len;
+ memcpy(buf + len, ctx->packet_ptr, from_stored);
+ ctx->packet_len -= from_stored;
+ ctx->packet_ptr += from_stored;
+ sh_audio->pts_bytes += from_stored;
+ len += from_stored;
+ }
+ if (len == 0)
+ len = -1; // The loop above only exits at error/EOF
if (len > 0 && sh_audio->channels >= 5) {
reorder_channel_nch(buf, AF_CHANNEL_LAYOUT_WAVEEX_DEFAULT,
AF_CHANNEL_LAYOUT_MPLAYER_DEFAULT,