diff options
-rw-r--r-- | src/demuxers/demux_mpeg_block.c | 88 | ||||
-rw-r--r-- | src/input/input_dvd.c | 16 | ||||
-rw-r--r-- | src/input/libdvdnav/dvdnav.c | 11 | ||||
-rw-r--r-- | src/input/libdvdnav/dvdnav_events.h | 3 | ||||
-rw-r--r-- | src/xine-engine/xine_internal.h | 3 |
5 files changed, 78 insertions, 43 deletions
diff --git a/src/demuxers/demux_mpeg_block.c b/src/demuxers/demux_mpeg_block.c index bc56b57ac..8b4e6309b 100644 --- a/src/demuxers/demux_mpeg_block.c +++ b/src/demuxers/demux_mpeg_block.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: demux_mpeg_block.c,v 1.162 2003/03/27 13:48:04 mroi Exp $ + * $Id: demux_mpeg_block.c,v 1.163 2003/04/05 12:28:15 miguelfreitas Exp $ * * demultiplexer for mpeg 1/2 program streams * @@ -82,6 +82,9 @@ typedef struct demux_mpeg_block_s { /* stream index for get_audio/video_frame */ int have_index; + int64_t last_cell_time; + off_t last_cell_pos; + int last_begin_time; } demux_mpeg_block_t ; typedef struct { @@ -204,18 +207,10 @@ static void demux_mpeg_block_parse_pack (demux_mpeg_block_t *this, int preview_m else buf->decoder_flags = 0; - buf->extra_info->input_pos = this->input->get_current_pos (this->input); - buf->extra_info->input_length = this->input->get_length (this->input); - - /* some input plugins like DVD can have better timing information and have - * already set the input_time, so we can derive our datarate from this */ - if (buf->extra_info->input_time) - this->rate = (int)((int64_t)buf->extra_info->input_pos * 1000 / - (buf->extra_info->input_time * 50)); - - if (this->rate && !buf->extra_info->input_time) - buf->extra_info->input_time = (int)((int64_t)buf->extra_info->input_pos - * 1000 / (this->rate * 50)); + if( !buf->extra_info->input_length ) { + buf->extra_info->input_pos = this->input->get_current_pos (this->input); + buf->extra_info->input_length = this->input->get_length (this->input); + } if (p[3] == 0xBA) { /* program stream pack header */ @@ -312,6 +307,7 @@ static void demux_mpeg_block_parse_pack (demux_mpeg_block_t *this, int preview_m if (stream_id == 0xbf) { /* NAV Packet */ int64_t start_pts, end_pts; + int64_t cell_time, frames; start_pts = (p[7+12] << 24); start_pts |= (p[7+13] << 16); @@ -323,6 +319,23 @@ static void demux_mpeg_block_parse_pack (demux_mpeg_block_t *this, int preview_m end_pts |= (p[7+18] << 8); end_pts |= p[7+19]; + cell_time = (p[7+0x18] >> 4 ) * 10 * 60 * 60 * 1000; + cell_time += (p[7+0x18] & 0x0f) * 60 * 60 * 1000; + cell_time += (p[7+0x19] >> 4 ) * 10 * 60 * 1000; + cell_time += (p[7+0x19] & 0x0f) * 60 * 1000; + cell_time += (p[7+0x1a] >> 4 ) * 10 * 1000; + cell_time += (p[7+0x1a] & 0x0f) * 1000; + frames = ((p[7+0x1b] & 0x30) >> 4) * 10; + frames += ((p[7+0x1b] & 0x0f) ) ; + + if (p[7+0x1b] & 0x80) + cell_time += (frames * 1000)/25; + else + cell_time += (frames * 1000)/30; + + this->last_cell_time = cell_time; + this->last_cell_pos = buf->extra_info->input_pos; + this->last_begin_time = buf->extra_info->input_time; #ifdef LOG printf ("demux_mpeg_block: NAV packet, start pts = %lld, end_pts = %lld\n", start_pts, end_pts); @@ -352,13 +365,27 @@ static void demux_mpeg_block_parse_pack (demux_mpeg_block_t *this, int preview_m buf->decoder_info[1] = BUF_SPECIAL_SPU_DVD_SUBTYPE; buf->decoder_info[2] = SPU_DVD_SUBTYPE_NAV; buf->pts = 0; /* NAV packets do not have PES values */ - buf->extra_info->input_pos = this->input->get_current_pos(this->input); - buf->extra_info->input_length = this->input->get_length (this->input); this->video_fifo->put (this->video_fifo, buf); return ; } + /* some input plugins like DVD can have better timing information and have + * already set the total_time, so we can derive our datarate from this */ + if (buf->extra_info->total_time) + this->rate = (int)((int64_t)buf->extra_info->input_length * 1000 / + (buf->extra_info->total_time * 50)); + + if (this->rate && this->last_cell_time) { + if( this->last_begin_time == buf->extra_info->input_time ) + buf->extra_info->input_time = this->last_cell_time + buf->extra_info->input_time + + ((buf->extra_info->input_pos - this->last_cell_pos) * 1000 / (this->rate * 50)); + } + + if (this->rate && !buf->extra_info->input_time) + buf->extra_info->input_time = (int)((int64_t)buf->extra_info->input_pos + * 1000 / (this->rate * 50)); + if (bMpeg1) { if (stream_id == 0xBF) { @@ -471,9 +498,6 @@ static void demux_mpeg_block_parse_pack (demux_mpeg_block_t *this, int preview_m buf->decoder_info[2] = SPU_DVD_SUBTYPE_PACKAGE; buf->pts = pts; - buf->extra_info->input_pos = this->input->get_current_pos(this->input); - buf->extra_info->input_length = this->input->get_length (this->input); - this->video_fifo->put (this->video_fifo, buf); #ifdef LOG printf ("demux_mpeg_block: SPU PACK put on fifo\n"); @@ -493,9 +517,6 @@ static void demux_mpeg_block_parse_pack (demux_mpeg_block_t *this, int preview_m if( !preview_mode ) check_newpts( this, pts, PTS_VIDEO ); - buf->extra_info->input_pos = this->input->get_current_pos(this->input); - buf->extra_info->input_length = this->input->get_length (this->input); - this->video_fifo->put (this->video_fifo, buf); #ifdef LOG printf ("demux_mpeg_block: SPU SVCD PACK (%lld, %d) put on fifo\n", pts, spu_id); @@ -515,9 +536,6 @@ static void demux_mpeg_block_parse_pack (demux_mpeg_block_t *this, int preview_m if( !preview_mode ) check_newpts( this, pts, PTS_VIDEO ); - buf->extra_info->input_pos = this->input->get_current_pos(this->input); - buf->extra_info->input_length = this->input->get_length (this->input); - this->video_fifo->put (this->video_fifo, buf); #ifdef LOG printf ("demux_mpeg_block: SPU CVD PACK (%lld, %d) put on fifo\n", pts, spu_id); @@ -543,9 +561,6 @@ static void demux_mpeg_block_parse_pack (demux_mpeg_block_t *this, int preview_m if( !preview_mode ) check_newpts( this, pts, PTS_AUDIO ); - buf->extra_info->input_pos = this->input->get_current_pos(this->input); - buf->extra_info->input_length = this->input->get_length (this->input); - if(this->audio_fifo) { this->audio_fifo->put (this->audio_fifo, buf); #ifdef LOG @@ -610,9 +625,6 @@ static void demux_mpeg_block_parse_pack (demux_mpeg_block_t *this, int preview_m if( !preview_mode ) check_newpts( this, pts, PTS_AUDIO ); - buf->extra_info->input_pos = this->input->get_current_pos(this->input); - buf->extra_info->input_length = this->input->get_length (this->input); - if(this->audio_fifo) { this->audio_fifo->put (this->audio_fifo, buf); #ifdef LOG @@ -633,9 +645,6 @@ static void demux_mpeg_block_parse_pack (demux_mpeg_block_t *this, int preview_m if( !preview_mode ) check_newpts( this, pts, PTS_VIDEO ); - buf->extra_info->input_pos = this->input->get_current_pos(this->input); - buf->extra_info->input_length = this->input->get_length (this->input); - this->video_fifo->put (this->video_fifo, buf); #ifdef LOG printf ("demux_mpeg_block: MPEG Video PACK put on fifo\n"); @@ -655,9 +664,6 @@ static void demux_mpeg_block_parse_pack (demux_mpeg_block_t *this, int preview_m if( !preview_mode ) check_newpts( this, pts, PTS_AUDIO ); - buf->extra_info->input_pos = this->input->get_current_pos(this->input); - buf->extra_info->input_length = this->input->get_length (this->input); - if(this->audio_fifo) { this->audio_fifo->put (this->audio_fifo, buf); #ifdef LOG @@ -948,7 +954,14 @@ static int demux_mpeg_block_seek (demux_plugin_t *this_gen, this->input->seek (this->input, start_pos, SEEK_SET); } else if (start_time) { - start_pos = start_time * this->rate * 50; + + if (this->last_cell_time) { + start_pos = start_time - (this->last_cell_time + this->last_begin_time)/1000; + start_pos *= this->rate * 50; + start_pos += this->last_cell_pos; + } else { + start_pos = start_time * this->rate * 50; + } start_pos /= (off_t) this->blocksize; start_pos *= (off_t) this->blocksize; @@ -960,6 +973,7 @@ static int demux_mpeg_block_seek (demux_plugin_t *this_gen, /* * now start demuxing */ + this->last_cell_time = 0; this->send_newpts = 1; if( !this->stream->demux_thread_running ) { diff --git a/src/input/input_dvd.c b/src/input/input_dvd.c index f945f0fe2..b36edb934 100644 --- a/src/input/input_dvd.c +++ b/src/input/input_dvd.c @@ -18,7 +18,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: input_dvd.c,v 1.141 2003/04/04 19:20:48 miguelfreitas Exp $ + * $Id: input_dvd.c,v 1.142 2003/04/05 12:28:16 miguelfreitas Exp $ * */ @@ -150,6 +150,7 @@ typedef struct { time_t pause_end_time; int64_t pg_length; int64_t pgc_length; + int64_t cell_start; int32_t buttonN; int typed_buttonN;/* for XINE_EVENT_INPUT_NUMBER_* */ @@ -627,6 +628,7 @@ static buf_element_t *dvd_plugin_read_block (input_plugin_t *this_gen, this->pg_length = cell_event->pg_length; this->pgc_length = cell_event->pgc_length; + this->cell_start = cell_event->cell_start; } break; case DVDNAV_HOP_CHANNEL: @@ -702,12 +704,16 @@ static buf_element_t *dvd_plugin_read_block (input_plugin_t *this_gen, if (this->pg_length && this->pgc_length) { int pos, length; dvdnav_get_position(this->dvdnav, &pos, &length); + buf->extra_info->input_pos = pos * (off_t)DVD_BLOCK_SIZE; + buf->extra_info->input_length = length * (off_t)DVD_BLOCK_SIZE; switch (((dvd_input_class_t *)this->input_plugin.input_class)->seek_mode) { case 0: /* PGC based seeking */ - buf->extra_info->input_time = this->pgc_length * pos / (length * 90); + buf->extra_info->total_time = this->pgc_length / 90; + buf->extra_info->input_time = this->cell_start / 90; break; case 1: /* PG based seeking */ - buf->extra_info->input_time = this->pg_length * pos / (length * 90); + buf->extra_info->total_time = this->pg_length / 90; + buf->extra_info->input_time = 0; break; } } @@ -1627,6 +1633,10 @@ static void *init_class (xine_t *xine, void *data) { /* * $Log: input_dvd.c,v $ + * Revision 1.142 2003/04/05 12:28:16 miguelfreitas + * "perfect" time display for dvds + * (see thread on xine-devel for details) + * * Revision 1.141 2003/04/04 19:20:48 miguelfreitas * add initial async error/general message reporting to frontend * obs: more messages should be added diff --git a/src/input/libdvdnav/dvdnav.c b/src/input/libdvdnav/dvdnav.c index 5cbc17615..bf9002ef7 100644 --- a/src/input/libdvdnav/dvdnav.c +++ b/src/input/libdvdnav/dvdnav.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: dvdnav.c,v 1.21 2003/04/01 09:02:43 jcdutton Exp $ + * $Id: dvdnav.c,v 1.22 2003/04/05 12:28:16 miguelfreitas Exp $ * */ @@ -602,6 +602,11 @@ dvdnav_status_t dvdnav_get_next_cache_block(dvdnav_t *this, unsigned char **buf, cell_event->pg_length += dvdnav_convert_time(&state->pgc->cell_playback[i - 1].playback_time); cell_event->pgc_length = dvdnav_convert_time(&state->pgc->playback_time); + + cell_event->cell_start = 0; + for (i = 1; i < state->cellN; i++) + cell_event->cell_start += + dvdnav_convert_time(&state->pgc->cell_playback[i - 1].playback_time); this->position_current.cell = this->position_next.cell; this->position_current.cell_restart = this->position_next.cell_restart; @@ -1018,6 +1023,10 @@ uint32_t dvdnav_get_next_still_flag(dvdnav_t *this) { /* * $Log: dvdnav.c,v $ + * Revision 1.22 2003/04/05 12:28:16 miguelfreitas + * "perfect" time display for dvds + * (see thread on xine-devel for details) + * * Revision 1.21 2003/04/01 09:02:43 jcdutton * Get libdvdnav to build in DEBUG and TRACE mode. * diff --git a/src/input/libdvdnav/dvdnav_events.h b/src/input/libdvdnav/dvdnav_events.h index 95f1e23ad..918e5df3d 100644 --- a/src/input/libdvdnav/dvdnav_events.h +++ b/src/input/libdvdnav/dvdnav_events.h @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: dvdnav_events.h,v 1.8 2003/03/25 13:17:21 mroi Exp $ + * $Id: dvdnav_events.h,v 1.9 2003/04/05 12:28:16 miguelfreitas Exp $ * */ @@ -99,6 +99,7 @@ typedef struct { int64_t cell_length; /*!< The length of the current cell in PTS ticks */ int64_t pg_length; /*!< The length of the current program in PTS ticks */ int64_t pgc_length; /*!< The length of the current program chain in PTS ticks */ + int64_t cell_start; /*!< The start of the current cell in PTS ticks */ } dvdnav_cell_change_event_t; /* FIXME: These are unused. */ diff --git a/src/xine-engine/xine_internal.h b/src/xine-engine/xine_internal.h index c59f04741..3564e598c 100644 --- a/src/xine-engine/xine_internal.h +++ b/src/xine-engine/xine_internal.h @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: xine_internal.h,v 1.132 2003/04/04 19:20:54 miguelfreitas Exp $ + * $Id: xine_internal.h,v 1.133 2003/04/05 12:28:16 miguelfreitas Exp $ * */ @@ -129,6 +129,7 @@ struct extra_info_s { int64_t vpts; /* set on output layers only */ int invalid; /* do not use this extra info to update anything */ + int total_time; /* duration in miliseconds of the stream */ }; /* |