mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
harcoded DTS computation for mpeg
Originally committed as revision 2624 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
d60a8f85d7
commit
e45f19437e
@ -346,7 +346,7 @@ static int get_packet_payload_size(AVFormatContext *ctx, int stream_index,
|
||||
if (s->is_mpeg2)
|
||||
buf_index += 3;
|
||||
if (pts != AV_NOPTS_VALUE) {
|
||||
if (dts != AV_NOPTS_VALUE)
|
||||
if (dts != pts)
|
||||
buf_index += 5 + 5;
|
||||
else
|
||||
buf_index += 5;
|
||||
@ -410,7 +410,7 @@ static void flush_packet(AVFormatContext *ctx, int stream_index,
|
||||
header_len = 0;
|
||||
}
|
||||
if (pts != AV_NOPTS_VALUE) {
|
||||
if (dts != AV_NOPTS_VALUE)
|
||||
if (dts != pts)
|
||||
header_len += 5 + 5;
|
||||
else
|
||||
header_len += 5;
|
||||
@ -444,7 +444,7 @@ static void flush_packet(AVFormatContext *ctx, int stream_index,
|
||||
put_byte(&ctx->pb, 0x80); /* mpeg2 id */
|
||||
|
||||
if (pts != AV_NOPTS_VALUE) {
|
||||
if (dts != AV_NOPTS_VALUE) {
|
||||
if (dts != pts) {
|
||||
put_byte(&ctx->pb, 0xc0); /* flags */
|
||||
put_byte(&ctx->pb, header_len - 3);
|
||||
put_timestamp(&ctx->pb, 0x03, pts);
|
||||
@ -460,7 +460,7 @@ static void flush_packet(AVFormatContext *ctx, int stream_index,
|
||||
}
|
||||
} else {
|
||||
if (pts != AV_NOPTS_VALUE) {
|
||||
if (dts != AV_NOPTS_VALUE) {
|
||||
if (dts != pts) {
|
||||
put_timestamp(&ctx->pb, 0x03, pts);
|
||||
put_timestamp(&ctx->pb, 0x01, dts);
|
||||
} else {
|
||||
@ -497,28 +497,75 @@ static void flush_packet(AVFormatContext *ctx, int stream_index,
|
||||
stream->frame_start_offset = 0;
|
||||
}
|
||||
|
||||
/* XXX: move that to upper layer */
|
||||
/* XXX: we assume that there are always 'max_b_frames' between
|
||||
reference frames. A better solution would be to use the AVFrame pts
|
||||
field */
|
||||
static void compute_pts_dts(AVStream *st, int64_t *ppts, int64_t *pdts,
|
||||
int64_t timestamp)
|
||||
{
|
||||
int frame_delay;
|
||||
int64_t pts, dts;
|
||||
|
||||
if (st->codec.codec_type == CODEC_TYPE_VIDEO &&
|
||||
st->codec.max_b_frames != 0) {
|
||||
frame_delay = (st->codec.frame_rate_base * 90000LL) /
|
||||
st->codec.frame_rate;
|
||||
if (timestamp == 0) {
|
||||
/* specific case for first frame : DTS just before */
|
||||
pts = timestamp;
|
||||
dts = timestamp - frame_delay;
|
||||
} else {
|
||||
timestamp -= frame_delay;
|
||||
if (st->codec.coded_frame->pict_type == FF_B_TYPE) {
|
||||
/* B frames has identical pts/dts */
|
||||
pts = timestamp;
|
||||
dts = timestamp;
|
||||
} else {
|
||||
/* a reference frame has a pts equal to the dts of the
|
||||
_next_ one */
|
||||
dts = timestamp;
|
||||
pts = timestamp + (st->codec.max_b_frames + 1) * frame_delay;
|
||||
}
|
||||
}
|
||||
#if 1
|
||||
printf("pts=%0.3f dts=%0.3f pict_type=%c\n",
|
||||
pts / 90000.0, dts / 90000.0,
|
||||
av_get_pict_type_char(st->codec.coded_frame->pict_type));
|
||||
#endif
|
||||
} else {
|
||||
pts = timestamp;
|
||||
dts = timestamp;
|
||||
}
|
||||
*ppts = pts & ((1LL << 33) - 1);
|
||||
*pdts = dts & ((1LL << 33) - 1);
|
||||
}
|
||||
|
||||
static int mpeg_mux_write_packet(AVFormatContext *ctx, int stream_index,
|
||||
const uint8_t *buf, int size, int64_t pts)
|
||||
const uint8_t *buf, int size,
|
||||
int64_t timestamp)
|
||||
{
|
||||
MpegMuxContext *s = ctx->priv_data;
|
||||
AVStream *st = ctx->streams[stream_index];
|
||||
StreamInfo *stream = st->priv_data;
|
||||
int64_t dts, new_start_pts, new_start_dts;
|
||||
int64_t pts, dts, new_start_pts, new_start_dts;
|
||||
int len, avail_size;
|
||||
|
||||
compute_pts_dts(st, &pts, &dts, timestamp);
|
||||
|
||||
/* XXX: system clock should be computed precisely, especially for
|
||||
CBR case. The current mode gives at least something coherent */
|
||||
if (stream_index == s->scr_stream_index)
|
||||
s->last_scr = pts;
|
||||
|
||||
#if 0
|
||||
printf("%d: pts=%0.3f scr=%0.3f\n",
|
||||
stream_index, pts / 90000.0, s->last_scr / 90000.0);
|
||||
printf("%d: pts=%0.3f dts=%0.3f scr=%0.3f\n",
|
||||
stream_index,
|
||||
pts / 90000.0,
|
||||
dts / 90000.0,
|
||||
s->last_scr / 90000.0);
|
||||
#endif
|
||||
|
||||
/* XXX: currently no way to pass dts, will change soon */
|
||||
dts = AV_NOPTS_VALUE;
|
||||
|
||||
/* we assume here that pts != AV_NOPTS_VALUE */
|
||||
new_start_pts = stream->start_pts;
|
||||
new_start_dts = stream->start_dts;
|
||||
|
Loading…
Reference in New Issue
Block a user