[vlc-devel] [PATCH] realrtsp pause seek
Wang Bo
silencewang at msn.com
Fri May 23 12:50:58 CEST 2008
---
modules/access/rtsp/access.c | 92 ++++++++++++++++++++++++++++++++++++++---
modules/access/rtsp/real.c | 13 +++++-
modules/access/rtsp/rtsp.c | 54 ++++++++++++++++++++++++-
3 files changed, 149 insertions(+), 10 deletions(-)
diff --git a/modules/access/rtsp/access.c b/modules/access/rtsp/access.c
index b8b42b1..3887650 100644
--- a/modules/access/rtsp/access.c
+++ b/modules/access/rtsp/access.c
@@ -79,6 +79,7 @@ struct access_sys_t
int fd;
+ int64_t i_seekto;
block_t *p_header;
};
@@ -120,6 +121,25 @@ static int RtspRead( void *p_userdata, uint8_t *p_buffer, int i_buffer )
return net_Read( p_access, p_sys->fd, 0, p_buffer, i_buffer, true );
}
+static int RtspReadAndSkip( void * p_userdata )
+{
+ access_t *p_access = (access_t *)p_userdata;
+ access_sys_t *p_sys = p_access->p_sys;
+ char buf[10240];
+ mtime_t time_wait = 500000;
+ int size, total=0;
+
+ /*msg_Dbg( p_access, "Try RtspReadAndSkip ");*/
+ do {
+ size = net_ReadNonBlock( p_access, p_sys->fd, 0, buf, 10240, time_wait );
+ /*if ( size > 0 ) buf[size] = 0;
+ msg_Dbg( p_access, "skip %d byte [0]%c [0] %d %s", size, buf[0], buf[0], buf);*/
+ total += size;
+ }while( size > 0 );
+
+ msg_Dbg( p_access, "RtspReadAndSkip skip %d bytes ", total);
+ return total;
+}
static int RtspReadLine( void *p_userdata, uint8_t *p_buffer, int i_buffer )
{
access_t *p_access = (access_t *)p_userdata;
@@ -127,11 +147,19 @@ static int RtspReadLine( void *p_userdata, uint8_t *p_buffer, int i_buffer )
char *psz = net_Gets( VLC_OBJECT(p_access), p_sys->fd, 0 );
- //fprintf(stderr, "ReadLine: %s\n", psz);
-
- if( psz ) strncpy( (char *)p_buffer, psz, i_buffer );
+ if ( psz )
+ {
+ if( strlen( psz ) > i_buffer - 1 )
+ {
+ msg_Warn( p_access, "read data exceed the buffer size , simple skip some datas!");
+ strncpy( (char *)p_buffer, psz + strlen(psz) - i_buffer + 10, i_buffer - 1 );
+ }
+ else
+ strncpy( (char *)p_buffer, psz, i_buffer - 1 );
+ }
else *p_buffer = 0;
+ p_buffer[ i_buffer -1 ] = '\0';
free( psz );
return 0;
}
@@ -179,6 +207,7 @@ static int Open( vlc_object_t *p_this )
p_access->p_sys = p_sys = malloc( sizeof( access_sys_t ) );
p_sys->p_rtsp = malloc( sizeof( rtsp_client_t) );
+ p_sys->i_seekto = 0;
p_sys->p_header = 0;
p_sys->p_rtsp->p_userdata = p_access;
p_sys->p_rtsp->pf_connect = RtspConnect;
@@ -209,7 +238,8 @@ static int Open( vlc_object_t *p_this )
psz_server = strdup("unknown");
}
- if( strstr( psz_server, "Real" ) || strstr( psz_server, "Helix" ) )
+ /* vatata is another rtsp/p2p streaming server which support real/rmvb streaming */
+ if( strstr( psz_server, "Real" ) || strstr( psz_server, "Helix" )|| strstr( psz_server, "Vatata" ) )
{
uint32_t bandwidth = 10485800;
rmff_header_t *h;
@@ -237,6 +267,8 @@ static int Open( vlc_object_t *p_this )
p_sys->p_header = block_New( p_access, 4096 );
p_sys->p_header->i_buffer =
rmff_dump_header( h, (char *)p_sys->p_header->p_buffer, 1024 );
+ p_sys->b_seekable = true;
+ p_sys->b_pace_control = true;
rmff_free_header( h );
}
else
@@ -288,6 +320,24 @@ static block_t *BlockRead( access_t *p_access )
return p_block;
}
+ if ( p_sys->i_seekto != 0 )
+ {
+ char buf[100];
+
+ sprintf(buf, "Range: npt=%.6f-", (double) p_sys->i_seekto/1000000 );
+ msg_Dbg( p_access, "Seek to %"PRId64" %s ", p_sys->i_seekto , buf );
+
+ /*pause at first*/
+ rtsp_request_pause( p_sys->p_rtsp, NULL );
+ RtspReadAndSkip( p_access );
+ /* skip data which have sent to player, so next play will play the correct position */
+
+ /* replay*/
+ rtsp_schedule_field(p_sys->p_rtsp, buf );
+ rtsp_request_play(p_sys->p_rtsp,NULL);
+ p_sys->i_seekto = 0;
+
+ }
i_size = real_get_rdt_chunk_header( p_access->p_sys->p_rtsp, &pheader );
if( i_size <= 0 ) return 0;
@@ -303,7 +353,32 @@ static block_t *BlockRead( access_t *p_access )
*****************************************************************************/
static int Seek( access_t *p_access, int64_t i_pos )
{
+ access_sys_t *p_sys = p_access->p_sys;
+
+ p_sys->i_seekto = i_pos ;
return VLC_SUCCESS;
+
+#if 0
+ /* the code do seek, but i meet some errors, i am afarid the send rtsp request may block the thread,
+ so i move the code to another function BlockRead which is in read-thread(?) and use iseekto as flag.
+ maybe real_get_rdt_chunk_header will read the rtsp's answer in another thread?
+ or maybe it is no problem here?
+ */
+ int64_t i_time = i_pos / 1000 ;
+ char buf[100];
+ sprintf(buf, "Range: npt=%.6f-", (double) i_time/1000 );
+
+ msg_Dbg( p_access, "Seek to "I64Fd" %s ", i_time, buf );
+
+ // pause at first
+ rtsp_request_pause( p_sys->p_rtsp, NULL );
+
+ // replay
+ rtsp_schedule_field(p_sys->p_rtsp, buf );
+ rtsp_request_play(p_sys->p_rtsp,NULL);
+
+ return VLC_SUCCESS;
+#endif
}
/*****************************************************************************
@@ -311,6 +386,7 @@ static int Seek( access_t *p_access, int64_t i_pos )
*****************************************************************************/
static int Control( access_t *p_access, int i_query, va_list args )
{
+ access_sys_t *p_sys = p_access->p_sys;
bool *pb_bool;
int *pi_int;
int64_t *pi_64;
@@ -321,12 +397,12 @@ static int Control( access_t *p_access, int i_query, va_list args )
case ACCESS_CAN_SEEK:
case ACCESS_CAN_FASTSEEK:
pb_bool = (bool*)va_arg( args, bool* );
- *pb_bool = false;//p_sys->b_seekable;
+ *pb_bool = p_sys->b_seekable;
break;
case ACCESS_CAN_PAUSE:
pb_bool = (bool*)va_arg( args, bool* );
- *pb_bool = false;
+ *pb_bool = true;
break;
case ACCESS_CAN_CONTROL_PACE:
@@ -347,7 +423,9 @@ static int Control( access_t *p_access, int i_query, va_list args )
/* */
case ACCESS_SET_PAUSE_STATE:
- /* Nothing to do */
+ pb_bool = (bool*)va_arg( args, bool* );
+ if ( ! pb_bool )
+ return Seek( p_access, p_access->info.i_pos );
break;
case ACCESS_GET_TITLE_INFO:
diff --git a/modules/access/rtsp/real.c b/modules/access/rtsp/real.c
index da499ec..83d3de2 100644
--- a/modules/access/rtsp/real.c
+++ b/modules/access/rtsp/real.c
@@ -469,6 +469,11 @@ rmff_header_t *real_parse_sdp(char *data, char **stream_rules, uint32_t bandwidt
char b[64];
int rulematches[16];
+ if ( ! desc->stream[i]->asm_rule_book )
+ {
+ goto error;
+ }
+
lprintf("calling asmrp_match with:\n%s\n%u\n", desc->stream[i]->asm_rule_book, bandwidth);
n=asmrp_match(desc->stream[i]->asm_rule_book, bandwidth, rulematches);
@@ -591,7 +596,11 @@ int real_get_rdt_chunk_header(rtsp_client_t *rtsp_session, rmff_pheader_t *ph) {
ph->stream_number=(flags1>>1)&1;
ph->timestamp=ts;
ph->reserved=0;
- ph->flags=0; /* TODO: determine keyframe flag and insert here? */
+
+ if ( header[7] == 0xc0 )
+ ph->flags=2;
+ else
+ ph->flags=0;
return size;
}
@@ -690,7 +699,7 @@ rmff_header_t *real_setup_and_get_header(rtsp_client_t *rtsp_session, int bandw
rmff_fix_header(h);
#if 0
- fprintf("Title: %s\nCopyright: %s\nAuthor: %s\nStreams: %i\n",
+ fprintf(stderr, "Title: %s\nCopyright: %s\nAuthor: %s\nStreams: %i\n",
h->cont->title, h->cont->copyright, h->cont->author, h->prop->num_streams);
#endif
diff --git a/modules/access/rtsp/rtsp.c b/modules/access/rtsp/rtsp.c
index 6730a93..9b2042e 100644
--- a/modules/access/rtsp/rtsp.c
+++ b/modules/access/rtsp/rtsp.c
@@ -215,6 +215,13 @@ static int rtsp_get_answers( rtsp_client_t *rtsp )
answer = rtsp_get( rtsp );
if( !answer ) return 0;
+ if ( answer[0] == '$' )
+ {
+ free( answer );
+ rtsp_free_answers( rtsp );
+ return 0;
+ }
+
code = rtsp_get_status_code( rtsp, answer );
free( answer );
@@ -234,6 +241,7 @@ static int rtsp_get_answers( rtsp_client_t *rtsp )
// answer_seq, rtsp->p_private->cseq );
rtsp->p_private->cseq = answer_seq;
+ rtsp->p_private->cseq ++;
}
}
if( !strncasecmp( answer, "Server:", 7 ) )
@@ -337,7 +345,12 @@ int rtsp_request_describe( rtsp_client_t *rtsp, const char *what )
int rtsp_request_setup( rtsp_client_t *rtsp, const char *what )
{
+ if(! what )
+ {
+ return 500;
+ }
rtsp_send_request( rtsp, "SETUP", what );
+
return rtsp_get_answers( rtsp );
}
@@ -379,15 +392,54 @@ int rtsp_request_play( rtsp_client_t *rtsp, const char *what )
rtsp->p_private->port, rtsp->p_private->path );
}
+ rtsp_schedule_standard( rtsp );
rtsp_send_request( rtsp, "PLAY", buf );
free( buf );
return rtsp_get_answers( rtsp );
}
+int rtsp_request_pause( rtsp_client_t *rtsp, const char *what )
+{
+ char *buf;
+
+ if( what )
+ {
+ buf = strdup( what );
+ }
+ else
+ {
+ buf = malloc( strlen(rtsp->p_private->host) +
+ strlen(rtsp->p_private->path) + 16 );
+ sprintf( buf, "rtsp://%s:%i/%s", rtsp->p_private->host,
+ rtsp->p_private->port, rtsp->p_private->path );
+ }
+ rtsp_schedule_field( rtsp, "User-Agent: RealMedia Player Version 6.0.9.1235 (linux-2.0-libc6-i386-gcc2.95)" );
+ //rtsp_schedule_standard( rtsp );
+ rtsp_send_request( rtsp, "PAUSE", buf );
+ free( buf );
+
+ return rtsp_get_answers( rtsp );
+}
+
int rtsp_request_tearoff( rtsp_client_t *rtsp, const char *what )
{
- rtsp_send_request( rtsp, "TEAROFF", what );
+ char *buf;
+
+ if( what )
+ {
+ buf = strdup( what );
+ }
+ else
+ {
+ buf = malloc( strlen(rtsp->p_private->host) +
+ strlen(rtsp->p_private->path) + 16 );
+ sprintf( buf, "rtsp://%s:%i/%s", rtsp->p_private->host,
+ rtsp->p_private->port, rtsp->p_private->path );
+ }
+ rtsp_send_request( rtsp, "TEAROFF", buf );
+ free( buf );
+
return rtsp_get_answers( rtsp );
}
--
1.5.5.1
More information about the vlc-devel
mailing list