You've already forked FFmpeg
mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-08-10 06:10:52 +02:00
Make timestamp interpolation work with mpeg2 field pictures.
Cleaner/simpler solutions are welcome. Originally committed as revision 12156 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
@@ -2788,6 +2788,7 @@ typedef struct AVCodecParserContext {
|
|||||||
/* video info */
|
/* video info */
|
||||||
int pict_type; /* XXX: Put it back in AVCodecContext. */
|
int pict_type; /* XXX: Put it back in AVCodecContext. */
|
||||||
int repeat_pict; /* XXX: Put it back in AVCodecContext. */
|
int repeat_pict; /* XXX: Put it back in AVCodecContext. */
|
||||||
|
int parity;
|
||||||
int64_t pts; /* pts of the current frame */
|
int64_t pts; /* pts of the current frame */
|
||||||
int64_t dts; /* dts of the current frame */
|
int64_t dts; /* dts of the current frame */
|
||||||
|
|
||||||
|
@@ -36,6 +36,7 @@ static void mpegvideo_extract_headers(AVCodecParserContext *s,
|
|||||||
int horiz_size_ext, vert_size_ext, bit_rate_ext;
|
int horiz_size_ext, vert_size_ext, bit_rate_ext;
|
||||||
//FIXME replace the crap with get_bits()
|
//FIXME replace the crap with get_bits()
|
||||||
s->repeat_pict = 0;
|
s->repeat_pict = 0;
|
||||||
|
s->parity = 0;
|
||||||
buf_end = buf + buf_size;
|
buf_end = buf + buf_size;
|
||||||
while (buf < buf_end) {
|
while (buf < buf_end) {
|
||||||
start_code= -1;
|
start_code= -1;
|
||||||
@@ -105,8 +106,11 @@ static void mpegvideo_extract_headers(AVCodecParserContext *s,
|
|||||||
|
|
||||||
/* the packet only represents half a frame
|
/* the packet only represents half a frame
|
||||||
XXX,FIXME maybe find a different solution */
|
XXX,FIXME maybe find a different solution */
|
||||||
if(picture_structure != 3)
|
if(picture_structure != 3){
|
||||||
s->repeat_pict = -1;
|
s->repeat_pict = -1;
|
||||||
|
s->parity = picture_structure-1;
|
||||||
|
}else
|
||||||
|
s->parity = !top_field_first;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@@ -337,8 +337,8 @@ typedef struct AVStream {
|
|||||||
struct AVCodecParserContext *parser;
|
struct AVCodecParserContext *parser;
|
||||||
|
|
||||||
int64_t cur_dts;
|
int64_t cur_dts;
|
||||||
int last_IP_duration;
|
int last_IP_duration[2];
|
||||||
int64_t last_IP_pts;
|
int64_t last_IP_pts[2];
|
||||||
/* av_seek_frame() support */
|
/* av_seek_frame() support */
|
||||||
AVIndexEntry *index_entries; /**< only used if the format does not
|
AVIndexEntry *index_entries; /**< only used if the format does not
|
||||||
support seeking natively */
|
support seeking natively */
|
||||||
|
@@ -702,21 +702,30 @@ static void compute_pkt_fields(AVFormatContext *s, AVStream *st,
|
|||||||
/* interpolate PTS and DTS if they are not present */
|
/* interpolate PTS and DTS if they are not present */
|
||||||
if(delay <=1){
|
if(delay <=1){
|
||||||
if (presentation_delayed) {
|
if (presentation_delayed) {
|
||||||
|
int fields= 2 + (pc ? pc->repeat_pict : 0);
|
||||||
|
int field_duration= pkt->duration / fields;
|
||||||
|
int parity= pc ? pc->parity : 0;
|
||||||
/* DTS = decompression timestamp */
|
/* DTS = decompression timestamp */
|
||||||
/* PTS = presentation timestamp */
|
/* PTS = presentation timestamp */
|
||||||
if (pkt->dts == AV_NOPTS_VALUE)
|
if (pkt->dts == AV_NOPTS_VALUE)
|
||||||
pkt->dts = st->last_IP_pts;
|
pkt->dts = st->last_IP_pts[parity];
|
||||||
update_initial_timestamps(s, pkt->stream_index, pkt->dts, pkt->pts);
|
update_initial_timestamps(s, pkt->stream_index, pkt->dts, pkt->pts);
|
||||||
if (pkt->dts == AV_NOPTS_VALUE)
|
if (pkt->dts == AV_NOPTS_VALUE)
|
||||||
pkt->dts = st->cur_dts;
|
pkt->dts = st->cur_dts;
|
||||||
|
|
||||||
/* this is tricky: the dts must be incremented by the duration
|
/* this is tricky: the dts must be incremented by the duration
|
||||||
of the frame we are displaying, i.e. the last I- or P-frame */
|
of the frame we are displaying, i.e. the last I- or P-frame */
|
||||||
if (st->last_IP_duration == 0)
|
st->cur_dts = pkt->dts;
|
||||||
st->last_IP_duration = pkt->duration;
|
for(i=0; i<fields; i++){
|
||||||
st->cur_dts = pkt->dts + st->last_IP_duration;
|
int p= (parity + i)&1;
|
||||||
st->last_IP_duration = pkt->duration;
|
if(!st->last_IP_duration[p])
|
||||||
st->last_IP_pts= pkt->pts;
|
st->last_IP_duration[p]= field_duration;
|
||||||
|
st->cur_dts += st->last_IP_duration[p];
|
||||||
|
st->last_IP_pts[p]= pkt->pts;
|
||||||
|
if(pkt->pts != AV_NOPTS_VALUE)
|
||||||
|
st->last_IP_pts[p] += i*field_duration;
|
||||||
|
st->last_IP_duration[p]= field_duration;
|
||||||
|
}
|
||||||
/* cannot compute PTS if not present (we can compute it only
|
/* cannot compute PTS if not present (we can compute it only
|
||||||
by knowing the future */
|
by knowing the future */
|
||||||
} else if(pkt->pts != AV_NOPTS_VALUE || pkt->dts != AV_NOPTS_VALUE || pkt->duration){
|
} else if(pkt->pts != AV_NOPTS_VALUE || pkt->dts != AV_NOPTS_VALUE || pkt->duration){
|
||||||
@@ -1014,7 +1023,8 @@ static void av_read_frame_flush(AVFormatContext *s)
|
|||||||
av_parser_close(st->parser);
|
av_parser_close(st->parser);
|
||||||
st->parser = NULL;
|
st->parser = NULL;
|
||||||
}
|
}
|
||||||
st->last_IP_pts = AV_NOPTS_VALUE;
|
st->last_IP_pts[0] =
|
||||||
|
st->last_IP_pts[1] = AV_NOPTS_VALUE;
|
||||||
st->cur_dts = AV_NOPTS_VALUE; /* we set the current DTS to an unspecified origin */
|
st->cur_dts = AV_NOPTS_VALUE; /* we set the current DTS to an unspecified origin */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1622,7 +1632,8 @@ static void av_estimate_timings_from_pts(AVFormatContext *ic, offset_t old_offse
|
|||||||
for(i=0; i<ic->nb_streams; i++){
|
for(i=0; i<ic->nb_streams; i++){
|
||||||
st= ic->streams[i];
|
st= ic->streams[i];
|
||||||
st->cur_dts= st->first_dts;
|
st->cur_dts= st->first_dts;
|
||||||
st->last_IP_pts = AV_NOPTS_VALUE;
|
st->last_IP_pts[0] =
|
||||||
|
st->last_IP_pts[1] = AV_NOPTS_VALUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2181,7 +2192,8 @@ AVStream *av_new_stream(AVFormatContext *s, int id)
|
|||||||
|
|
||||||
/* default pts setting is MPEG-like */
|
/* default pts setting is MPEG-like */
|
||||||
av_set_pts_info(st, 33, 1, 90000);
|
av_set_pts_info(st, 33, 1, 90000);
|
||||||
st->last_IP_pts = AV_NOPTS_VALUE;
|
st->last_IP_pts[0] =
|
||||||
|
st->last_IP_pts[1] = AV_NOPTS_VALUE;
|
||||||
for(i=0; i<MAX_REORDER_DELAY+1; i++)
|
for(i=0; i<MAX_REORDER_DELAY+1; i++)
|
||||||
st->pts_buffer[i]= AV_NOPTS_VALUE;
|
st->pts_buffer[i]= AV_NOPTS_VALUE;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user