aboutsummaryrefslogtreecommitdiffstats
path: root/libav
diff options
context:
space:
mode:
authorJuanjo <pulento@users.sourceforge.net>2002-03-20 11:16:07 +0000
committerJuanjo <pulento@users.sourceforge.net>2002-03-20 11:16:07 +0000
commitaf469427b345528797a6f0f33e8e6e5df623593d (patch)
tree531b234412600c2f8c22f001639895765ae31691 /libav
parentce7c56c2504693d23949cca5b7cadddd673348ab (diff)
downloadffmpeg-af469427b345528797a6f0f33e8e6e5df623593d.tar.gz
- Fix pts calculation on mpeg mux (A/V sync) - Thanks to Lennert Buytenhek
- Fix temporal-reference-glitches for MPEG1 - Thanks to Lennert Buytenhek Originally committed as revision 343 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libav')
-rw-r--r--libav/mpeg.c28
-rw-r--r--libav/tick.h31
-rw-r--r--libav/utils.c28
3 files changed, 79 insertions, 8 deletions
diff --git a/libav/mpeg.c b/libav/mpeg.c
index 5ac9c62b18..2871278778 100644
--- a/libav/mpeg.c
+++ b/libav/mpeg.c
@@ -17,6 +17,7 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "avformat.h"
+#include "tick.h"
#define MAX_PAYLOAD_SIZE 4096
#define NB_STREAMS 2
@@ -27,7 +28,8 @@ typedef struct {
UINT8 id;
int max_buffer_size; /* in bytes */
int packet_number;
- float pts;
+ INT64 pts;
+ Ticker pts_ticker;
INT64 start_pts;
} StreamInfo;
@@ -211,6 +213,20 @@ static int mpeg_mux_init(AVFormatContext *ctx)
stream->packet_number = 0;
stream->pts = 0;
stream->start_pts = -1;
+
+ st = ctx->streams[i];
+ switch (st->codec.codec_type) {
+ case CODEC_TYPE_AUDIO:
+ ticker_init(&stream->pts_ticker,
+ st->codec.sample_rate,
+ 90000 * st->codec.frame_size);
+ break;
+ case CODEC_TYPE_VIDEO:
+ ticker_init(&stream->pts_ticker,
+ st->codec.frame_rate,
+ 90000 * FRAME_RATE_BASE);
+ break;
+ }
}
return 0;
fail:
@@ -316,7 +332,7 @@ static int mpeg_mux_write_packet(AVFormatContext *ctx,
while (size > 0) {
/* set pts */
if (stream->start_pts == -1)
- stream->start_pts = stream->pts * 90000.0;
+ stream->start_pts = stream->pts;
len = s->packet_data_max_size - stream->buffer_ptr;
if (len > size)
len = size;
@@ -327,16 +343,12 @@ static int mpeg_mux_write_packet(AVFormatContext *ctx,
while (stream->buffer_ptr >= s->packet_data_max_size) {
/* output the packet */
if (stream->start_pts == -1)
- stream->start_pts = stream->pts * 90000.0;
+ stream->start_pts = stream->pts;
flush_packet(ctx, stream_index);
}
}
- if (st->codec.codec_type == CODEC_TYPE_AUDIO) {
- stream->pts += (float)st->codec.frame_size / st->codec.sample_rate;
- } else {
- stream->pts += FRAME_RATE_BASE / (float)st->codec.frame_rate;
- }
+ stream->pts += ticker_tick(&stream->pts_ticker, 1);
return 0;
}
diff --git a/libav/tick.h b/libav/tick.h
new file mode 100644
index 0000000000..8b6d6b4421
--- /dev/null
+++ b/libav/tick.h
@@ -0,0 +1,31 @@
+/* tick.h - Compute successive integer multiples of a rational
+ * number without long-term rounding error.
+ * (c)2002 by Lennert Buytenhek <buytenh@gnu.org>
+ * File licensed under the GPL, see http://www.fsf.org/ for more info.
+ * Dedicated to Marija Kulikova.
+ */
+
+#include "avcodec.h"
+
+typedef struct Ticker {
+ int value;
+ int inrate;
+ int outrate;
+ int div;
+ int mod;
+} Ticker;
+
+extern void ticker_init(Ticker *tick, INT64 inrate, INT64 outrate);
+
+extern inline int ticker_tick(Ticker *tick, int num)
+{
+ int n = num * tick->div;
+
+ tick->value += num * tick->mod;
+ while (tick->value > 0) {
+ tick->value -= tick->inrate;
+ n++;
+ }
+
+ return n;
+}
diff --git a/libav/utils.c b/libav/utils.c
index aafc4e7863..7315ebdc92 100644
--- a/libav/utils.c
+++ b/libav/utils.c
@@ -17,6 +17,7 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "avformat.h"
+#include "tick.h"
#ifndef CONFIG_WIN32
#include <unistd.h>
#include <fcntl.h>
@@ -615,4 +616,31 @@ int get_frame_filename(char *buf, int buf_size,
return -1;
}
+static int gcd(INT64 a, INT64 b)
+{
+ INT64 c;
+
+ while (1) {
+ c = a % b;
+ if (c == 0)
+ return b;
+ a = b;
+ b = c;
+ }
+}
+
+void ticker_init(Ticker *tick, INT64 inrate, INT64 outrate)
+{
+ int g;
+
+ g = gcd(inrate, outrate);
+ inrate /= g;
+ outrate /= g;
+ tick->value = -outrate/2;
+
+ tick->inrate = inrate;
+ tick->outrate = outrate;
+ tick->div = tick->outrate / tick->inrate;
+ tick->mod = tick->outrate % tick->inrate;
+}