@ -900,9 +900,13 @@ int ff_rtsp_read_reply(AVFormatContext *s, RTSPMessageHeader *reply,
char buf [ 4096 ] , buf1 [ 1024 ] , * q ;
unsigned char ch ;
const char * p ;
int ret , content_length , line_count = 0 ;
int ret , content_length , line_count = 0 , request = 0 ;
unsigned char * content = NULL ;
start :
line_count = 0 ;
request = 0 ;
content = NULL ;
memset ( reply , 0 , sizeof ( * reply ) ) ;
/* parse reply (XXX: use buffers) */
@ -938,9 +942,15 @@ int ff_rtsp_read_reply(AVFormatContext *s, RTSPMessageHeader *reply,
if ( line_count = = 0 ) {
/* get reply code */
get_word ( buf1 , sizeof ( buf1 ) , & p ) ;
get_word ( buf1 , sizeof ( buf1 ) , & p ) ;
reply - > status_code = atoi ( buf1 ) ;
av_strlcpy ( reply - > reason , p , sizeof ( reply - > reason ) ) ;
if ( ! strncmp ( buf1 , " RTSP/ " , 5 ) ) {
get_word ( buf1 , sizeof ( buf1 ) , & p ) ;
reply - > status_code = atoi ( buf1 ) ;
av_strlcpy ( reply - > reason , p , sizeof ( reply - > reason ) ) ;
} else {
av_strlcpy ( reply - > reason , buf1 , sizeof ( reply - > reason ) ) ; // method
get_word ( buf1 , sizeof ( buf1 ) , & p ) ; // object
request = 1 ;
}
} else {
ff_rtsp_parse_line ( reply , p , rt , method ) ;
av_strlcat ( rt - > last_reply , p , sizeof ( rt - > last_reply ) ) ;
@ -949,7 +959,7 @@ int ff_rtsp_read_reply(AVFormatContext *s, RTSPMessageHeader *reply,
line_count + + ;
}
if ( rt - > session_id [ 0 ] = = ' \0 ' & & reply - > session_id [ 0 ] ! = ' \0 ' )
if ( rt - > session_id [ 0 ] = = ' \0 ' & & reply - > session_id [ 0 ] ! = ' \0 ' & & ! request )
av_strlcpy ( rt - > session_id , reply - > session_id , sizeof ( rt - > session_id ) ) ;
content_length = reply - > content_length ;
@ -964,6 +974,44 @@ int ff_rtsp_read_reply(AVFormatContext *s, RTSPMessageHeader *reply,
else
av_free ( content ) ;
if ( request ) {
char buf [ 1024 ] ;
char base64buf [ AV_BASE64_SIZE ( sizeof ( buf ) ) ] ;
const char * ptr = buf ;
if ( ! strcmp ( reply - > reason , " OPTIONS " ) ) {
snprintf ( buf , sizeof ( buf ) , " RTSP/1.0 200 OK \r \n " ) ;
if ( reply - > seq )
av_strlcatf ( buf , sizeof ( buf ) , " CSeq: %d \r \n " , reply - > seq ) ;
if ( reply - > session_id [ 0 ] )
av_strlcatf ( buf , sizeof ( buf ) , " Session: %s \r \n " ,
reply - > session_id ) ;
} else {
snprintf ( buf , sizeof ( buf ) , " RTSP/1.0 501 Not Implemented \r \n " ) ;
}
av_strlcat ( buf , " \r \n " , sizeof ( buf ) ) ;
if ( rt - > control_transport = = RTSP_MODE_TUNNEL ) {
av_base64_encode ( base64buf , sizeof ( base64buf ) , buf , strlen ( buf ) ) ;
ptr = base64buf ;
}
ffurl_write ( rt - > rtsp_hd_out , ptr , strlen ( ptr ) ) ;
rt - > last_cmd_time = av_gettime ( ) ;
/* Even if the request from the server had data, it is not the data
* that the caller wants or expects . The memory could also be leaked
* if the actual following reply has content data . */
if ( content_ptr )
av_freep ( content_ptr ) ;
/* If method is set, this is called from ff_rtsp_send_cmd,
* where a reply to exactly this request is awaited . For
* callers from within packet reciving , we just want to
* return to the caller and go back to receiving packets . */
if ( method )
goto start ;
return 0 ;
}
if ( rt - > seq ! = reply - > seq ) {
av_log ( s , AV_LOG_WARNING , " CSeq %d expected, %d received. \n " ,
rt - > seq , reply - > seq ) ;