access.c
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:11k
源码类别:

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * access.c: Real rtsp input
  3.  *****************************************************************************
  4.  * Copyright (C) 2005 VideoLAN
  5.  * $Id: 0115d30ad77641c7427bf22afed52e14b3e6ee6a $
  6.  *
  7.  * Authors: Gildas Bazin <gbazin@videolan.org>
  8.  *
  9.  * This program is free software; you can redistribute it and/or modify
  10.  * it under the terms of the GNU General Public License as published by
  11.  * the Free Software Foundation; either version 2 of the License, or
  12.  * (at your option) any later version.
  13.  *
  14.  * This program is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  * GNU General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU General Public License
  20.  * along with this program; if not, write to the Free Software
  21.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  22.  *****************************************************************************/
  23. /*****************************************************************************
  24.  * Preamble
  25.  *****************************************************************************/
  26. #ifdef HAVE_CONFIG_H
  27. # include "config.h"
  28. #endif
  29. #include <vlc_common.h>
  30. #include <vlc_plugin.h>
  31. #include <vlc_access.h>
  32. #include <vlc_dialog.h>
  33. #include <vlc_network.h>
  34. #include "rtsp.h"
  35. #include "real.h"
  36. /*****************************************************************************
  37.  * Module descriptor
  38.  *****************************************************************************/
  39. static int  Open ( vlc_object_t * );
  40. static void Close( vlc_object_t * );
  41. #define CACHING_TEXT N_("Caching value (ms)")
  42. #define CACHING_LONGTEXT N_( 
  43.     "Caching value for RTSP streams. This " 
  44.     "value should be set in milliseconds." )
  45. vlc_module_begin ()
  46.     set_description( N_("Real RTSP") )
  47.     set_shortname( N_("Real RTSP") )
  48.     set_category( CAT_INPUT )
  49.     set_subcategory( SUBCAT_INPUT_ACCESS )
  50.     add_integer( "realrtsp-caching", 3000, NULL,
  51.                  CACHING_TEXT, CACHING_LONGTEXT, true )
  52.         change_safe()
  53.     set_capability( "access", 10 )
  54.     set_callbacks( Open, Close )
  55.     add_shortcut( "realrtsp" )
  56.     add_shortcut( "rtsp" )
  57.     add_shortcut( "pnm" )
  58. vlc_module_end ()
  59. /*****************************************************************************
  60.  * Exported prototypes
  61.  *****************************************************************************/
  62. static block_t *BlockRead( access_t * );
  63. static int     Seek( access_t *, int64_t );
  64. static int     Control( access_t *, int, va_list );
  65. struct access_sys_t
  66. {
  67.     bool b_seekable;
  68.     bool b_pace_control;
  69.     rtsp_client_t *p_rtsp;
  70.     int fd;
  71.     block_t *p_header;
  72. };
  73. /*****************************************************************************
  74.  * Network wrappers
  75.  *****************************************************************************/
  76. static int RtspConnect( void *p_userdata, char *psz_server, int i_port )
  77. {
  78.     access_t *p_access = (access_t *)p_userdata;
  79.     access_sys_t *p_sys = p_access->p_sys;
  80.     /* Open connection */
  81.     p_sys->fd = net_ConnectTCP( p_access, psz_server, i_port );
  82.     if( p_sys->fd < 0 )
  83.     {
  84.         msg_Err( p_access, "cannot connect to %s:%d", psz_server, i_port );
  85.         dialog_Fatal( p_access, _("Connection failed"),
  86.                         _("VLC could not connect to "%s:%d"."), psz_server, i_port );
  87.         return VLC_EGENERIC;
  88.     }
  89.     return VLC_SUCCESS;
  90. }
  91. static int RtspDisconnect( void *p_userdata )
  92. {
  93.     access_t *p_access = (access_t *)p_userdata;
  94.     access_sys_t *p_sys = p_access->p_sys;
  95.     net_Close( p_sys->fd );
  96.     return VLC_SUCCESS;
  97. }
  98. static int RtspRead( void *p_userdata, uint8_t *p_buffer, int i_buffer )
  99. {
  100.     access_t *p_access = (access_t *)p_userdata;
  101.     access_sys_t *p_sys = p_access->p_sys;
  102.     return net_Read( p_access, p_sys->fd, 0, p_buffer, i_buffer, true );
  103. }
  104. static int RtspReadLine( void *p_userdata, uint8_t *p_buffer, int i_buffer )
  105. {
  106.     access_t *p_access = (access_t *)p_userdata;
  107.     access_sys_t *p_sys = p_access->p_sys;
  108.     char *psz = net_Gets( VLC_OBJECT(p_access), p_sys->fd, 0 );
  109.     //fprintf(stderr, "ReadLine: %sn", psz);
  110.     if( psz ) strncpy( (char *)p_buffer, psz, i_buffer );
  111.     else *p_buffer = 0;
  112.     free( psz );
  113.     return 0;
  114. }
  115. static int RtspWrite( void *p_userdata, uint8_t *p_buffer, int i_buffer )
  116. {
  117.     access_t *p_access = (access_t *)p_userdata;
  118.     access_sys_t *p_sys = p_access->p_sys;
  119.     //fprintf(stderr, "Write: %s", p_buffer);
  120.     net_Printf( VLC_OBJECT(p_access), p_sys->fd, 0, "%s", p_buffer );
  121.     return 0;
  122. }
  123. /*****************************************************************************
  124.  * Open: open the rtsp connection
  125.  *****************************************************************************/
  126. static int Open( vlc_object_t *p_this )
  127. {
  128.     access_t *p_access = (access_t *)p_this;
  129.     access_sys_t *p_sys;
  130.     char* psz_server = NULL;
  131.     int i_result;
  132.     if( !p_access->psz_access || (
  133.         strncmp( p_access->psz_access, "rtsp", 4 ) &&
  134.         strncmp( p_access->psz_access, "pnm", 3 )  &&
  135.         strncmp( p_access->psz_access, "realrtsp", 8 ) ))
  136.     {
  137.             return VLC_EGENERIC;
  138.     }
  139.     p_access->pf_read = NULL;
  140.     p_access->pf_block = BlockRead;
  141.     p_access->pf_seek = Seek;
  142.     p_access->pf_control = Control;
  143.     p_access->info.i_update = 0;
  144.     p_access->info.i_size = 0;
  145.     p_access->info.i_pos = 0;
  146.     p_access->info.b_eof = false;
  147.     p_access->info.i_title = 0;
  148.     p_access->info.i_seekpoint = 0;
  149.     p_access->p_sys = p_sys = malloc( sizeof( access_sys_t ) );
  150.     if( !p_sys )
  151.         return VLC_ENOMEM;
  152.     p_sys->p_rtsp = malloc( sizeof( rtsp_client_t) );
  153.     if( !p_sys->p_rtsp )
  154.     {
  155.         free( p_sys );
  156.         return VLC_ENOMEM;
  157.     }
  158.     p_sys->p_header = NULL;
  159.     p_sys->p_rtsp->p_userdata = p_access;
  160.     p_sys->p_rtsp->pf_connect = RtspConnect;
  161.     p_sys->p_rtsp->pf_disconnect = RtspDisconnect;
  162.     p_sys->p_rtsp->pf_read = RtspRead;
  163.     p_sys->p_rtsp->pf_read_line = RtspReadLine;
  164.     p_sys->p_rtsp->pf_write = RtspWrite;
  165.     i_result = rtsp_connect( p_sys->p_rtsp, p_access->psz_path, 0 );
  166.     if( i_result )
  167.     {
  168.         msg_Dbg( p_access, "could not connect to: %s", p_access->psz_path );
  169.         free( p_sys->p_rtsp );
  170.         p_sys->p_rtsp = NULL;
  171.         goto error;
  172.     }
  173.     msg_Dbg( p_access, "rtsp connected" );
  174.     /* looking for server type */
  175.     if( rtsp_search_answers( p_sys->p_rtsp, "Server" ) )
  176.         psz_server = strdup( rtsp_search_answers( p_sys->p_rtsp, "Server" ) );
  177.     else
  178.     {
  179.         if( rtsp_search_answers( p_sys->p_rtsp, "RealChallenge1" ) )
  180.             psz_server = strdup("Real");
  181.         else
  182.             psz_server = strdup("unknown");
  183.     }
  184.     if( strstr( psz_server, "Real" ) || strstr( psz_server, "Helix" ) )
  185.     {
  186.         uint32_t bandwidth = 10485800;
  187.         rmff_header_t *h;
  188.         msg_Dbg( p_access, "found a real/helix rtsp server" );
  189.         if( !(h = real_setup_and_get_header( p_sys->p_rtsp, bandwidth )) )
  190.         {
  191.             /* Check if we got a redirect */
  192.             if( rtsp_search_answers( p_sys->p_rtsp, "Location" ) )
  193.             {
  194.                 msg_Dbg( p_access, "redirect: %s",
  195.                          rtsp_search_answers(p_sys->p_rtsp, "Location") );
  196.                 msg_Warn( p_access, "redirect not supported" );
  197.                 goto error;
  198.             }
  199.             msg_Err( p_access, "rtsp session can not be established" );
  200.             dialog_Fatal( p_access, _("Session failed"),
  201.                     _("The requested RTSP session could not be established.") );
  202.             goto error;
  203.         }
  204.         p_sys->p_header = block_New( p_access, 4096 );
  205.         p_sys->p_header->i_buffer =
  206.             rmff_dump_header( h, (char *)p_sys->p_header->p_buffer, 1024 );
  207.         rmff_free_header( h );
  208.     }
  209.     else
  210.     {
  211.         msg_Warn( p_access, "only real/helix rtsp servers supported for now" );
  212.         goto error;
  213.     }
  214.     /* Update default_pts to a suitable value for file access */
  215.     var_Create( p_access, "realrtsp-caching",
  216.                 VLC_VAR_INTEGER | VLC_VAR_DOINHERIT);
  217.     free( psz_server );
  218.     return VLC_SUCCESS;
  219.  error:
  220.     free( psz_server );
  221.     Close( p_this );
  222.     return VLC_EGENERIC;
  223. }
  224. /*****************************************************************************
  225.  * Close: close the target
  226.  *****************************************************************************/
  227. static void Close( vlc_object_t * p_this )
  228. {
  229.     access_t     *p_access = (access_t*)p_this;
  230.     access_sys_t *p_sys = p_access->p_sys;
  231.     if( p_sys->p_rtsp ) rtsp_close( p_sys->p_rtsp );
  232.     free( p_sys->p_rtsp );
  233.     free( p_sys );
  234. }
  235. /*****************************************************************************
  236.  * Read: standard read on a file descriptor.
  237.  *****************************************************************************/
  238. static block_t *BlockRead( access_t *p_access )
  239. {
  240.     access_sys_t *p_sys = p_access->p_sys;
  241.     block_t *p_block;
  242.     rmff_pheader_t pheader;
  243.     int i_size;
  244.     if( p_sys->p_header )
  245.     {
  246.         p_block = p_sys->p_header;
  247.         p_sys->p_header = NULL;
  248.         return p_block;
  249.     }
  250.     i_size = real_get_rdt_chunk_header( p_access->p_sys->p_rtsp, &pheader );
  251.     if( i_size <= 0 ) return NULL;
  252.     p_block = block_New( p_access, i_size );
  253.     p_block->i_buffer = real_get_rdt_chunk( p_access->p_sys->p_rtsp, &pheader,
  254.                                             &p_block->p_buffer );
  255.     return p_block;
  256. }
  257. /*****************************************************************************
  258.  * Seek: seek to a specific location in a file
  259.  *****************************************************************************/
  260. static int Seek( access_t *p_access, int64_t i_pos )
  261. {
  262.     return VLC_SUCCESS;
  263. }
  264. /*****************************************************************************
  265.  * Control:
  266.  *****************************************************************************/
  267. static int Control( access_t *p_access, int i_query, va_list args )
  268. {
  269.     bool        *pb_bool;
  270.     int64_t     *pi_64;
  271.     switch( i_query )
  272.     {
  273.         /* */
  274.         case ACCESS_CAN_SEEK:
  275.         case ACCESS_CAN_FASTSEEK:
  276.             pb_bool = (bool*)va_arg( args, bool* );
  277.             *pb_bool = false;//p_sys->b_seekable;
  278.             break;
  279.         case ACCESS_CAN_PAUSE:
  280.             pb_bool = (bool*)va_arg( args, bool* );
  281.             *pb_bool = false;
  282.             break;
  283.         case ACCESS_CAN_CONTROL_PACE:
  284.             pb_bool = (bool*)va_arg( args, bool* );
  285.             *pb_bool = true;//p_sys->b_pace_control;
  286.             break;
  287.         case ACCESS_GET_PTS_DELAY:
  288.             pi_64 = (int64_t*)va_arg( args, int64_t * );
  289.             *pi_64 = var_GetInteger( p_access, "realrtsp-caching" ) * 1000;
  290.             break;
  291.         /* */
  292.         case ACCESS_SET_PAUSE_STATE:
  293.             /* Nothing to do */
  294.             break;
  295.         case ACCESS_GET_TITLE_INFO:
  296.         case ACCESS_SET_TITLE:
  297.         case ACCESS_SET_SEEKPOINT:
  298.         case ACCESS_SET_PRIVATE_ID_STATE:
  299.         case ACCESS_GET_META:
  300.         case ACCESS_GET_CONTENT_TYPE:
  301.             return VLC_EGENERIC;
  302.         default:
  303.             msg_Warn( p_access, "unimplemented query in control" );
  304.             return VLC_EGENERIC;
  305.     }
  306.     return VLC_SUCCESS;
  307. }