]> git.sesse.net Git - vlc/blobdiff - modules/demux/live555.cpp
Be more carefull on when rtpInfo timestamps should be set.
[vlc] / modules / demux / live555.cpp
index 6eaea80689130fc201b31921b1c77d470cb86cf0..21af20dd7022f024b64cec2c3909e89580bfa46e 100644 (file)
@@ -146,6 +146,7 @@ struct timeout_thread_t
     VLC_COMMON_MEMBERS
 
     int64_t      i_remain;
+    vlc_bool_t   b_handle_keep_alive;
     demux_sys_t  *p_sys;
 };
 
@@ -459,6 +460,21 @@ createnew:
         return VLC_EGENERIC;
     }
 
+    /* Kasenna enables KeepAlive by analysing the User-Agent string. 
+     * Appending _KA to the string should be enough to enable this feature, 
+     * however, there is a bug where the _KA doesn't get parsed from the 
+     * default User-Agent as created by VLC/Live555 code. This is probably due 
+     * to spaces in the string or the string being too long. Here we override
+     * the default string with a more compact version.
+     */
+    if( var_CreateGetBool( p_demux, "rtsp-kasenna" ))
+    {
+#if LIVEMEDIA_LIBRARY_VERSION_INT > 1130457500
+        p_sys->rtsp->setUserAgentString( "VLC_MEDIA_PLAYER_KA" );
+#endif
+    }
+
+
     psz_url = (char*)malloc( strlen( p_sys->psz_path ) + 8 );
     if( !psz_url ) return VLC_ENOMEM;
 
@@ -478,6 +494,8 @@ createnew:
         psz_pwd  = var_CreateGetString( p_demux, "rtsp-pwd" );
     }
 
+describe:
+msg_Info( p_demux, "[%s] user=%s pwd=%s", psz_url, psz_user, psz_pwd );
     authenticator.setUsernameAndPassword( (const char*)psz_user,
                                           (const char*)psz_pwd );
 
@@ -485,7 +503,6 @@ createnew:
                                                &authenticator );
     if( psz_options ) delete [] psz_options;
 
-describe:
     p_sdp = p_sys->rtsp->describeURL( psz_url,
                 &authenticator, var_CreateGetBool( p_demux, "rtsp-kasenna" ) );
 
@@ -499,7 +516,9 @@ describe:
         const char *psz_error = p_sys->env->getResultMsg();
 
         msg_Dbg( p_demux, "DESCRIBE failed with %d: %s", i_code, psz_error );
-        sscanf( psz_error, "%*sRTSP/%*s%3u", &i_code );
+        if( var_CreateGetBool( p_demux, "rtsp-http" ) )
+            sscanf( psz_error, "%*s %*s HTTP GET %*s HTTP/%*u.%*u %3u %*s", &i_code );
+        else sscanf( psz_error, "%*sRTSP/%*s%3u", &i_code );
 
         if( i_code == 401 )
         {
@@ -511,12 +530,12 @@ describe:
                                                    &psz_login, &psz_password );
             if( i_ret == DIALOG_OK_YES )
             {
-               msg_Dbg( p_demux, "retrying with user=%s, pwd=%s",
-                           psz_login, psz_password );
-               if( psz_url ) free( psz_url );
-               if( psz_login ) psz_user = psz_login;
-               if( psz_password ) psz_pwd = psz_password;
-               goto describe;
+                msg_Dbg( p_demux, "retrying with user=%s, pwd=%s",
+                            psz_login, psz_password );
+                if( psz_login ) psz_user = psz_login;
+                if( psz_password ) psz_pwd = psz_password;
+                i_ret = VLC_SUCCESS;
+                goto describe;
             }
             if( psz_login ) free( psz_login );
             if( psz_password ) free( psz_password );
@@ -956,10 +975,10 @@ static int Play( demux_t *p_demux )
     p_sys->i_pcr = 0;
 
 #if (LIVEMEDIA_LIBRARY_VERSION_INT >= 1195257600)
-    /* TODO */
     for( i = 0; i < p_sys->i_track; i++ )
     {
-        p_sys->track[i]->i_pts = (int64_t) ( p_sys->track[i]->sub->rtpInfo.timestamp * (double)1000000.0 );
+        if( !p_sys->track[i]->b_rtcp_sync )
+            p_sys->track[i]->i_pts = (int64_t) ( p_sys->track[i]->sub->rtpInfo.timestamp * (double)1000000.0 );
         p_sys->track[i]->i_start_seq = (int)p_sys->track[i]->sub->rtpInfo.seqNum;
         msg_Info( p_demux, "set startseq: %u", p_sys->track[i]->i_start_seq );
     }
