⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rtsp.c

📁 video linux conference
💻 C
📖 第 1 页 / 共 3 页
字号:
            answer->p_body = NULL;            break;        case HTTPD_MSG_TEARDOWN:            /* for now only multicast so easy again */            answer->i_status = 200;            answer->psz_status = strdup( "OK" );            answer->i_body = 0;            answer->p_body = NULL;            psz_session = httpd_MsgGet( query, "Session" );            msg_Dbg( p_vod, "HTTPD_MSG_TEARDOWN for session: %s", psz_session);            p_rtsp = RtspClientGet( p_media, psz_session );            if( !p_rtsp ) break;            vod_MediaControl( p_vod, p_media, psz_session, VOD_MEDIA_STOP );            RtspClientDel( p_media, p_rtsp );            break;        default:            return VLC_EGENERIC;    }    httpd_MsgAdd( answer, "Server", "VLC Server" );    httpd_MsgAdd( answer, "Content-Length", "%d", answer->i_body );    httpd_MsgAdd( answer, "Cseq", "%d",                  atoi( httpd_MsgGet( query, "Cseq" ) ) );    httpd_MsgAdd( answer, "Cache-Control", "%s", "no-cache" );    if( psz_session )    {        httpd_MsgAdd( answer, "Session", "%s;timeout=5", psz_session );    }    return VLC_SUCCESS;}static int RtspCallbackES( httpd_callback_sys_t *p_args, httpd_client_t *cl,                           httpd_message_t *answer, httpd_message_t *query ){    media_es_t *p_es = (media_es_t*)p_args;    vod_media_t *p_media = p_es->p_media;    vod_t *p_vod = p_media->p_vod;    rtsp_client_t *p_rtsp = NULL;    char *psz_session = NULL;    char *psz_transport = NULL;    char *psz_position = NULL;    int i;    if( answer == NULL || query == NULL ) return VLC_SUCCESS;    fprintf( stderr, "RtspCallback query: type=%d\n", query->i_type );    answer->i_proto   = HTTPD_PROTO_RTSP;    answer->i_version = query->i_version;    answer->i_type    = HTTPD_MSG_ANSWER;    switch( query->i_type )    {    case HTTPD_MSG_SETUP:        psz_transport = httpd_MsgGet( query, "Transport" );        fprintf( stderr, "HTTPD_MSG_SETUP: transport=%s\n", psz_transport );        if( strstr( psz_transport, "multicast" ) && p_media->psz_destination )        {            fprintf( stderr, "HTTPD_MSG_SETUP: multicast\n" );            answer->i_status = 200;            answer->psz_status = strdup( "OK" );            answer->i_body = 0;            answer->p_body = NULL;            psz_session = httpd_MsgGet( query, "Session" );            if( !psz_session || !*psz_session )            {                asprintf( &psz_session, "%d", rand() );            }            httpd_MsgAdd( answer, "Transport",                          "RTP/AVP/UDP;destination=%s;port=%d-%d;ttl=%d",                          p_media->psz_destination, p_media->i_port,                          p_media->i_port+1, p_media->i_ttl );        }        else if( strstr( psz_transport, "unicast" ) &&                 strstr( psz_transport, "client_port=" ) )        {            rtsp_client_t *p_rtsp;            rtsp_client_es_t *p_rtsp_es;            char *ip = httpd_ClientIP( cl );            int i_port = atoi( strstr( psz_transport, "client_port=" ) +                               strlen("client_port=") );            if( !ip )            {                answer->i_status = 400;                answer->psz_status = strdup( "Internal server error" );                answer->i_body = 0;                answer->p_body = NULL;                break;            }            fprintf( stderr, "HTTPD_MSG_SETUP: unicast ip=%s port=%d\n",                     ip, i_port );            psz_session = httpd_MsgGet( query, "Session" );            if( !psz_session || !*psz_session )            {                asprintf( &psz_session, "%d", rand() );                p_rtsp = RtspClientNew( p_media, psz_session );            }            else            {                p_rtsp = RtspClientGet( p_media, psz_session );                if( !p_rtsp )                {                    /* FIXME right error code */                    answer->i_status = 400;                    answer->psz_status = strdup( "Unknown session id" );                    answer->i_body = 0;                    answer->p_body = NULL;                    free( ip );                    break;                }            }            p_rtsp_es = malloc( sizeof(rtsp_client_es_t) );            p_rtsp_es->i_port = i_port;            p_rtsp_es->psz_ip = strdup( ip );            p_rtsp_es->p_media_es = p_es;            TAB_APPEND( p_rtsp->i_es, p_rtsp->es, p_rtsp_es );            answer->i_status = 200;            answer->psz_status = strdup( "OK" );            answer->i_body = 0;            answer->p_body = NULL;            httpd_MsgAdd( answer, "Transport", "RTP/AVP/UDP;client_port=%d-%d",                          i_port, i_port + 1 );        }        else /* TODO  strstr( psz_transport, "interleaved" ) ) */        {            answer->i_status = 400;            answer->psz_status = strdup( "Bad Request" );            answer->i_body = 0;            answer->p_body = NULL;        }        break;        case HTTPD_MSG_TEARDOWN:            answer->i_status = 200;            answer->psz_status = strdup( "OK" );            answer->i_body = 0;            answer->p_body = NULL;            psz_session = httpd_MsgGet( query, "Session" );            msg_Dbg( p_vod, "HTTPD_MSG_TEARDOWN for session: %s", psz_session);            p_rtsp = RtspClientGet( p_media, psz_session );            if( !p_rtsp ) break;            for( i = 0; i < p_rtsp->i_es; i++ )            {                if( p_rtsp->es[i]->p_media_es == p_es )                {                    if( p_rtsp->es[i]->psz_ip ) free( p_rtsp->es[i]->psz_ip );                    TAB_REMOVE( p_rtsp->i_es, p_rtsp->es, p_rtsp->es[i] );                    break;                }            }            if( !p_rtsp->i_es )            {                vod_MediaControl( p_vod, p_media, psz_session,                                  VOD_MEDIA_STOP );                RtspClientDel( p_media, p_rtsp );            }            break;        case HTTPD_MSG_PLAY:            /* This is kind of a kludge. Should we only support Aggregate             * Operations ? */            psz_session = httpd_MsgGet( query, "Session" );            msg_Dbg( p_vod, "HTTPD_MSG_PLAY for session: %s", psz_session );            p_rtsp = RtspClientGet( p_media, psz_session );            psz_position = httpd_MsgGet( query, "Range" );            if( psz_position ) psz_position = strstr( psz_position, "npt=" );            if( psz_position )            {                float f_pos;                msg_Dbg( p_vod, "seeking request: %s", psz_position );                psz_position += 4;                if( sscanf( psz_position, "%f", &f_pos ) == 1 )                {                    f_pos /= ((float)(p_media->i_length/1000))/1000 / 100;                    vod_MediaControl( p_vod, p_media, psz_session,                                      VOD_MEDIA_SEEK, (double)f_pos );                }            }            answer->i_status = 200;            answer->psz_status = strdup( "OK" );            answer->i_body = 0;            answer->p_body = NULL;            break;        case HTTPD_MSG_PAUSE:            /* This is kind of a kludge. Should we only support Aggregate             * Operations ? */            psz_session = httpd_MsgGet( query, "Session" );            msg_Dbg( p_vod, "HTTPD_MSG_PAUSE for session: %s", psz_session );            p_rtsp = RtspClientGet( p_media, psz_session );            if( !p_rtsp ) break;            vod_MediaControl( p_vod, p_media, psz_session, VOD_MEDIA_PAUSE );            p_rtsp->b_paused = VLC_TRUE;            answer->i_status = 200;            answer->psz_status = strdup( "OK" );            answer->i_body = 0;            answer->p_body = NULL;            break;        default:            return VLC_EGENERIC;            break;    }    httpd_MsgAdd( answer, "Server", "VLC Server" );    httpd_MsgAdd( answer, "Content-Length", "%d", answer->i_body );    httpd_MsgAdd( answer, "Cseq", "%d",                  atoi( httpd_MsgGet( query, "Cseq" ) ) );    httpd_MsgAdd( answer, "Cache-Control", "%s", "no-cache" );    if( psz_session )    {        httpd_MsgAdd( answer, "Session", "%s"/*;timeout=5*/, psz_session );    }    return VLC_SUCCESS;}/***************************************************************************** * SDPGenerate: TODO * FIXME: need to be moved to a common place ? *****************************************************************************/static char *SDPGenerate( vod_media_t *p_media, char *psz_destination ){    int i, i_size;    char *p, *psz_sdp;    /* Calculate size */    i_size = strlen( "v=0\r\n" ) +        strlen( "o=- * * IN IP4 127.0.0.1\r\n" ) + 10 + 10 +        strlen( "s=*\r\n" ) + strlen( p_media->psz_session_name ) +        strlen( "i=*\r\n" ) + strlen( p_media->psz_session_description ) +        strlen( "u=*\r\n" ) + strlen( p_media->psz_session_url ) +        strlen( "e=*\r\n" ) + strlen( p_media->psz_session_email ) +        strlen( "t=0 0\r\n" ) + /* FIXME */        strlen( "a=tool:"PACKAGE_STRING"\r\n" ) +        strlen( "c=IN IP4 */*\r\n" ) + 20 + 10 +        strlen( psz_destination ? psz_destination : "0.0.0.0" ) +        strlen( "a=range:npt=0-1000000000.000\r\n" );    for( i = 0; i < p_media->i_es; i++ )    {        media_es_t *p_es = p_media->es[i];        i_size += strlen( "m=**d*o * RTP/AVP *\r\n" ) + 10 + 10;        if( p_es->psz_rtpmap )        {            i_size += strlen( "a=rtpmap:* *\r\n" ) +                strlen( p_es->psz_rtpmap ) + 10;        }        if( p_es->psz_fmtp )        {            i_size += strlen( "a=fmtp:* *\r\n" ) +                strlen( p_es->psz_fmtp ) + 10;        }        i_size += strlen( "a=control:*/trackid=*\r\n" ) +            strlen( p_media->psz_rtsp_control ) + 10;    }    p = psz_sdp = malloc( i_size );    p += sprintf( p, "v=0\r\n" );    p += sprintf( p, "o=- "I64Fd" %d IN IP4 127.0.0.1\r\n",                  p_media->i_sdp_id, p_media->i_sdp_version );    if( *p_media->psz_session_name )        p += sprintf( p, "s=%s\r\n", p_media->psz_session_name );    if( *p_media->psz_session_description )        p += sprintf( p, "i=%s\r\n", p_media->psz_session_description );    if( *p_media->psz_session_url )        p += sprintf( p, "u=%s\r\n", p_media->psz_session_url );    if( *p_media->psz_session_email )        p += sprintf( p, "e=%s\r\n", p_media->psz_session_email );    p += sprintf( p, "t=0 0\r\n" ); /* FIXME */    p += sprintf( p, "a=tool:"PACKAGE_STRING"\r\n" );    p += sprintf( p, "c=IN IP4 %s/%d\r\n", psz_destination ?                  psz_destination : "0.0.0.0", p_media->i_ttl );    if( p_media->i_length > 0 )    p += sprintf( p, "a=range:npt=0-%.3f\r\n",                  ((float)(p_media->i_length/1000))/1000 );    for( i = 0; i < p_media->i_es; i++ )    {        media_es_t *p_es = p_media->es[i];        if( p_es->fmt.i_cat == AUDIO_ES )        {            p += sprintf( p, "m=audio %d RTP/AVP %d\r\n",                          p_es->i_port, p_es->i_payload_type );        }        else if( p_es->fmt.i_cat == VIDEO_ES )        {            p += sprintf( p, "m=video %d RTP/AVP %d\r\n",                          p_es->i_port, p_es->i_payload_type );        }        else        {            continue;        }        if( p_es->psz_rtpmap )        {            p += sprintf( p, "a=rtpmap:%d %s\r\n", p_es->i_payload_type,                          p_es->psz_rtpmap );        }        if( p_es->psz_fmtp )        {            p += sprintf( p, "a=fmtp:%d %s\r\n", p_es->i_payload_type,                          p_es->psz_fmtp );        }        p += sprintf( p, "a=control:%s/trackid=%d\r\n",                      p_media->psz_rtsp_control, i );    }    fprintf( stderr, psz_sdp );    return psz_sdp;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -