1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2024-12-23 12:43:46 +02:00

use consistant PTS handling - fixed MPEG2 Pack header generation (clock_ref value is still slightly inaccurate)

Originally committed as revision 1055 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
Fabrice Bellard 2002-10-21 15:57:21 +00:00
parent 916c80e94a
commit b2cac18443

View File

@ -17,7 +17,6 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
#include "avformat.h" #include "avformat.h"
#include "tick.h"
#define MAX_PAYLOAD_SIZE 4096 #define MAX_PAYLOAD_SIZE 4096
#define NB_STREAMS 2 #define NB_STREAMS 2
@ -28,8 +27,6 @@ typedef struct {
UINT8 id; UINT8 id;
int max_buffer_size; /* in bytes */ int max_buffer_size; /* in bytes */
int packet_number; int packet_number;
INT64 pts;
Ticker pts_ticker;
INT64 start_pts; INT64 start_pts;
} StreamInfo; } StreamInfo;
@ -77,17 +74,29 @@ static int put_pack_header(AVFormatContext *ctx,
init_put_bits(&pb, buf, 128, NULL, NULL); init_put_bits(&pb, buf, 128, NULL, NULL);
put_bits(&pb, 32, PACK_START_CODE); put_bits(&pb, 32, PACK_START_CODE);
if (s->is_mpeg2) {
put_bits(&pb, 2, 0x2);
} else {
put_bits(&pb, 4, 0x2); put_bits(&pb, 4, 0x2);
}
put_bits(&pb, 3, (UINT32)((timestamp >> 30) & 0x07)); put_bits(&pb, 3, (UINT32)((timestamp >> 30) & 0x07));
put_bits(&pb, 1, 1); put_bits(&pb, 1, 1);
put_bits(&pb, 15, (UINT32)((timestamp >> 15) & 0x7fff)); put_bits(&pb, 15, (UINT32)((timestamp >> 15) & 0x7fff));
put_bits(&pb, 1, 1); put_bits(&pb, 1, 1);
put_bits(&pb, 15, (UINT32)((timestamp) & 0x7fff)); put_bits(&pb, 15, (UINT32)((timestamp) & 0x7fff));
put_bits(&pb, 1, 1); put_bits(&pb, 1, 1);
if (s->is_mpeg2) {
/* clock extension */
put_bits(&pb, 9, 0);
put_bits(&pb, 1, 1);
}
put_bits(&pb, 1, 1); put_bits(&pb, 1, 1);
put_bits(&pb, 22, s->mux_rate); put_bits(&pb, 22, s->mux_rate);
put_bits(&pb, 1, 1); put_bits(&pb, 1, 1);
if (s->is_mpeg2) {
put_bits(&pb, 5, 0x1f); /* reserved */
put_bits(&pb, 3, 0); /* stuffing length */
}
flush_put_bits(&pb); flush_put_bits(&pb);
return pbBufPtr(&pb) - pb.buf; return pbBufPtr(&pb) - pb.buf;
} }
@ -217,36 +226,20 @@ static int mpeg_mux_init(AVFormatContext *ctx)
/* every 2 seconds */ /* every 2 seconds */
s->pack_header_freq = 2 * bitrate / s->packet_size / 8; s->pack_header_freq = 2 * bitrate / s->packet_size / 8;
if (s->is_vcd) if (s->is_mpeg2)
/* every 200 packets. Need to look at the spec. */
s->system_header_freq = s->pack_header_freq * 40;
else if (s->is_vcd)
/* every 40 packets, this is my invention */ /* every 40 packets, this is my invention */
s->system_header_freq = s->pack_header_freq * 40; s->system_header_freq = s->pack_header_freq * 40;
else else
/* every 10 seconds */
s->system_header_freq = s->pack_header_freq * 5; s->system_header_freq = s->pack_header_freq * 5;
for(i=0;i<ctx->nb_streams;i++) { for(i=0;i<ctx->nb_streams;i++) {
stream = ctx->streams[i]->priv_data; stream = ctx->streams[i]->priv_data;
stream->buffer_ptr = 0; stream->buffer_ptr = 0;
stream->packet_number = 0; stream->packet_number = 0;
stream->pts = 0;
stream->start_pts = -1; 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;
default:
av_abort();
}
} }
return 0; return 0;
fail: fail:
@ -354,7 +347,7 @@ static void flush_packet(AVFormatContext *ctx, int stream_index, int last_pkt)
} }
static int mpeg_mux_write_packet(AVFormatContext *ctx, int stream_index, static int mpeg_mux_write_packet(AVFormatContext *ctx, int stream_index,
UINT8 *buf, int size, int force_pts) UINT8 *buf, int size, int pts)
{ {
MpegMuxContext *s = ctx->priv_data; MpegMuxContext *s = ctx->priv_data;
AVStream *st = ctx->streams[stream_index]; AVStream *st = ctx->streams[stream_index];
@ -364,9 +357,7 @@ static int mpeg_mux_write_packet(AVFormatContext *ctx, int stream_index,
while (size > 0) { while (size > 0) {
/* set pts */ /* set pts */
if (stream->start_pts == -1) { if (stream->start_pts == -1) {
if (force_pts) stream->start_pts = pts;
stream->pts = force_pts;
stream->start_pts = stream->pts;
} }
len = s->packet_data_max_size - stream->buffer_ptr; len = s->packet_data_max_size - stream->buffer_ptr;
if (len > size) if (len > size)
@ -378,16 +369,10 @@ static int mpeg_mux_write_packet(AVFormatContext *ctx, int stream_index,
while (stream->buffer_ptr >= s->packet_data_max_size) { while (stream->buffer_ptr >= s->packet_data_max_size) {
/* output the packet */ /* output the packet */
if (stream->start_pts == -1) if (stream->start_pts == -1)
stream->start_pts = stream->pts; stream->start_pts = pts;
flush_packet(ctx, stream_index, 0); flush_packet(ctx, stream_index, 0);
} }
} }
stream->pts += ticker_tick(&stream->pts_ticker, 1);
//if (st->codec.codec_type == CODEC_TYPE_VIDEO)
// fprintf(stderr,"\nVideo PTS: %6lld", stream->pts);
//else
// fprintf(stderr,"\nAudio PTS: %6lld", stream->pts);
return 0; return 0;
} }
@ -510,7 +495,7 @@ static int mpegps_read_packet(AVFormatContext *s,
int len, size, startcode, i, c, flags, header_len, type, codec_id; int len, size, startcode, i, c, flags, header_len, type, codec_id;
INT64 pts, dts; INT64 pts, dts;
/* next start code (should be immediately after */ /* next start code (should be immediately after) */
redo: redo:
m->header_state = 0xff; m->header_state = 0xff;
size = MAX_SYNC_SIZE; size = MAX_SYNC_SIZE;
@ -536,8 +521,8 @@ static int mpegps_read_packet(AVFormatContext *s,
goto redo; goto redo;
len = get_be16(&s->pb); len = get_be16(&s->pb);
pts = 0; pts = AV_NOPTS_VALUE;
dts = 0; dts = AV_NOPTS_VALUE;
/* stuffing */ /* stuffing */
for(;;) { for(;;) {
c = get_byte(&s->pb); c = get_byte(&s->pb);
@ -555,7 +540,6 @@ static int mpegps_read_packet(AVFormatContext *s,
if ((c & 0xf0) == 0x20) { if ((c & 0xf0) == 0x20) {
pts = get_pts(&s->pb, c); pts = get_pts(&s->pb, c);
len -= 4; len -= 4;
dts = pts;
} else if ((c & 0xf0) == 0x30) { } else if ((c & 0xf0) == 0x30) {
pts = get_pts(&s->pb, c); pts = get_pts(&s->pb, c);
dts = get_pts(&s->pb, -1); dts = get_pts(&s->pb, -1);
@ -573,7 +557,6 @@ static int mpegps_read_packet(AVFormatContext *s,
goto redo; goto redo;
if ((flags & 0xc0) == 0x80) { if ((flags & 0xc0) == 0x80) {
pts = get_pts(&s->pb, -1); pts = get_pts(&s->pb, -1);
dts = pts;
header_len -= 5; header_len -= 5;
len -= 5; len -= 5;
} if ((flags & 0xc0) == 0xc0) { } if ((flags & 0xc0) == 0xc0) {