summaryrefslogtreecommitdiffstats
path: root/audio
diff options
context:
space:
mode:
authorRudolf Polzer <divverent@xonotic.org>2013-04-28 11:39:30 +0200
committerRudolf Polzer <divverent@xonotic.org>2013-04-28 11:39:38 +0200
commit2d8783075f788b9486a13e929871077850faa230 (patch)
treea59370baa7c15b1e70ea48df819a047703faa4e1 /audio
parent7a42df871255ae8f3c1bab13dc3e87e642d262ac (diff)
downloadmpv-2d8783075f788b9486a13e929871077850faa230.tar.bz2
mpv-2d8783075f788b9486a13e929871077850faa230.tar.xz
encoding: fix final audio frame sync
When --ocopyts was used, the final audio frame got improper pts. Fixed by now using the play() logic to play the final frame too.
Diffstat (limited to 'audio')
-rw-r--r--audio/out/ao_lavc.c32
1 files changed, 22 insertions, 10 deletions
diff --git a/audio/out/ao_lavc.c b/audio/out/ao_lavc.c
index 062d1b928b..33139ce866 100644
--- a/audio/out/ao_lavc.c
+++ b/audio/out/ao_lavc.c
@@ -331,6 +331,7 @@ static void fill_with_padding(void *buf, int cnt, int sz, const void *padding)
// close audio device
static int encode(struct ao *ao, double apts, void *data);
+static int play(struct ao *ao, void *data, int len, int flags);
static void uninit(struct ao *ao, bool cut_audio)
{
struct priv *ac = ao->priv;
@@ -343,21 +344,31 @@ static void uninit(struct ao *ao, bool cut_audio)
}
if (ac->buffer) {
- double pts = ao->pts + ac->offset / (double) ao->samplerate;
if (ao->buffer.len > 0) {
- void *paddingbuf = talloc_size(ao,
- ac->aframesize * ao->channels * ac->sample_size);
+ // TRICK: append aframesize-1 samples to the end, then play() will
+ // encode all it can
+ size_t extralen =
+ (ac->aframesize - 1) * ao->channels * ac->sample_size;
+ void *paddingbuf = talloc_size(ao, ao->buffer.len + extralen);
memcpy(paddingbuf, ao->buffer.start, ao->buffer.len);
fill_with_padding((char *) paddingbuf + ao->buffer.len,
- (ac->aframesize * ao->channels * ac->sample_size
- - ao->buffer.len) / ac->sample_size,
+ extralen / ac->sample_size,
ac->sample_size, ac->sample_padding);
- encode(ao, pts, paddingbuf);
- pts += ac->aframesize / (double) ao->samplerate;
+ int written = play(ao, paddingbuf, ao->buffer.len + extralen, 0);
+ if (written < ao->buffer.len) {
+ mp_msg(MSGT_ENCODE, MSGL_ERR,
+ "ao-lavc: did not write enough data at the end\n");
+ }
talloc_free(paddingbuf);
ao->buffer.len = 0;
}
- while (encode(ao, pts, NULL) > 0) ;
+
+ double outpts = ac->expected_next_pts;
+ if (!ectx->options->rawts && ectx->options->copyts)
+ outpts += ectx->discontinuity_pts_offset;
+ outpts += encode_lavc_getoffset(ectx, ac->stream);
+
+ while (encode(ao, outpts, NULL) > 0) ;
}
ao->priv = NULL;
@@ -516,11 +527,12 @@ static int play(struct ao *ao, void *data, int len, int flags)
if (!encode_lavc_start(ectx)) {
mp_msg(MSGT_ENCODE, MSGL_WARN,
- "ao-lavc: not ready yet for encoding audio\n");
+ "ao-lavc: not ready yet for encoding audio\n");
return 0;
}
if (pts == MP_NOPTS_VALUE) {
- mp_msg(MSGT_ENCODE, MSGL_WARN, "ao-lavc: frame without pts, please report; synthesizing pts instead\n");
+ mp_msg(MSGT_ENCODE, MSGL_WARN,
+ "ao-lavc: frame without pts, please report; synthesizing pts instead\n");
// synthesize pts from previous expected next pts
pts = ac->expected_next_pts;
}