summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/demuxers/demux_real.c16
-rw-r--r--src/input/input_rtsp.c26
-rw-r--r--src/input/libreal/real.c6
-rw-r--r--src/input/librtsp/rtsp_session.c30
-rw-r--r--src/input/librtsp/rtsp_session.h4
5 files changed, 62 insertions, 20 deletions
diff --git a/src/demuxers/demux_real.c b/src/demuxers/demux_real.c
index 7441c8619..90852c25c 100644
--- a/src/demuxers/demux_real.c
+++ b/src/demuxers/demux_real.c
@@ -31,7 +31,7 @@
*
* Based on FFmpeg's libav/rm.c.
*
- * $Id: demux_real.c,v 1.109 2006/07/10 22:08:13 dgp85 Exp $
+ * $Id: demux_real.c,v 1.110 2006/12/18 21:31:47 klan Exp $
*/
#ifdef HAVE_CONFIG_H
@@ -1409,12 +1409,15 @@ static int demux_real_seek (demux_plugin_t *this_gen,
real_index_entry_t *index, *other_index = NULL;
int i = 0, entries;
- start_pos = (off_t) ( (double) start_pos / 65535 *
- this->input->get_length (this->input) );
+ lprintf("seek start_pos=%d, start_time=%d, playing=%d\n",
+ (int)start_pos, start_time, playing);
if((this->input->get_capabilities(this->input) & INPUT_CAP_SEEKABLE) &&
((this->audio_stream && this->audio_stream->index) ||
(this->video_stream && this->video_stream->index))) {
+
+ start_pos = (off_t) ( (double) start_pos / 65535 *
+ this->input->get_length (this->input) );
/* video index has priority over audio index */
if(this->video_stream && this->video_stream->index) {
@@ -1453,6 +1456,13 @@ static int demux_real_seek (demux_plugin_t *this_gen,
_x_demux_flush_engine(this->stream);
}
}
+ else if (this->input->seek_time != NULL) {
+ /* RTSP supports only time based seek */
+ if (start_pos && !start_time)
+ start_time = (int64_t) this->duration * start_pos / 65535;
+
+ this->input->seek_time(this->input, start_time, SEEK_SET);
+ }
this->send_newpts = 1;
this->old_seqnum = -1;
diff --git a/src/input/input_rtsp.c b/src/input/input_rtsp.c
index 0256edc8d..bcbc19555 100644
--- a/src/input/input_rtsp.c
+++ b/src/input/input_rtsp.c
@@ -134,6 +134,18 @@ static off_t rtsp_plugin_seek (input_plugin_t *this_gen, off_t offset, int origi
return this->curpos;
}
+static off_t rtsp_plugin_seek_time (input_plugin_t *this_gen, int time_offset, int origin) {
+
+ rtsp_input_plugin_t *this = (rtsp_input_plugin_t *) this_gen;
+
+ lprintf ("seek_time %d msec, origin %d\n", time_offset, origin);
+
+ if (origin == SEEK_SET)
+ rtsp_session_set_start_time (this->rtsp, time_offset);
+
+ return this->curpos;
+}
+
static off_t rtsp_plugin_get_length (input_plugin_t *this_gen) {
/*
@@ -145,7 +157,7 @@ static off_t rtsp_plugin_get_length (input_plugin_t *this_gen) {
}
static uint32_t rtsp_plugin_get_capabilities (input_plugin_t *this_gen) {
- return INPUT_CAP_PREVIEW | INPUT_CAP_RIP_FORBIDDEN;
+ return INPUT_CAP_PREVIEW | INPUT_CAP_RIP_FORBIDDEN | INPUT_CAP_NOCACHE;
}
static uint32_t rtsp_plugin_get_blocksize (input_plugin_t *this_gen) {
@@ -212,7 +224,7 @@ static int rtsp_plugin_open (input_plugin_t *this_gen) {
lprintf ("trying to open '%s'\n", this->mrl);
- rtsp = rtsp_session_start(this->stream,this->mrl);
+ rtsp = rtsp_session_start(this->stream, this->mrl);
if (!rtsp) {
lprintf ("returning null.\n");
@@ -226,22 +238,19 @@ static int rtsp_plugin_open (input_plugin_t *this_gen) {
}
static input_plugin_t *rtsp_class_get_instance (input_class_t *cls_gen, xine_stream_t *stream,
- const char *data) {
+ const char *mrl) {
/* rtsp_input_class_t *cls = (rtsp_input_class_t *) cls_gen; */
rtsp_input_plugin_t *this;
- char *mrl = strdup(data);
- if (strncasecmp (mrl, "rtsp://", 6)) {
- free (mrl);
+ if (strncasecmp (mrl, "rtsp://", 6))
return NULL;
- }
this = (rtsp_input_plugin_t *) xine_xmalloc (sizeof (rtsp_input_plugin_t));
this->stream = stream;
this->rtsp = NULL;
- this->mrl = mrl;
+ this->mrl = strdup (mrl);
/* since we handle only real streams yet, we can savely add
* an .rm extention to force handling by demux_real.
*/
@@ -255,6 +264,7 @@ static input_plugin_t *rtsp_class_get_instance (input_class_t *cls_gen, xine_str
this->input_plugin.read = rtsp_plugin_read;
this->input_plugin.read_block = rtsp_plugin_read_block;
this->input_plugin.seek = rtsp_plugin_seek;
+ this->input_plugin.seek_time = rtsp_plugin_seek_time;
this->input_plugin.get_current_pos = rtsp_plugin_get_current_pos;
this->input_plugin.get_length = rtsp_plugin_get_length;
this->input_plugin.get_blocksize = rtsp_plugin_get_blocksize;
diff --git a/src/input/libreal/real.c b/src/input/libreal/real.c
index 270fd16e4..c3d39fab3 100644
--- a/src/input/libreal/real.c
+++ b/src/input/libreal/real.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: real.c,v 1.24 2006/11/29 19:43:01 dgp85 Exp $
+ * $Id: real.c,v 1.25 2006/12/18 21:31:47 klan Exp $
*
* special functions for real streams.
* adopted from joschkas real tools.
@@ -715,10 +715,6 @@ rmff_header_t *real_setup_and_get_header(rtsp_t *rtsp_session, uint32_t bandwid
rtsp_schedule_field(rtsp_session, subscribe);
rtsp_request_setparameter(rtsp_session,NULL);
- /* and finally send a play request */
- rtsp_schedule_field(rtsp_session, "Range: npt=0-");
- rtsp_request_play(rtsp_session,NULL);
-
xine_buffer_free(subscribe);
xine_buffer_free(buf);
return h;
diff --git a/src/input/librtsp/rtsp_session.c b/src/input/librtsp/rtsp_session.c
index 6f06693a9..8a5135ac3 100644
--- a/src/input/librtsp/rtsp_session.c
+++ b/src/input/librtsp/rtsp_session.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: rtsp_session.c,v 1.16 2004/04/24 16:55:42 miguelfreitas Exp $
+ * $Id: rtsp_session.c,v 1.17 2006/12/18 21:31:47 klan Exp $
*
* high level interface to rtsp servers.
*/
@@ -53,7 +53,7 @@ struct rtsp_session_s {
rtsp_t *s;
/* receive buffer */
- uint8_t *recv;
+ uint8_t *recv;
int recv_size;
int recv_read;
@@ -62,11 +62,13 @@ struct rtsp_session_s {
int header_len;
int header_read;
+ int playing;
+ int start_time;
};
rtsp_session_t *rtsp_session_start(xine_stream_t *stream, char *mrl) {
- rtsp_session_t *rtsp_session = malloc(sizeof(rtsp_session_t));
+ rtsp_session_t *rtsp_session = xine_xmalloc(sizeof(rtsp_session_t));
char *server;
char *mrl_line=strdup(mrl);
rmff_header_t *h;
@@ -144,6 +146,23 @@ connect:
return rtsp_session;
}
+void rtsp_session_set_start_time (rtsp_session_t *this, int start_time) {
+
+ if (start_time >= 0)
+ this->start_time = start_time;
+}
+
+static void rtsp_session_play (rtsp_session_t *this) {
+
+ char buf[256];
+
+ snprintf (buf, sizeof(buf), "Range: npt=%d.%03d-",
+ this->start_time/1000, this->start_time%1000);
+
+ rtsp_schedule_field (this->s, buf);
+ rtsp_request_play (this->s,NULL);
+}
+
int rtsp_session_read (rtsp_session_t *this, char *data, int len) {
int to_copy=len;
@@ -154,6 +173,11 @@ int rtsp_session_read (rtsp_session_t *this, char *data, int len) {
if (len < 0) return 0;
while (to_copy > fill) {
+ if (!this->playing) {
+ rtsp_session_play (this);
+ this->playing = 1;
+ }
+
memcpy(dest, source, fill);
to_copy -= fill;
dest += fill;
diff --git a/src/input/librtsp/rtsp_session.h b/src/input/librtsp/rtsp_session.h
index 140d09a0a..649842e7a 100644
--- a/src/input/librtsp/rtsp_session.h
+++ b/src/input/librtsp/rtsp_session.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: rtsp_session.h,v 1.6 2003/12/09 00:02:31 f1rmb Exp $
+ * $Id: rtsp_session.h,v 1.7 2006/12/18 21:31:47 klan Exp $
*
* high level interface to rtsp servers.
*/
@@ -29,6 +29,8 @@ typedef struct rtsp_session_s rtsp_session_t;
rtsp_session_t *rtsp_session_start(xine_stream_t *stream, char *mrl);
+void rtsp_session_set_start_time(rtsp_session_t *this, int start_time);
+
int rtsp_session_read(rtsp_session_t *session, char *data, int len);
int rtsp_session_peek_header(rtsp_session_t *this, char *buf, int maxsize);