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:
parent
916c80e94a
commit
b2cac18443
65
libav/mpeg.c
65
libav/mpeg.c
@ -17,7 +17,6 @@
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "avformat.h"
|
||||
#include "tick.h"
|
||||
|
||||
#define MAX_PAYLOAD_SIZE 4096
|
||||
#define NB_STREAMS 2
|
||||
@ -28,8 +27,6 @@ typedef struct {
|
||||
UINT8 id;
|
||||
int max_buffer_size; /* in bytes */
|
||||
int packet_number;
|
||||
INT64 pts;
|
||||
Ticker pts_ticker;
|
||||
INT64 start_pts;
|
||||
} StreamInfo;
|
||||
|
||||
@ -77,17 +74,29 @@ static int put_pack_header(AVFormatContext *ctx,
|
||||
init_put_bits(&pb, buf, 128, NULL, NULL);
|
||||
|
||||
put_bits(&pb, 32, PACK_START_CODE);
|
||||
put_bits(&pb, 4, 0x2);
|
||||
if (s->is_mpeg2) {
|
||||
put_bits(&pb, 2, 0x2);
|
||||
} else {
|
||||
put_bits(&pb, 4, 0x2);
|
||||
}
|
||||
put_bits(&pb, 3, (UINT32)((timestamp >> 30) & 0x07));
|
||||
put_bits(&pb, 1, 1);
|
||||
put_bits(&pb, 15, (UINT32)((timestamp >> 15) & 0x7fff));
|
||||
put_bits(&pb, 1, 1);
|
||||
put_bits(&pb, 15, (UINT32)((timestamp) & 0x7fff));
|
||||
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, 22, s->mux_rate);
|
||||
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);
|
||||
return pbBufPtr(&pb) - pb.buf;
|
||||
}
|
||||
@ -217,36 +226,20 @@ static int mpeg_mux_init(AVFormatContext *ctx)
|
||||
/* every 2 seconds */
|
||||
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 */
|
||||
s->system_header_freq = s->pack_header_freq * 40;
|
||||
else
|
||||
/* every 10 seconds */
|
||||
s->system_header_freq = s->pack_header_freq * 5;
|
||||
|
||||
|
||||
for(i=0;i<ctx->nb_streams;i++) {
|
||||
stream = ctx->streams[i]->priv_data;
|
||||
stream->buffer_ptr = 0;
|
||||
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;
|
||||
default:
|
||||
av_abort();
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
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,
|
||||
UINT8 *buf, int size, int force_pts)
|
||||
UINT8 *buf, int size, int pts)
|
||||
{
|
||||
MpegMuxContext *s = ctx->priv_data;
|
||||
AVStream *st = ctx->streams[stream_index];
|
||||
@ -364,9 +357,7 @@ static int mpeg_mux_write_packet(AVFormatContext *ctx, int stream_index,
|
||||
while (size > 0) {
|
||||
/* set pts */
|
||||
if (stream->start_pts == -1) {
|
||||
if (force_pts)
|
||||
stream->pts = force_pts;
|
||||
stream->start_pts = stream->pts;
|
||||
stream->start_pts = pts;
|
||||
}
|
||||
len = s->packet_data_max_size - stream->buffer_ptr;
|
||||
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) {
|
||||
/* output the packet */
|
||||
if (stream->start_pts == -1)
|
||||
stream->start_pts = stream->pts;
|
||||
stream->start_pts = pts;
|
||||
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;
|
||||
}
|
||||
|
||||
@ -510,7 +495,7 @@ static int mpegps_read_packet(AVFormatContext *s,
|
||||
int len, size, startcode, i, c, flags, header_len, type, codec_id;
|
||||
INT64 pts, dts;
|
||||
|
||||
/* next start code (should be immediately after */
|
||||
/* next start code (should be immediately after) */
|
||||
redo:
|
||||
m->header_state = 0xff;
|
||||
size = MAX_SYNC_SIZE;
|
||||
@ -536,8 +521,8 @@ static int mpegps_read_packet(AVFormatContext *s,
|
||||
goto redo;
|
||||
|
||||
len = get_be16(&s->pb);
|
||||
pts = 0;
|
||||
dts = 0;
|
||||
pts = AV_NOPTS_VALUE;
|
||||
dts = AV_NOPTS_VALUE;
|
||||
/* stuffing */
|
||||
for(;;) {
|
||||
c = get_byte(&s->pb);
|
||||
@ -555,7 +540,6 @@ static int mpegps_read_packet(AVFormatContext *s,
|
||||
if ((c & 0xf0) == 0x20) {
|
||||
pts = get_pts(&s->pb, c);
|
||||
len -= 4;
|
||||
dts = pts;
|
||||
} else if ((c & 0xf0) == 0x30) {
|
||||
pts = get_pts(&s->pb, c);
|
||||
dts = get_pts(&s->pb, -1);
|
||||
@ -573,7 +557,6 @@ static int mpegps_read_packet(AVFormatContext *s,
|
||||
goto redo;
|
||||
if ((flags & 0xc0) == 0x80) {
|
||||
pts = get_pts(&s->pb, -1);
|
||||
dts = pts;
|
||||
header_len -= 5;
|
||||
len -= 5;
|
||||
} if ((flags & 0xc0) == 0xc0) {
|
||||
|
Loading…
Reference in New Issue
Block a user