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
|
* 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);
|
||||||
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, 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) {
|
||||||
|
Loading…
Reference in New Issue
Block a user