diff mpcommon.c @ 32863:674117ab7ce7

Move MPlayer's audio pts calculation code into mp_common.c and reuse it in mencoder. This should improve A-V sync behaviour a lot when re-encoding audio. Patch by Rudolf Polzer [divVerent alientrap org]
author reimar
date Tue, 22 Feb 2011 18:22:16 +0000
parents 702867779920
children 25d2ef30d784
line wrap: on
line diff
--- a/mpcommon.c	Tue Feb 22 18:18:15 2011 +0000
+++ b/mpcommon.c	Tue Feb 22 18:22:16 2011 +0000
@@ -462,3 +462,37 @@
 #endif
     return 1;
 }
+
+/// Returns a_pts
+double calc_a_pts(sh_audio_t *sh_audio, demux_stream_t *d_audio)
+{
+    if(!sh_audio || !d_audio)
+        return MP_NOPTS_VALUE;
+    // first calculate the end pts of audio that has been output by decoder
+    double a_pts = sh_audio->pts;
+    if (a_pts != MP_NOPTS_VALUE)
+        // Good, decoder supports new way of calculating audio pts.
+        // sh_audio->pts is the timestamp of the latest input packet with
+        // known pts that the decoder has decoded. sh_audio->pts_bytes is
+        // the amount of bytes the decoder has written after that timestamp.
+        a_pts += sh_audio->pts_bytes / (double) sh_audio->o_bps;
+    else {
+        // Decoder doesn't support new way of calculating pts (or we're
+        // being called before it has decoded anything with known timestamp).
+        // Use the old method of audio pts calculation: take the timestamp
+        // of last packet with known pts the decoder has read data from,
+        // and add amount of bytes read after the beginning of that packet
+        // divided by input bps. This will be inaccurate if the input/output
+        // ratio is not constant for every audio packet or if it is constant
+        // but not accurately known in sh_audio->i_bps.
+
+        a_pts = d_audio->pts;
+        // ds_tell_pts returns bytes read after last timestamp from
+        // demuxing layer, decoder might use sh_audio->a_in_buffer for bytes
+        // it has read but not decoded
+        if (sh_audio->i_bps)
+            a_pts += (ds_tell_pts(d_audio) - sh_audio->a_in_buffer_len) /
+                     (double)sh_audio->i_bps;
+    }
+    return a_pts;
+}