# HG changeset patch # User reimar # Date 1278105282 0 # Node ID a3a50df246f8abb5f964949329e321f8eab33fea # Parent 84f43ca3fad11ebbd7eadf98af030f9e0ff555f0 Move the subtitle pts handling code to demuxer.c This also fixes endpts using first->endpts instead of current->endpts and the move should avoid missing such fixes in the future by having all related code in one place. diff -r 84f43ca3fad1 -r a3a50df246f8 libmpdemux/demuxer.c --- a/libmpdemux/demuxer.c Fri Jul 02 19:59:02 2010 +0000 +++ b/libmpdemux/demuxer.c Fri Jul 02 21:14:42 2010 +0000 @@ -794,16 +794,42 @@ return len; } -int ds_get_packet_sub(demux_stream_t *ds, unsigned char **start) +/** + * Get a subtitle packet. In particular avoid reading the stream. + * \param pts input: maximum pts value of subtitle packet. NOPTS or NULL for any. + * output: start/referece pts of subtitle + * May be NULL. + * \param endpts output: pts for end of display time. May be NULL. + * \return -1 if no packet is available + */ +int ds_get_packet_sub(demux_stream_t *ds, unsigned char **start, + double *pts, double *endpts) { int len; + *start = NULL; + // initialize pts + if (pts) + *pts = MP_NOPTS_VALUE; + if (endpts) + *endpts = MP_NOPTS_VALUE; if (ds->buffer_pos >= ds->buffer_size) { - *start = NULL; if (!ds->packs) return -1; // no sub if (!ds_fill_buffer(ds)) return -1; // EOF } + // only start of buffer has valid pts + if (ds->buffer_pos == 0) { + if (endpts) + *endpts = ds->current->endpts; + if (pts) { + *pts = ds->current->pts; + // check if we are too early + if (*pts != MP_NOPTS_VALUE && ds->current->pts != MP_NOPTS_VALUE && + ds->current->pts > *pts) + return -1; + } + } len = ds->buffer_size - ds->buffer_pos; *start = &ds->buffer[ds->buffer_pos]; ds->buffer_pos += len; diff -r 84f43ca3fad1 -r a3a50df246f8 libmpdemux/demuxer.h --- a/libmpdemux/demuxer.h Fri Jul 02 19:59:02 2010 +0000 +++ b/libmpdemux/demuxer.h Fri Jul 02 21:14:42 2010 +0000 @@ -396,7 +396,8 @@ void ds_free_packs(demux_stream_t *ds); int ds_get_packet(demux_stream_t *ds,unsigned char **start); int ds_get_packet_pts(demux_stream_t *ds, unsigned char **start, double *pts); -int ds_get_packet_sub(demux_stream_t *ds,unsigned char **start); +int ds_get_packet_sub(demux_stream_t *ds,unsigned char **start, + double *pts, double *endpts); double ds_get_next_pts(demux_stream_t *ds); int ds_parse(demux_stream_t *sh, uint8_t **buffer, int *len, double pts, off_t pos); void ds_clear_parser(demux_stream_t *sh); diff -r 84f43ca3fad1 -r a3a50df246f8 mencoder.c --- a/mencoder.c Fri Jul 02 19:59:02 2010 +0000 +++ b/mencoder.c Fri Jul 02 21:14:42 2010 +0000 @@ -1659,7 +1659,7 @@ if(vobsub_writer){ unsigned char* packet=NULL; int len; - while((len=ds_get_packet_sub(d_dvdsub,&packet))>0){ + while((len=ds_get_packet_sub(d_dvdsub,&packet, NULL, NULL))>0){ mp_msg(MSGT_MENCODER,MSGL_V,"\rDVD sub: len=%d v_pts=%5.3f s_pts=%5.3f \n",len,sh_video->pts,d_dvdsub->pts); vobsub_out_output(vobsub_writer,packet,len,mux_v->timer + d_dvdsub->pts - sh_video->pts); } diff -r 84f43ca3fad1 -r a3a50df246f8 mpcommon.c --- a/mpcommon.c Fri Jul 02 19:59:02 2010 +0000 +++ b/mpcommon.c Fri Jul 02 21:14:42 2010 +0000 @@ -136,7 +136,7 @@ } } else { // DVD sub - len = ds_get_packet_sub(d_dvdsub, (unsigned char**)&packet); + len = ds_get_packet_sub(d_dvdsub, (unsigned char**)&packet, NULL, NULL); if (len > 0) { // XXX This is wrong, sh_video->pts can be arbitrarily // much behind demuxing position. Unfortunately using @@ -171,12 +171,11 @@ } if (d_dvdsub->non_interleaved) ds_get_next_pts(d_dvdsub); - while (d_dvdsub->first) { - double subpts = ds_get_next_pts(d_dvdsub); - if (subpts > curpts) + while (1) { + double subpts = curpts; + len = ds_get_packet_sub(d_dvdsub, &packet, &subpts, &endpts); + if (len < 0) break; - endpts = d_dvdsub->first->endpts; - len = ds_get_packet_sub(d_dvdsub, &packet); if (type == 'm') { if (len < 2) continue; len = FFMIN(len - 2, AV_RB16(packet));