Originally committed as revision 3551 to svn://svn.ffmpeg.org/ffmpeg/trunk
pull/126/head
Michael Niedermayer 21 years ago
parent 7000a17542
commit 9205093333
  1. 115
      libavformat/mpeg.c

@ -43,8 +43,6 @@ typedef struct {
PacketDesc *premux_packet; PacketDesc *premux_packet;
PacketDesc **next_packet; PacketDesc **next_packet;
int packet_number; int packet_number;
int64_t start_pts;
int64_t start_dts;
uint8_t lpcm_header[3]; uint8_t lpcm_header[3];
int lpcm_align; int lpcm_align;
} StreamInfo; } StreamInfo;
@ -408,8 +406,6 @@ static int mpeg_mux_init(AVFormatContext *ctx)
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->packet_number = 0; stream->packet_number = 0;
stream->start_pts = AV_NOPTS_VALUE;
stream->start_dts = AV_NOPTS_VALUE;
} }
s->system_header_size = get_system_header_size(ctx); s->system_header_size = get_system_header_size(ctx);
s->last_scr = 0; s->last_scr = 0;
@ -840,14 +836,11 @@ static void put_vcd_padding_sector(AVFormatContext *ctx)
s->packet_number++; s->packet_number++;
} }
static int64_t update_scr(AVFormatContext *ctx,int stream_index,int64_t pts) static int64_t get_vcd_scr(AVFormatContext *ctx,int stream_index,int64_t pts)
{ {
MpegMuxContext *s = ctx->priv_data; MpegMuxContext *s = ctx->priv_data;
int64_t scr; int64_t scr;
StreamInfo *stream;
int i;
if (s->is_vcd) {
/* Since the data delivery rate is constant, SCR is computed /* Since the data delivery rate is constant, SCR is computed
using the formula C + i * 1200 where C is the start constant using the formula C + i * 1200 where C is the start constant
and i is the pack index. and i is the pack index.
@ -860,35 +853,6 @@ static int64_t update_scr(AVFormatContext *ctx,int stream_index,int64_t pts)
the "recommended" value).*/ the "recommended" value).*/
scr = 36000 + s->packet_number * 1200; scr = 36000 + s->packet_number * 1200;
#if 0
for(i=0;i<ctx->nb_streams;i++) {
stream = ctx->streams[i]->priv_data;
if(scr > stream->start_pts && stream->start_pts!=AV_NOPTS_VALUE) {
av_log(ctx, AV_LOG_DEBUG, "mpeg vcd: SCR above PTS (scr=%0.3f, stream index=%d, stream_pts=%0.3f).\n", scr/90000.0, i, stream->start_pts / 90000.0);
}
}
#endif
}
else {
/* XXX I believe this calculation of SCR is wrong. SCR
specifies at which time the data should enter the decoder.
Two packs cannot enter the decoder at the same time. */
/* XXX: system clock should be computed precisely, especially for
CBR case. The current mode gives at least something coherent */
if (stream_index == 0
&& pts != AV_NOPTS_VALUE)
scr = pts;
else
scr = s->last_scr;
}
s->last_scr=scr;
return scr; return scr;
} }
@ -1000,7 +964,7 @@ retry:
the constant overall bitrate.*/ the constant overall bitrate.*/
int vcd_pad_bytes; int vcd_pad_bytes;
while((vcd_pad_bytes = get_vcd_padding_size(ctx,stream->start_pts) ) >= s->packet_size){ //FIXME pts cannot be correct here while((vcd_pad_bytes = get_vcd_padding_size(ctx,stream->premux_packet->pts) ) >= s->packet_size){ //FIXME pts cannot be correct here
put_vcd_padding_sector(ctx); put_vcd_padding_sector(ctx);
s->last_scr += s->packet_size*90000LL / (s->mux_rate*50LL); //FIXME rounding and first few bytes of each packet s->last_scr += s->packet_size*90000LL / (s->mux_rate*50LL); //FIXME rounding and first few bytes of each packet
} }
@ -1030,8 +994,7 @@ static int mpeg_mux_write_packet(AVFormatContext *ctx, AVPacket *pkt)
uint8_t *buf= pkt->data; uint8_t *buf= pkt->data;
AVStream *st = ctx->streams[stream_index]; AVStream *st = ctx->streams[stream_index];
StreamInfo *stream = st->priv_data; StreamInfo *stream = st->priv_data;
int64_t pts, dts, new_start_pts, new_start_dts; int64_t pts, dts;
int len, avail_size;
PacketDesc *pkt_desc; PacketDesc *pkt_desc;
pts= pkt->pts; pts= pkt->pts;
@ -1081,79 +1044,9 @@ static int mpeg_mux_write_packet(AVFormatContext *ctx, AVPacket *pkt)
for(;;){ for(;;){
int ret= output_packet(ctx, 0); int ret= output_packet(ctx, 0);
if(ret<0) if(ret<=0)
return ret; return ret;
else if(ret==0)
break;
}
#if 0
/* we assume here that pts != AV_NOPTS_VALUE */
new_start_pts = stream->start_pts;
new_start_dts = stream->start_dts;
if (stream->start_pts == AV_NOPTS_VALUE) {
new_start_pts = pts;
new_start_dts = dts;
} }
avail_size = get_packet_payload_size(ctx, stream_index,
new_start_pts,
new_start_dts);
if (stream->buffer_ptr >= avail_size) {
update_scr(ctx,stream_index,stream->start_pts);
/* unlikely case: outputing the pts or dts increase the packet
size so that we cannot write the start of the next
packet. In this case, we must flush the current packet with
padding.
Note: this always happens for the first audio and video packet
in a VCD file, since they do not carry any data.*/
flush_packet(ctx, stream_index,
stream->start_pts, stream->start_dts, s->last_scr);
stream->buffer_ptr = 0;
}
stream->start_pts = new_start_pts;
stream->start_dts = new_start_dts;
stream->nb_frames++;
while (size > 0) {
avail_size = get_packet_payload_size(ctx, stream_index,
stream->start_pts,
stream->start_dts);
len = avail_size - stream->buffer_ptr;
if (len > size)
len = size;
memcpy(stream->buffer + stream->buffer_ptr, buf, len);
stream->buffer_ptr += len;
buf += len;
size -= len;
if (stream->buffer_ptr >= avail_size) {
update_scr(ctx,stream_index,stream->start_pts);
/* if packet full, we send it now */
flush_packet(ctx, stream_index,
stream->start_pts, stream->start_dts, s->last_scr);
stream->buffer_ptr = 0;
if (s->is_vcd) {
/* Write one or more padding sectors, if necessary, to reach
the constant overall bitrate.*/
int vcd_pad_bytes;
while((vcd_pad_bytes = get_vcd_padding_size(ctx,stream->start_pts) ) >= s->packet_size)
put_vcd_padding_sector(ctx);
}
/* Make sure only the FIRST pes packet for this frame has
a timestamp */
stream->start_pts = AV_NOPTS_VALUE;
stream->start_dts = AV_NOPTS_VALUE;
}
}
#endif
return 0;
} }
static int mpeg_mux_end(AVFormatContext *ctx) static int mpeg_mux_end(AVFormatContext *ctx)

Loading…
Cancel
Save