livedotcom.cpp
上传用户:riyaled888
上传日期:2009-03-27
资源大小:7338k
文件大小:35k
源码类别:

多媒体

开发平台:

MultiPlatform

  1. /*****************************************************************************
  2.  * live.cpp : live.com support.
  3.  *****************************************************************************
  4.  * Copyright (C) 2003-2004 VideoLAN
  5.  * $Id: livedotcom.cpp 9298 2004-11-12 22:23:11Z hartman $
  6.  *
  7.  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  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., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  22.  *****************************************************************************/
  23. /*****************************************************************************
  24.  * Preamble
  25.  *****************************************************************************/
  26. #include <stdlib.h>                                      /* malloc(), free() */
  27. #include <vlc/vlc.h>
  28. #include <vlc/input.h>
  29. #include <iostream>
  30. #if defined( WIN32 )
  31. #   include <winsock2.h>
  32. #endif
  33. #include "BasicUsageEnvironment.hh"
  34. #include "GroupsockHelper.hh"
  35. #include "liveMedia.hh"
  36. extern "C" {
  37. #include "../access/mms/asf.h"  /* Who said ugly ? */
  38. }
  39. #if (LIVEMEDIA_LIBRARY_VERSION_INT < 1089936000)
  40. #define RECLAIM_ENV(env) delete (env)
  41. #else
  42. #define RECLAIM_ENV(env) (env)->reclaim()
  43. #endif
  44. using namespace std;
  45. /*****************************************************************************
  46.  * Module descriptor
  47.  *****************************************************************************/
  48. static int  Open ( vlc_object_t * );
  49. static void Close( vlc_object_t * );
  50. #define CACHING_TEXT N_("Caching value (ms)")
  51. #define CACHING_LONGTEXT N_( 
  52.     "Allows you to modify the default caching value for RTSP streams. This " 
  53.     "value should be set in millisecond units." )
  54. #define KASENNA_TEXT N_( "Kasenna RTSP dialect")
  55. #define KASENNA_LONGTEXT N_( "Kasenna server speak an old and unstandard dialect of RTSP " 
  56.     "When you set this parameter, VLC will try this dialect for communication. In " 
  57.     "this mode you cannot talk to normal RTSP servers." )
  58. vlc_module_begin();
  59.     set_description( _("live.com (RTSP/RTP/SDP) demuxer" ) );
  60.     set_capability( "demux2", 50 );
  61.     set_callbacks( Open, Close );
  62.     add_shortcut( "live" );
  63.     add_submodule();
  64.         set_description( _("RTSP/RTP access and demux") );
  65.         add_shortcut( "rtsp" );
  66.         add_shortcut( "sdp" );
  67.         set_capability( "access_demux", 0 );
  68.         set_callbacks( Open, Close );
  69.         add_bool( "rtsp-tcp", 0, NULL,
  70.                   N_("Use RTP over RTSP (TCP)"),
  71.                   N_("Use RTP over RTSP (TCP)"), VLC_TRUE );
  72.         add_integer( "rtsp-caching", 4 * DEFAULT_PTS_DELAY / 1000, NULL,
  73.             CACHING_TEXT, CACHING_LONGTEXT, VLC_TRUE );
  74.         add_bool( "rtsp-kasenna", VLC_FALSE, NULL, KASENNA_TEXT,
  75.                   KASENNA_LONGTEXT, VLC_TRUE );
  76. vlc_module_end();
  77. /* TODO:
  78.  *  - Improve support of PS/TS
  79.  *  - Support X-QT/X-QUICKTIME generic codec for audio.
  80.  *
  81.  *  - Check memory leak, delete/free -> still one when using rtsp-tcp but I'm
  82.  *  not sure if it comes from me.
  83.  *
  84.  */
  85. /*****************************************************************************
  86.  * Local prototypes
  87.  *****************************************************************************/
  88. typedef struct
  89. {
  90.     demux_t     *p_demux;
  91.     vlc_bool_t   b_quicktime;
  92.     vlc_bool_t   b_muxed;
  93.     vlc_bool_t   b_asf;
  94.     es_format_t  fmt;
  95.     es_out_id_t  *p_es;
  96.     stream_t     *p_out_muxed;    /* for muxed stream */
  97.     RTPSource    *rtpSource;
  98.     FramedSource *readSource;
  99.     vlc_bool_t   b_rtcp_sync;
  100.     uint8_t      *p_buffer;
  101.     unsigned int  i_buffer;
  102.     char         waiting;
  103.     mtime_t      i_pts;
  104. } live_track_t;
  105. struct demux_sys_t
  106. {
  107.     char         *p_sdp;    /* XXX mallocated */
  108.     MediaSession     *ms;
  109.     TaskScheduler    *scheduler;
  110.     UsageEnvironment *env ;
  111.     RTSPClient       *rtsp;
  112.     /* */
  113.     int              i_track;
  114.     live_track_t     **track;   /* XXX mallocated */
  115.     mtime_t          i_pcr;
  116.     mtime_t          i_pcr_start;
  117.     /* Asf */
  118.     asf_header_t     asfh;
  119.     stream_t         *p_out_asf;
  120.     /* */
  121.     mtime_t          i_length;
  122.     mtime_t          i_start;
  123.     char             event;
  124. };
  125. static int Demux  ( demux_t * );
  126. static int Control( demux_t *, int, va_list );
  127. static int ParseASF( demux_t * );
  128. static void StreamRead( void *p_private, unsigned int i_size, unsigned int i_truncated_bytes, struct timeval pts, unsigned int i_duration );
  129. static void StreamClose( void *p_private );
  130. static void TaskInterrupt( void *p_private );
  131. /*****************************************************************************
  132.  * DemuxOpen:
  133.  *****************************************************************************/
  134. static int  Open ( vlc_object_t *p_this )
  135. {
  136.     demux_t     *p_demux = (demux_t*)p_this;
  137.     demux_sys_t *p_sys;
  138.     MediaSubsessionIterator *iter;
  139.     MediaSubsession *sub;
  140.     vlc_bool_t b_rtsp_tcp;
  141.     uint8_t *p_peek;
  142.     int     i_sdp;
  143.     int     i_sdp_max;
  144.     uint8_t *p_sdp;
  145.     if( p_demux->s )
  146.     {
  147.         /* See if it looks like a SDP
  148.            v, o, s fields are mandatory and in this order */
  149.         if( stream_Peek( p_demux->s, &p_peek, 7 ) < 7 )
  150.         {
  151.             msg_Err( p_demux, "cannot peek" );
  152.             return VLC_EGENERIC;
  153.         }
  154.         if( strncmp( (char*)p_peek, "v=0rn", 5 ) && strncmp( (char*)p_peek, "v=0n", 4 ) &&
  155.             ( p_peek[0] < 'a' || p_peek[0] > 'z' || p_peek[1] != '=' ) )
  156.         {
  157.             msg_Warn( p_demux, "SDP module discarded" );
  158.             return VLC_EGENERIC;
  159.         }
  160.     }
  161.     else
  162.     {
  163.         var_Create( p_demux, "rtsp-caching", VLC_VAR_INTEGER|VLC_VAR_DOINHERIT );
  164.     }
  165.     p_demux->pf_demux  = Demux;
  166.     p_demux->pf_control= Control;
  167.     p_demux->p_sys     = p_sys = (demux_sys_t*)malloc( sizeof( demux_sys_t ) );
  168.     p_sys->p_sdp = NULL;
  169.     p_sys->scheduler = NULL;
  170.     p_sys->env = NULL;
  171.     p_sys->ms = NULL;
  172.     p_sys->rtsp = NULL;
  173.     p_sys->i_track = 0;
  174.     p_sys->track   = NULL;
  175.     p_sys->i_pcr   = 0;
  176.     p_sys->i_pcr_start = 0;
  177.     p_sys->i_length = 0;
  178.     p_sys->i_start = 0;
  179.     p_sys->p_out_asf = NULL;
  180.     if( ( p_sys->scheduler = BasicTaskScheduler::createNew() ) == NULL )
  181.     {
  182.         msg_Err( p_demux, "BasicTaskScheduler::createNew failed" );
  183.         goto error;
  184.     }
  185.     if( ( p_sys->env = BasicUsageEnvironment::createNew(*p_sys->scheduler) ) == NULL )
  186.     {
  187.         msg_Err( p_demux, "BasicUsageEnvironment::createNew failed" );
  188.         goto error;
  189.     }
  190.     if( p_demux->s == NULL && !strcasecmp( p_demux->psz_access, "rtsp" ) )
  191.     {
  192.         char *psz_url;
  193.         char *psz_options;
  194.         if( ( p_sys->rtsp = RTSPClient::createNew(*p_sys->env, 1/*verbose*/, "VLC Media Player" ) ) == NULL )
  195.         {
  196.             msg_Err( p_demux, "RTSPClient::createNew failed (%s)", p_sys->env->getResultMsg() );
  197.             goto error;
  198.         }
  199.         psz_url = (char*)malloc( strlen( p_demux->psz_path ) + 8 );
  200.         sprintf( psz_url, "rtsp://%s", p_demux->psz_path );
  201.         /* Add kasenna option */
  202.         psz_options = p_sys->rtsp->sendOptionsCmd( psz_url );
  203.         if( psz_options )
  204.             delete [] psz_options;
  205.         p_sdp = (uint8_t*)p_sys->rtsp->describeURL( psz_url,
  206.                               NULL, var_CreateGetBool( p_demux, "rtsp-kasenna" ) );
  207.         if( p_sdp == NULL )
  208.         {
  209.             msg_Err( p_demux, "describeURL failed (%s)", p_sys->env->getResultMsg() );
  210.             free( psz_url );
  211.             goto error;
  212.         }
  213.         free( psz_url );
  214.         /* malloc-ated copy */
  215.         p_sys->p_sdp = strdup( (char*)p_sdp );
  216.         delete[] p_sdp;
  217.         fprintf( stderr, "sdp=%sn", p_sys->p_sdp );
  218.     }
  219.     else if( p_demux->s == NULL && !strcasecmp( p_demux->psz_access, "sdp" ) )
  220.     {
  221.         p_sys->p_sdp = strdup( p_demux->psz_path );
  222.     }
  223.     else
  224.     {
  225.         /* Gather the complete sdp file */
  226.         i_sdp = 0;
  227.         i_sdp_max = 1000;
  228.         p_sdp = (uint8_t*)malloc( i_sdp_max );
  229.         for( ;; )
  230.         {
  231.             int i_read = stream_Read( p_demux->s, &p_sdp[i_sdp], i_sdp_max - i_sdp - 1 );
  232.             if( i_read < 0 )
  233.             {
  234.                 msg_Err( p_demux, "failed to read SDP" );
  235.                 free( p_sys );
  236.                 return VLC_EGENERIC;
  237.             }
  238.             i_sdp += i_read;
  239.             if( i_read < i_sdp_max - i_sdp - 1 )
  240.             {
  241.                 p_sdp[i_sdp] = '';
  242.                 break;
  243.             }
  244.             i_sdp_max += 1000;
  245.             p_sdp = (uint8_t*)realloc( p_sdp, i_sdp_max );
  246.         }
  247.         p_sys->p_sdp = (char*)p_sdp;
  248.         msg_Dbg( p_demux, "sdp=%sn", p_sys->p_sdp );
  249.     }
  250.     if( ( p_sys->ms = MediaSession::createNew(*p_sys->env, p_sys->p_sdp ) ) == NULL )
  251.     {
  252.         msg_Err( p_demux, "MediaSession::createNew failed" );
  253.         goto error;
  254.     }
  255.     b_rtsp_tcp = var_CreateGetBool( p_demux, "rtsp-tcp" );
  256.     /* Initialise each media subsession */
  257.     iter = new MediaSubsessionIterator( *p_sys->ms );
  258.     while( ( sub = iter->next() ) != NULL )
  259.     {
  260.         unsigned int i_buffer = 0;
  261.         Boolean bInit;
  262.         /* Value taken from mplayer */
  263.         if( !strcmp( sub->mediumName(), "audio" ) )
  264.             i_buffer = 100000;
  265.         else if( !strcmp( sub->mediumName(), "video" ) )
  266.             i_buffer = 2000000;
  267.         else
  268.             continue;
  269.         if( !strcmp( sub->codecName(), "X-ASF-PF" ) )
  270.             bInit = sub->initiate( 4 ); /* Constant ? */
  271.         else
  272.             bInit = sub->initiate();
  273.         if( !bInit )
  274.         {
  275.             msg_Warn( p_demux, "RTP subsession '%s/%s' failed(%s)", sub->mediumName(), sub->codecName(), p_sys->env->getResultMsg() );
  276.         }
  277.         else
  278.         {
  279.             if( sub->rtpSource() )
  280.             {
  281.                 int fd = sub->rtpSource()->RTPgs()->socketNum();
  282.                 /* Increase the buffer size */
  283.                 increaseReceiveBufferTo( *p_sys->env, fd, i_buffer );
  284.             }
  285.             msg_Dbg( p_demux, "RTP subsession '%s/%s'", sub->mediumName(), sub->codecName() );
  286.             /* Issue the SETUP */
  287.             if( p_sys->rtsp )
  288.             {
  289.                 p_sys->rtsp->setupMediaSubsession( *sub, False, b_rtsp_tcp ? True : False );
  290.             }
  291.         }
  292.     }
  293.     if( p_sys->rtsp )
  294.     {
  295.         /* The PLAY */
  296.         if( !p_sys->rtsp->playMediaSession( *p_sys->ms ) )
  297.         {
  298.             msg_Err( p_demux, "PLAY failed %s", p_sys->env->getResultMsg() );
  299.             goto error;
  300.         }
  301.     }
  302.     /* Create all es struct */
  303.     iter->reset();
  304.     while( ( sub = iter->next() ) != NULL )
  305.     {
  306.         live_track_t *tk;
  307.         if( sub->readSource() == NULL )
  308.         {
  309.             continue;
  310.         }
  311.         tk = (live_track_t*)malloc( sizeof( live_track_t ) );
  312.         tk->p_demux = p_demux;
  313.         tk->waiting = 0;
  314.         tk->i_pts   = 0;
  315.         tk->b_quicktime = VLC_FALSE;
  316.         tk->b_muxed     = VLC_FALSE;
  317.         tk->b_asf       = VLC_FALSE;
  318.         tk->b_rtcp_sync = VLC_FALSE;
  319.         tk->p_out_muxed = NULL;
  320.         tk->p_es        = NULL;
  321.         tk->i_buffer    = 65536;
  322.         tk->p_buffer    = (uint8_t *)malloc( 65536 );
  323.         /* Value taken from mplayer */
  324.         if( !strcmp( sub->mediumName(), "audio" ) )
  325.         {
  326.             es_format_Init( &tk->fmt, AUDIO_ES, VLC_FOURCC( 'u', 'n', 'd', 'f' ) );
  327.             tk->fmt.audio.i_channels = sub->numChannels();
  328.             tk->fmt.audio.i_rate = sub->rtpSource()->timestampFrequency();
  329.             if( !strcmp( sub->codecName(), "MPA" ) ||
  330.                 !strcmp( sub->codecName(), "MPA-ROBUST" ) ||
  331.                 !strcmp( sub->codecName(), "X-MP3-DRAFT-00" ) )
  332.             {
  333.                 tk->fmt.i_codec = VLC_FOURCC( 'm', 'p', 'g', 'a' );
  334.                 tk->fmt.audio.i_rate = 0;
  335.             }
  336.             else if( !strcmp( sub->codecName(), "AC3" ) )
  337.             {
  338.                 tk->fmt.i_codec = VLC_FOURCC( 'a', '5', '2', ' ' );
  339.                 tk->fmt.audio.i_rate = 0;
  340.             }
  341.             else if( !strcmp( sub->codecName(), "L16" ) )
  342.             {
  343.                 tk->fmt.i_codec = VLC_FOURCC( 't', 'w', 'o', 's' );
  344.                 tk->fmt.audio.i_bitspersample = 16;
  345.             }
  346.             else if( !strcmp( sub->codecName(), "L8" ) )
  347.             {
  348.                 tk->fmt.i_codec = VLC_FOURCC( 'a', 'r', 'a', 'w' );
  349.                 tk->fmt.audio.i_bitspersample = 8;
  350.             }
  351.             else if( !strcmp( sub->codecName(), "PCMU" ) )
  352.             {
  353.                 tk->fmt.i_codec = VLC_FOURCC( 'u', 'l', 'a', 'w' );
  354.             }
  355.             else if( !strcmp( sub->codecName(), "PCMA" ) )
  356.             {
  357.                 tk->fmt.i_codec = VLC_FOURCC( 'a', 'l', 'a', 'w' );
  358.             }
  359.             else if( !strcmp( sub->codecName(), "MP4A-LATM" ) )
  360.             {
  361.                 unsigned int i_extra;
  362.                 uint8_t      *p_extra;
  363.                 tk->fmt.i_codec = VLC_FOURCC( 'm', 'p', '4', 'a' );
  364.                 if( ( p_extra = parseStreamMuxConfigStr( sub->fmtp_config(), i_extra ) ) )
  365.                 {
  366.                     tk->fmt.i_extra = i_extra;
  367.                     tk->fmt.p_extra = malloc( i_extra );
  368.                     memcpy( tk->fmt.p_extra, p_extra, i_extra );
  369.                     delete[] p_extra;
  370.                 }
  371.             }
  372.             else if( !strcmp( sub->codecName(), "MPEG4-GENERIC" ) )
  373.             {
  374.                 unsigned int i_extra;
  375.                 uint8_t      *p_extra;
  376.                 tk->fmt.i_codec = VLC_FOURCC( 'm', 'p', '4', 'a' );
  377.                 if( ( p_extra = parseGeneralConfigStr( sub->fmtp_config(), i_extra ) ) )
  378.                 {
  379.                     tk->fmt.i_extra = i_extra;
  380.                     tk->fmt.p_extra = malloc( i_extra );
  381.                     memcpy( tk->fmt.p_extra, p_extra, i_extra );
  382.                     delete[] p_extra;
  383.                 }
  384.             }
  385.             else if( !strcmp( sub->codecName(), "X-ASF-PF" ) )
  386.             {
  387.                 tk->b_asf = VLC_TRUE;
  388.                 if( p_sys->p_out_asf == NULL )
  389.                     p_sys->p_out_asf = stream_DemuxNew( p_demux, "asf", p_demux->out );;
  390.             }
  391.         }
  392.         else if( !strcmp( sub->mediumName(), "video" ) )
  393.         {
  394.             es_format_Init( &tk->fmt, VIDEO_ES, VLC_FOURCC( 'u', 'n', 'd', 'f' ) );
  395.             if( !strcmp( sub->codecName(), "MPV" ) )
  396.             {
  397.                 tk->fmt.i_codec = VLC_FOURCC( 'm', 'p', 'g', 'v' );
  398.             }
  399.             else if( !strcmp( sub->codecName(), "H263" ) ||
  400.                      !strcmp( sub->codecName(), "H263-1998" ) ||
  401.                      !strcmp( sub->codecName(), "H263-2000" ) )
  402.             {
  403.                 tk->fmt.i_codec = VLC_FOURCC( 'H', '2', '6', '3' );
  404.             }
  405.             else if( !strcmp( sub->codecName(), "H261" ) )
  406.             {
  407.                 tk->fmt.i_codec = VLC_FOURCC( 'H', '2', '6', '1' );
  408.             }
  409.             else if( !strcmp( sub->codecName(), "JPEG" ) )
  410.             {
  411.                 tk->fmt.i_codec = VLC_FOURCC( 'M', 'J', 'P', 'G' );
  412.             }
  413.             else if( !strcmp( sub->codecName(), "X-SV3V-ES" ) )
  414.             {
  415.                 tk->fmt.i_codec = VLC_FOURCC( 'S', 'V', 'Q', '3' );
  416.             }
  417.             else if( !strcmp( sub->codecName(), "MP4V-ES" ) )
  418.             {
  419.                 unsigned int i_extra;
  420.                 uint8_t      *p_extra;
  421.                 tk->fmt.i_codec = VLC_FOURCC( 'm', 'p', '4', 'v' );
  422.                 if( ( p_extra = parseGeneralConfigStr( sub->fmtp_config(), i_extra ) ) )
  423.                 {
  424.                     tk->fmt.i_extra = i_extra;
  425.                     tk->fmt.p_extra = malloc( i_extra );
  426.                     memcpy( tk->fmt.p_extra, p_extra, i_extra );
  427.                     delete[] p_extra;
  428.                 }
  429.             }
  430.             else if( !strcmp( sub->codecName(), "X-QT" ) || !strcmp( sub->codecName(), "X-QUICKTIME" ) )
  431.             {
  432.                 tk->b_quicktime = VLC_TRUE;
  433.             }
  434.             else if( !strcmp( sub->codecName(), "MP2T" ) )
  435.             {
  436.                 tk->b_muxed = VLC_TRUE;
  437.                 tk->p_out_muxed = stream_DemuxNew( p_demux, "ts", p_demux->out );
  438.             }
  439.             else if( !strcmp( sub->codecName(), "MP2P" ) || !strcmp( sub->codecName(), "MP1S" ) )
  440.             {
  441.                 tk->b_muxed = VLC_TRUE;
  442.                 tk->p_out_muxed = stream_DemuxNew( p_demux, "ps", p_demux->out );
  443.             }
  444.             else if( !strcmp( sub->codecName(), "X-ASF-PF" ) )
  445.             {
  446.                 tk->b_asf = VLC_TRUE;
  447.                 if( p_sys->p_out_asf == NULL )
  448.                     p_sys->p_out_asf = stream_DemuxNew( p_demux, "asf", p_demux->out );;
  449.             }
  450.         }
  451.         if( tk->fmt.i_codec != VLC_FOURCC( 'u', 'n', 'd', 'f' ) )
  452.         {
  453.             tk->p_es = es_out_Add( p_demux->out, &tk->fmt );
  454.         }
  455.         if( sub->rtcpInstance() != NULL )
  456.         {
  457.             sub->rtcpInstance()->setByeHandler( StreamClose, tk );
  458.         }
  459.         if( tk->p_es || tk->b_quicktime || tk->b_muxed || tk->b_asf )
  460.         {
  461.             tk->readSource = sub->readSource();
  462.             tk->rtpSource  = sub->rtpSource();
  463.             /* Append */
  464.             p_sys->track = (live_track_t**)realloc( p_sys->track, sizeof( live_track_t ) * ( p_sys->i_track + 1 ) );
  465.             p_sys->track[p_sys->i_track++] = tk;
  466.         }
  467.         else
  468.         {
  469.             free( tk );
  470.         }
  471.     }
  472.     delete iter;
  473.     if( p_sys->p_out_asf && ParseASF( p_demux ) )
  474.     {
  475.         msg_Err( p_demux, "cannot find a usable asf header" );
  476.         /* TODO Clean tracks */
  477.         goto error;
  478.     }
  479.     p_sys->i_length = (mtime_t)(p_sys->ms->playEndTime() * 1000000.0);
  480.     if( p_sys->i_length < 0 )
  481.     {
  482.         p_sys->i_length = 0;
  483.     }
  484.     else if( p_sys->i_length > 0 )
  485.     {
  486.         /* FIXME */
  487.         /* p_input->stream.p_selected_area->i_size = 1000;*/ /* needed for now */
  488.     }
  489.     if( p_sys->i_track <= 0 )
  490.     {
  491.         msg_Err( p_demux, "no codec supported, aborting" );
  492.         goto error;
  493.     }
  494.     return VLC_SUCCESS;
  495. error:
  496.     if( p_sys->p_out_asf )
  497.     {
  498.         stream_DemuxDelete( p_sys->p_out_asf );
  499.     }
  500.     if( p_sys->ms )
  501.     {
  502.         Medium::close( p_sys->ms );
  503.     }
  504.     if( p_sys->rtsp )
  505.     {
  506.         Medium::close( p_sys->rtsp );
  507.     }
  508.     if( p_sys->env )
  509.     {
  510.         RECLAIM_ENV(p_sys->env);
  511.     }
  512.     if( p_sys->scheduler )
  513.     {
  514.         delete p_sys->scheduler;
  515.     }
  516.     if( p_sys->p_sdp )
  517.     {
  518.         free( p_sys->p_sdp );
  519.     }
  520.     free( p_sys );
  521.     return VLC_EGENERIC;
  522. }
  523. /*****************************************************************************
  524.  * DemuxClose:
  525.  *****************************************************************************/
  526. static void Close( vlc_object_t *p_this )
  527. {
  528.     demux_t *p_demux = (demux_t*)p_this;
  529.     demux_sys_t    *p_sys = p_demux->p_sys;
  530.     int            i;
  531.     for( i = 0; i < p_sys->i_track; i++ )
  532.     {
  533.         live_track_t *tk = p_sys->track[i];
  534.         if( tk->b_muxed )
  535.         {
  536.             stream_DemuxDelete( tk->p_out_muxed );
  537.         }
  538.         free( tk->p_buffer );
  539.         free( tk );
  540.     }
  541.     if( p_sys->i_track )
  542.     {
  543.         free( p_sys->track );
  544.     }
  545.     if( p_sys->p_out_asf )
  546.     {
  547.         stream_DemuxDelete( p_sys->p_out_asf );
  548.     }
  549.     if( p_sys->rtsp && p_sys->ms )
  550.     {
  551.         /* TEARDOWN */
  552.         p_sys->rtsp->teardownMediaSession( *p_sys->ms );
  553.     }
  554.     Medium::close( p_sys->ms );
  555.     if( p_sys->rtsp )
  556.     {
  557.         Medium::close( p_sys->rtsp );
  558.     }
  559.     if( p_sys->env )
  560.     {
  561.         RECLAIM_ENV(p_sys->env);
  562.     }
  563.     if( p_sys->scheduler )
  564.     {
  565.         delete p_sys->scheduler;
  566.     }
  567.     if( p_sys->p_sdp )
  568.     {
  569.         free( p_sys->p_sdp );
  570.     }
  571.     free( p_sys );
  572. }
  573. /*****************************************************************************
  574.  * Demux:
  575.  *****************************************************************************/
  576. static int Demux( demux_t *p_demux )
  577. {
  578.     demux_sys_t    *p_sys = p_demux->p_sys;
  579.     TaskToken      task;
  580.     vlc_bool_t      b_send_pcr = VLC_TRUE;
  581.     mtime_t         i_pcr = 0;
  582.     int             i;
  583.     for( i = 0; i < p_sys->i_track; i++ )
  584.     {
  585.         live_track_t *tk = p_sys->track[i];
  586.         if( tk->b_asf || tk->b_muxed )
  587.             b_send_pcr = VLC_FALSE;
  588.         if( i_pcr == 0 )
  589.         {
  590.             i_pcr = tk->i_pts;
  591.         }
  592.         else if( tk->i_pts != 0 && i_pcr > tk->i_pts )
  593.         {
  594.             i_pcr = tk->i_pts ;
  595.         }
  596.     }
  597.     if( i_pcr != p_sys->i_pcr && i_pcr > 0 )
  598.     {
  599.         p_sys->i_pcr = i_pcr;
  600.         if( b_send_pcr )
  601.             es_out_Control( p_demux->out, ES_OUT_SET_PCR, i_pcr );
  602.         if( p_sys->i_pcr_start <= 0 || p_sys->i_pcr_start > i_pcr ||
  603.             ( p_sys->i_length > 0 && i_pcr - p_sys->i_pcr_start > p_sys->i_length ) )
  604.         {
  605.             p_sys->i_pcr_start = i_pcr;
  606.         }
  607.     }
  608.     /* First warm we want to read data */
  609.     p_sys->event = 0;
  610.     for( i = 0; i < p_sys->i_track; i++ )
  611.     {
  612.         live_track_t *tk = p_sys->track[i];
  613.         if( tk->waiting == 0 )
  614.         {
  615.             tk->waiting = 1;
  616.             tk->readSource->getNextFrame( tk->p_buffer, tk->i_buffer,
  617.                                           StreamRead, tk,
  618.                                           StreamClose, tk );
  619.         }
  620.     }
  621.     /* Create a task that will be called if we wait more than 300ms */
  622.     task = p_sys->scheduler->scheduleDelayedTask( 300000, TaskInterrupt, p_demux );
  623.     /* Do the read */
  624.     p_sys->scheduler->doEventLoop( &p_sys->event );
  625.     /* remove the task */
  626.     p_sys->scheduler->unscheduleDelayedTask( task );
  627.     /* Check for gap in pts value */
  628.     for( i = 0; i < p_sys->i_track; i++ )
  629.     {
  630.         live_track_t *tk = p_sys->track[i];
  631.         if( !tk->b_muxed && !tk->b_rtcp_sync && tk->rtpSource->hasBeenSynchronizedUsingRTCP() )
  632.         {
  633.             msg_Dbg( p_demux, "tk->rtpSource->hasBeenSynchronizedUsingRTCP()" );
  634.             es_out_Control( p_demux->out, ES_OUT_RESET_PCR );
  635.             tk->b_rtcp_sync = VLC_TRUE;
  636.             /* reset PCR and PCR start, mmh won't work well for multi-stream I fear */
  637.             tk->i_pts = 0;
  638.             p_sys->i_pcr_start = 0;
  639.             p_sys->i_pcr = 0;
  640.             i_pcr = 0;
  641.         }
  642.     }
  643.     return p_demux->b_error ? 0 : 1;
  644. }
  645. /*****************************************************************************
  646.  * Control:
  647.  *****************************************************************************/
  648. static int Control( demux_t *p_demux, int i_query, va_list args )
  649. {
  650.     demux_sys_t *p_sys = p_demux->p_sys;
  651.     int64_t *pi64;
  652.     double  *pf, f;
  653.     vlc_bool_t *pb, b_bool;
  654.     int i;
  655.     switch( i_query )
  656.     {
  657.         case DEMUX_GET_TIME:
  658.             pi64 = (int64_t*)va_arg( args, int64_t * );
  659.             *pi64 = p_sys->i_pcr - p_sys->i_pcr_start + p_sys->i_start;
  660.             return VLC_SUCCESS;
  661.         case DEMUX_GET_LENGTH:
  662.             pi64 = (int64_t*)va_arg( args, int64_t * );
  663.             *pi64 = p_sys->i_length;
  664.             return VLC_SUCCESS;
  665.         case DEMUX_GET_POSITION:
  666.             pf = (double*)va_arg( args, double* );
  667.             if( p_sys->i_length > 0 )
  668.             {
  669.                 *pf = (double)( p_sys->i_pcr - p_sys->i_pcr_start + p_sys->i_start)/
  670.                       (double)(p_sys->i_length);
  671.             }
  672.             else
  673.             {
  674.                 *pf = 0;
  675.             }
  676.             return VLC_SUCCESS;
  677.         case DEMUX_SET_POSITION:
  678.         {
  679.             float time;
  680.             f = (double)va_arg( args, double );
  681.             time = f * (double)p_sys->i_length / 1000000.0;   /* in second */
  682.             if( p_sys->rtsp && p_sys->i_length > 0 )
  683.             {
  684.                 MediaSubsessionIterator *iter = new MediaSubsessionIterator( *p_sys->ms );
  685.                 MediaSubsession         *sub;
  686.                 int i;
  687.                 while( ( sub = iter->next() ) != NULL )
  688.                 {
  689.                     p_sys->rtsp->playMediaSubsession( *sub, time );
  690.                 }
  691.                 delete iter;
  692.                 p_sys->i_start = (mtime_t)(f * (double)p_sys->i_length);
  693.                 p_sys->i_pcr_start = 0;
  694.                 p_sys->i_pcr       = 0;
  695.                 
  696.                 for( i = 0; i < p_sys->i_track; i++ )
  697.                 {
  698.                     p_sys->track[i]->i_pts = 0;
  699.                 }
  700.                 return VLC_SUCCESS;
  701.             }
  702.             return VLC_SUCCESS;
  703.         }
  704.         /* Special for access_demux */
  705.         case DEMUX_CAN_PAUSE:
  706.             pb = (vlc_bool_t*)va_arg( args, vlc_bool_t * );
  707.             if( p_sys->rtsp && p_sys->i_length )
  708.                 *pb = VLC_TRUE; /* Not always true, but will be handled in SET_PAUSE_STATE */
  709.             else
  710.                 *pb = VLC_FALSE;
  711.             return VLC_SUCCESS;
  712.         case DEMUX_CAN_CONTROL_PACE:
  713.             pb = (vlc_bool_t*)va_arg( args, vlc_bool_t * );
  714.             *pb = VLC_FALSE;
  715.             return VLC_SUCCESS;
  716.         case DEMUX_SET_PAUSE_STATE:
  717.             double d_npt;
  718.             MediaSubsessionIterator *iter;
  719.             MediaSubsession *sub;
  720.             d_npt = ( (double)( p_sys->i_pcr - p_sys->i_pcr_start + p_sys->i_start ) ) / 1000000.00;
  721.             b_bool = (vlc_bool_t)va_arg( args, vlc_bool_t );
  722.             if( p_sys->rtsp == NULL )
  723.                 return VLC_EGENERIC;
  724.             iter = new MediaSubsessionIterator( *p_sys->ms );
  725.             while( ( sub = iter->next() ) != NULL )
  726.             {
  727.                 if( ( b_bool && !p_sys->rtsp->pauseMediaSubsession( *sub ) ) ||
  728.                     ( !b_bool && !p_sys->rtsp->playMediaSubsession( *sub, d_npt > 0 ? d_npt : -1 ) ) )
  729.                 {
  730.                     delete iter;
  731.                     return VLC_EGENERIC;
  732.                 }
  733.             }
  734.             delete iter;
  735. #if 0
  736.             /* reset PCR and PCR start, mmh won't work well for multi-stream I fear */
  737.             for( i = 0; i < p_sys->i_track; i++ )
  738.             {
  739.                 p_sys->track[i]->i_pts = 0;
  740.             }
  741.             p_sys->i_pcr_start = 0; /* FIXME Wrong */
  742.             p_sys->i_pcr = 0;
  743. #endif
  744.             return VLC_SUCCESS;
  745.         case DEMUX_GET_TITLE_INFO:
  746.         case DEMUX_SET_TITLE:
  747.         case DEMUX_SET_SEEKPOINT:
  748.             return VLC_EGENERIC;
  749.         case DEMUX_GET_PTS_DELAY:
  750.             pi64 = (int64_t*)va_arg( args, int64_t * );
  751.             *pi64 = (int64_t)var_GetInteger( p_demux, "rtsp-caching" ) * I64C(1000);
  752.             return VLC_SUCCESS;
  753.         default:
  754.             return VLC_EGENERIC;
  755.     }
  756. }
  757. /*****************************************************************************
  758.  *
  759.  *****************************************************************************/
  760. static void StreamRead( void *p_private, unsigned int i_size, unsigned int i_truncated_bytes, struct timeval pts, unsigned int duration )
  761. {
  762.     live_track_t   *tk = (live_track_t*)p_private;
  763.     demux_t        *p_demux = tk->p_demux;
  764.     demux_sys_t    *p_sys = p_demux->p_sys;
  765.     block_t        *p_block;
  766.     mtime_t i_pts = (uint64_t)pts.tv_sec * UI64C(1000000) + (uint64_t)pts.tv_usec;
  767.     /* XXX Beurk beurk beurk Avoid having negative value XXX */
  768.     i_pts &= UI64C(0x00ffffffffffffff);
  769.     if( tk->b_quicktime && tk->p_es == NULL )
  770.     {
  771.         QuickTimeGenericRTPSource *qtRTPSource = (QuickTimeGenericRTPSource*)tk->rtpSource;
  772.         QuickTimeGenericRTPSource::QTState &qtState = qtRTPSource->qtState;
  773.         uint8_t *sdAtom = (uint8_t*)&qtState.sdAtom[4];
  774.         if( qtState.sdAtomSize < 16 + 32 )
  775.         {
  776.             /* invalid */
  777.             p_sys->event = 0xff;
  778.             tk->waiting = 0;
  779.             return;
  780.         }
  781.         tk->fmt.i_codec = VLC_FOURCC( sdAtom[0], sdAtom[1], sdAtom[2], sdAtom[3] );
  782.         tk->fmt.video.i_width  = (sdAtom[28] << 8) | sdAtom[29];
  783.         tk->fmt.video.i_height = (sdAtom[30] << 8) | sdAtom[31];
  784.         tk->fmt.i_extra        = qtState.sdAtomSize - 16;
  785.         tk->fmt.p_extra        = malloc( tk->fmt.i_extra );
  786.         memcpy( tk->fmt.p_extra, &sdAtom[12], tk->fmt.i_extra );
  787.         tk->p_es = es_out_Add( p_demux->out, &tk->fmt );
  788.     }
  789. #if 0
  790.     fprintf( stderr, "StreamRead size=%d pts=%lldn",
  791.              i_size,
  792.              pts.tv_sec * 1000000LL + pts.tv_usec );
  793. #endif
  794.     /* grow buffer if it looks like buffer is too small, but don't eat
  795.      * up all the memory on strange streams */
  796.     if( i_truncated_bytes > 0 && tk->i_buffer < 2000000 )
  797.     {
  798.         void *p_tmp;
  799.         msg_Dbg( p_demux, "lost %d bytes", i_truncated_bytes );
  800.         msg_Dbg( p_demux, "increasing buffer size to %d", tk->i_buffer * 2 );
  801.         tk->i_buffer *= 2;
  802.         p_tmp = realloc( tk->p_buffer, tk->i_buffer );
  803.         if (p_tmp == NULL)
  804.         {
  805.             msg_Warn( p_demux, "realloc failed" );
  806.         }
  807.         else
  808.         {
  809.             tk->p_buffer = (uint8_t*)p_tmp;
  810.         }
  811.     }
  812.     if( i_size > tk->i_buffer )
  813.     {
  814.         msg_Warn( p_demux, "buffer overflow" );
  815.     }
  816.     /* FIXME could i_size be > buffer size ? */
  817.     if( tk->fmt.i_codec == VLC_FOURCC('h','2','6','1') )
  818.     {
  819. #if LIVEMEDIA_LIBRARY_VERSION_INT >= 1081468800
  820.         H261VideoRTPSource *h261Source = (H261VideoRTPSource*)tk->rtpSource;
  821.         uint32_t header = h261Source->lastSpecialHeader();
  822. #else
  823.         uint32_t header = 0;
  824.         msg_Warn( p_demux, "need livemedia library >= "2004.04.09"" );
  825. #endif
  826.         p_block = block_New( p_demux, i_size + 4 );
  827.         memcpy( p_block->p_buffer, &header, 4 );
  828.         memcpy( p_block->p_buffer + 4, tk->p_buffer, i_size );
  829.     }
  830.     else if( tk->b_asf )
  831.     {
  832.         int i_copy = __MIN( p_sys->asfh.i_min_data_packet_size, i_size );
  833.         p_block = block_New( p_demux, p_sys->asfh.i_min_data_packet_size );
  834.         memcpy( p_block->p_buffer, tk->p_buffer, i_copy );
  835.     }
  836.     else
  837.     {
  838.         p_block = block_New( p_demux, i_size );
  839.         memcpy( p_block->p_buffer, tk->p_buffer, i_size );
  840.     }
  841.     if( tk->fmt.i_codec == VLC_FOURCC('h','2','6','1') &&
  842.         tk->rtpSource->curPacketMarkerBit() )
  843.     {
  844.         p_block->i_flags |= BLOCK_FLAG_END_OF_FRAME;
  845.     }
  846.     //p_block->i_rate = p_input->stream.control.i_rate;
  847.     if( i_pts != tk->i_pts && !tk->b_muxed )
  848.     {
  849.         p_block->i_dts = i_pts;
  850.         p_block->i_pts = i_pts;
  851.     }
  852.     //fprintf( stderr, "tk -> dpts=%lldn", i_pts - tk->i_pts );
  853.     if( tk->b_muxed )
  854.     {
  855.         stream_DemuxSend( tk->p_out_muxed, p_block );
  856.     }
  857.     else if( tk->b_asf )
  858.     {
  859.         stream_DemuxSend( p_sys->p_out_asf, p_block );
  860.     }
  861.     else
  862.     {
  863.         es_out_Send( p_demux->out, tk->p_es, p_block );
  864.     }
  865.     /* warm that's ok */
  866.     p_sys->event = 0xff;
  867.     /* we have read data */
  868.     tk->waiting = 0;
  869.     if( i_pts > 0 && !tk->b_muxed )
  870.     {
  871.         tk->i_pts = i_pts;
  872.     }
  873. }
  874. /*****************************************************************************
  875.  *
  876.  *****************************************************************************/
  877. static void StreamClose( void *p_private )
  878. {
  879.     live_track_t   *tk = (live_track_t*)p_private;
  880.     demux_t        *p_demux = tk->p_demux;
  881.     demux_sys_t    *p_sys = p_demux->p_sys;
  882.     fprintf( stderr, "StreamClosen" );
  883.     p_sys->event = 0xff;
  884.     p_demux->b_error = VLC_TRUE;
  885. }
  886. /*****************************************************************************
  887.  *
  888.  *****************************************************************************/
  889. static void TaskInterrupt( void *p_private )
  890. {
  891.     demux_t *p_demux = (demux_t*)p_private;
  892.     fprintf( stderr, "TaskInterruptn" );
  893.     /* Avoid lock */
  894.     p_demux->p_sys->event = 0xff;
  895. }
  896. /*****************************************************************************
  897.  *
  898.  *****************************************************************************/
  899. static int b64_decode( char *dest, char *src );
  900. static int ParseASF( demux_t *p_demux )
  901. {
  902.     demux_sys_t    *p_sys = p_demux->p_sys;
  903.     const char *psz_marker = "a=pgmpu:data:application/vnd.ms.wms-hdr.asfv1;base64,";
  904.     char *psz_asf = strcasestr( p_sys->p_sdp, psz_marker );
  905.     char *psz_end;
  906.     block_t *p_header;
  907.     /* Parse the asf header */
  908.     if( psz_asf == NULL )
  909.         return VLC_EGENERIC;
  910.     psz_asf += strlen( psz_marker );
  911.     psz_asf = strdup( psz_asf );    /* Duplicate it */
  912.     psz_end = strchr( psz_asf, 'n' );
  913.     while( psz_end > psz_asf && ( *psz_end == 'n' || *psz_end == 'r' ) )
  914.         *psz_end-- = '';
  915.     if( psz_asf >= psz_end )
  916.     {
  917.         free( psz_asf );
  918.         return VLC_EGENERIC;
  919.     }
  920.     /* Always smaller */
  921.     p_header = block_New( p_demux, psz_end - psz_asf );
  922.     p_header->i_buffer = b64_decode( (char*)p_header->p_buffer, psz_asf );
  923.     fprintf( stderr, "Size=%d Hdrb64=%sn", p_header->i_buffer, psz_asf );
  924.     if( p_header->i_buffer <= 0 )
  925.     {
  926.         free( psz_asf );
  927.         return VLC_EGENERIC;
  928.     }
  929.     /* Parse it to get packet size */
  930.     E_(asf_HeaderParse)( &p_sys->asfh, p_header->p_buffer, p_header->i_buffer );
  931.     /* Send it to demuxer */
  932.     stream_DemuxSend( p_sys->p_out_asf, p_header );
  933.     free( psz_asf );
  934.     return VLC_SUCCESS;
  935. }
  936. /*char b64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";*/
  937. static int b64_decode( char *dest, char *src )
  938. {
  939.     const char *dest_start = dest;
  940.     int  i_level;
  941.     int  last = 0;
  942.     int  b64[256] = {
  943.         -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,  /* 00-0F */
  944.         -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,  /* 10-1F */
  945.         -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,-1,-1,-1,63,  /* 20-2F */
  946.         52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-1,-1,-1,  /* 30-3F */
  947.         -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,  /* 40-4F */
  948.         15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,  /* 50-5F */
  949.         -1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,  /* 60-6F */
  950.         41,42,43,44,45,46,47,48,49,50,51,-1,-1,-1,-1,-1,  /* 70-7F */
  951.         -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,  /* 80-8F */
  952.         -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,  /* 90-9F */
  953.         -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,  /* A0-AF */
  954.         -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,  /* B0-BF */
  955.         -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,  /* C0-CF */
  956.         -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,  /* D0-DF */
  957.         -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,  /* E0-EF */
  958.         -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1   /* F0-FF */
  959.         };
  960.     for( i_level = 0; *src != ''; src++ )
  961.     {
  962.         int  c;
  963.         c = b64[(unsigned int)*src];
  964.         if( c == -1 )
  965.         {
  966.             continue;
  967.         }
  968.         switch( i_level )
  969.         {
  970.             case 0:
  971.                 i_level++;
  972.                 break;
  973.             case 1:
  974.                 *dest++ = ( last << 2 ) | ( ( c >> 4)&0x03 );
  975.                 i_level++;
  976.                 break;
  977.             case 2:
  978.                 *dest++ = ( ( last << 4 )&0xf0 ) | ( ( c >> 2 )&0x0f );
  979.                 i_level++;
  980.                 break;
  981.             case 3:
  982.                 *dest++ = ( ( last &0x03 ) << 6 ) | c;
  983.                 i_level = 0;
  984.         }
  985.         last = c;
  986.     }
  987.     *dest = '';
  988.     return dest - dest_start;
  989. }