summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/demuxers/demux_mpeg_block.c88
-rw-r--r--src/input/input_dvd.c16
-rw-r--r--src/input/libdvdnav/dvdnav.c11
-rw-r--r--src/input/libdvdnav/dvdnav_events.h3
-rw-r--r--src/xine-engine/xine_internal.h3
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 */
};
/*