mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
- 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
This commit is contained in:
parent
ce7c56c250
commit
af469427b3
1
doc/TODO
1
doc/TODO
@ -14,7 +14,6 @@ Planned in next release:
|
||||
- find a solution to clear feed1.ffm if format change.
|
||||
- new grab architecture : use avformat instead of audio: and video:
|
||||
protocol.
|
||||
- correct PTS handling to sync audio and video.
|
||||
- fix 0 size picture in AVIs = skip picture
|
||||
|
||||
BUGS:
|
||||
|
28
libav/mpeg.c
28
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;
|
||||
}
|
||||
|
||||
|
31
libav/tick.h
Normal file
31
libav/tick.h
Normal file
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
@ -129,7 +129,6 @@ static void mpeg1_encode_sequence_header(MpegEncContext *s)
|
||||
}
|
||||
|
||||
}
|
||||
s->fake_picture_number++;
|
||||
}
|
||||
|
||||
|
||||
@ -226,6 +225,7 @@ void mpeg1_encode_picture_header(MpegEncContext *s, int picture_number)
|
||||
/* temporal reference */
|
||||
put_bits(&s->pb, 10, (s->fake_picture_number -
|
||||
s->gop_picture_number) & 0x3ff);
|
||||
s->fake_picture_number++;
|
||||
|
||||
put_bits(&s->pb, 3, s->pict_type);
|
||||
put_bits(&s->pb, 16, 0xffff); /* non constant bit rate */
|
||||
|
Loading…
Reference in New Issue
Block a user