@@ -1162,7 +1181,7 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
             if( p_sys->rtsp && p_sys->i_npt_length > 0 )
             {
                 int i;
-                time = f * (double)p_sys->i_npt_length / 1000000.0;   /* in second */
+                time = f * (double)p_sys->i_npt_length / (double)1000000.0;   /* in second */
                 if( !p_sys->rtsp->playMediaSession( *p_sys->ms, time, -1, 1 ) )
                 {
                     msg_Err( p_demux, "PLAY failed %s",
@@ -1175,6 +1194,8 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
                 /* Retrieve RTP-Info values */
                 for( i = 0; i < p_sys->i_track; i++ )
                 {
+                    //if( !p_sys->track[i]->b_rtcp_sync )
+                    p_sys->track[i]->b_rtcp_sync = VLC_FALSE;
                     p_sys->track[i]->i_pts = (int64_t) ( p_sys->track[i]->sub->rtpInfo.timestamp * (double)1000000.0 );
                     p_sys->track[i]->i_start_seq = p_sys->track[i]->sub->rtpInfo.seqNum;
                     msg_Info( p_demux, "set pos startseq: %u", p_sys->track[i]->i_start_seq );
@@ -1246,12 +1267,27 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
                     msg_Err( p_demux, "PLAY or PAUSE failed %s", p_sys->env->getResultMsg() );
                     return VLC_EGENERIC;
             }
+
+            /* When we Pause, we'll need the TimeoutPrevention thread to
+             * handle sending the "Keep Alive" message to the server. 
+             * Unfortunately Live555 isn't thread safe and so can't 
+             * do this normally while the main Demux thread is handling
+             * a live stream. We end up with the Timeout thread blocking
+             * waiting for a response from the server. So when we PAUSE
+             * we set a flag that the TimeoutPrevention function will check
+             * and if it's set, it will trigger the GET_PARAMETER message */
+            if( b_bool && p_sys->p_timeout != NULL )
+                p_sys->p_timeout->b_handle_keep_alive = VLC_TRUE;
+            else if( !b_bool && p_sys->p_timeout != NULL ) 
+                p_sys->p_timeout->b_handle_keep_alive = VLC_FALSE;
+
             es_out_Control( p_demux->out, ES_OUT_RESET_PCR );
             p_sys->i_pcr = 0;
 #if (LIVEMEDIA_LIBRARY_VERSION_INT >= 1195257600)
             for( i = 0; i < p_sys->i_track; i++ )
             {
-                p_sys->track[i]->i_pts = (int64_t) ( p_sys->track[i]->sub->rtpInfo.timestamp * (double)1000000.0 );
+                if( !p_sys->track[i]->b_rtcp_sync )
+                    p_sys->track[i]->i_pts = 0; // (int64_t) ( p_sys->track[i]->sub->rtpInfo.timestamp * (double)1000000.0 );
                 p_sys->track[i]->i_start_seq = p_sys->track[i]->sub->rtpInfo.seqNum;
                 msg_Info( p_demux, "set pause startseq: %u", p_sys->track[i]->i_start_seq );
             }
@@ -1613,10 +1649,21 @@ static void TimeoutPrevention( timeout_thread_t *p_timeout )
     {
         if( p_timeout->i_remain <= 0 )
         {
+            char *psz_bye = NULL;
             p_timeout->i_remain = (int64_t)p_timeout->p_sys->i_timeout -2;
             p_timeout->i_remain *= 1000000;
-            p_timeout->p_sys->b_timeout_call = VLC_TRUE;
             msg_Dbg( p_timeout, "reset the timeout timer" );
+            if( p_timeout->b_handle_keep_alive == VLC_TRUE )
+            {
+#if LIVEMEDIA_LIBRARY_VERSION_INT >= 1138089600
+                p_timeout->p_sys->rtsp->getMediaSessionParameter( *p_timeout->p_sys->ms, NULL, psz_bye );
+#endif
+                p_timeout->p_sys->b_timeout_call = VLC_FALSE;
+            }
+            else
+            {
+                p_timeout->p_sys->b_timeout_call = VLC_TRUE;
+            }
         }
         p_timeout->i_remain -= 200000;
         msleep( 200000 ); /* 200 ms */