RtspFileAu.cxx
上传用户:sy_wanhua
上传日期:2013-07-25
资源大小:3048k
文件大小:9k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

C/C++

  1. /* ====================================================================
  2.  * The Vovida Software License, Version 1.0 
  3.  * 
  4.  * Copyright (c) 2000 Vovida Networks, Inc.  All rights reserved.
  5.  * 
  6.  * Redistribution and use in source and binary forms, with or without
  7.  * modification, are permitted provided that the following conditions
  8.  * are met:
  9.  * 
  10.  * 1. Redistributions of source code must retain the above copyright
  11.  *    notice, this list of conditions and the following disclaimer.
  12.  * 
  13.  * 2. Redistributions in binary form must reproduce the above copyright
  14.  *    notice, this list of conditions and the following disclaimer in
  15.  *    the documentation and/or other materials provided with the
  16.  *    distribution.
  17.  * 
  18.  * 3. The names "VOCAL", "Vovida Open Communication Application Library",
  19.  *    and "Vovida Open Communication Application Library (VOCAL)" must
  20.  *    not be used to endorse or promote products derived from this
  21.  *    software without prior written permission. For written
  22.  *    permission, please contact vocal@vovida.org.
  23.  *
  24.  * 4. Products derived from this software may not be called "VOCAL", nor
  25.  *    may "VOCAL" appear in their name, without prior written
  26.  *    permission of Vovida Networks, Inc.
  27.  * 
  28.  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
  29.  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  30.  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
  31.  * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
  32.  * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
  33.  * IN EXCESS OF 281421,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
  34.  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  35.  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  36.  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  37.  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  38.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
  39.  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  40.  * DAMAGE.
  41.  * 
  42.  * ====================================================================
  43.  * 
  44.  * This software consists of voluntary contributions made by Vovida
  45.  * Networks, Inc. and many individuals on behalf of Vovida Networks,
  46.  * Inc.  For more information on Vovida Networks, Inc., please see
  47.  * <http://www.vovida.org/>.
  48.  *
  49.  */
  50. static const char* const RtspFileAu_cxx_version =
  51.     "$Id: RtspFileAu.cxx,v 1.22 2001/05/15 20:26:08 bko Exp $";
  52. #include "RtspFileAu.hxx"
  53. #include "RtpFileTypes.hxx"
  54. RtspFileAu::RtspFileAu( const string& shortFilename )
  55.     : RtspFile( shortFilename ),
  56.       m_xAudioFile( 0 )
  57. {
  58.     myFileMode = RTSP_FILE_MODE_UNKNOWN;
  59. }
  60. RtspFileAu::~RtspFileAu()
  61. {
  62.     close();
  63. }
  64. bool
  65. RtspFileAu::saveHeader( const int ftIndex, RtspSdp& rtspSdp )
  66. {
  67.     // check filemap contains full codec information
  68.     if( rtpFileTypeInfo[ftIndex].AuFileFormat == 0x0000 )
  69.     {
  70.         cpLog( LOG_ERR, "Incomplete rtpFileTypeInfo map for codec %s",
  71.                rtpFileTypeInfo[ftIndex].name.c_str() );
  72.         return false;
  73.     }
  74.     mySfInfo.format = SF_FORMAT_AU | SF_FORCE_OPEN;
  75.     mySfInfo.format_tag = rtpFileTypeInfo[ftIndex].AuFileFormat;
  76.     mySfInfo.samplerate = 8000;
  77.     mySfInfo.channels = 1;
  78.     mySfInfo.pcmbitwidth = 16;
  79.     mySfInfo.samples = 0;
  80.     mySfInfo.sections = 1;
  81.     mySfInfo.seekable = 1;
  82.     mySfInfo.bytewidth = rtpFileTypeInfo[ftIndex].bytewidth;
  83.     // save sf_info to file
  84.     SNDFILE* xAudioFile = sf_open_write( localFilename().getData(), &mySfInfo );
  85.     if( !xAudioFile )
  86.     {
  87.         cpLog( LOG_DEBUG, "sf_open_write %s - failed while saving header",
  88.                localFilename().getData() );
  89.         return false;
  90.     }
  91.     dummyWrite( xAudioFile, rtpFileTypeInfo[ftIndex].packetSize );
  92.     if( cpLogGetPriority() >= LOG_DEBUG )
  93.     {
  94.         printSfInfo();
  95.     }
  96.     // close audio file
  97.     sf_close( xAudioFile );
  98.     return true;
  99. }
  100. bool
  101. RtspFileAu::loadHeader( int* ftIndex, int* lengthInMs  )
  102. {
  103.     *ftIndex = 0;
  104.     *lengthInMs = 0;
  105.     // read sf_info from file
  106.     memset( &mySfInfo, 0, sizeof( mySfInfo ) );
  107.     mySfInfo.format = SF_FORCE_OPEN;
  108.     SNDFILE* xAudioFile = sf_open_read( localFilename().getData(), &mySfInfo );
  109.     if( !xAudioFile )
  110.     {
  111.         char errbuff[80];
  112.         sf_error_str( xAudioFile, errbuff, 80 );
  113.         cpLog( LOG_ERR, "sf_open_read %s - failed: %s ",
  114.                localFilename().getData(), errbuff );
  115.         return false;
  116.     }
  117.     if( ( mySfInfo.format & SF_FORMAT_TYPEMASK ) != SF_FORMAT_AU )
  118.     {
  119.         cpLog( LOG_ERR, "Audio file header doesn't match file extension" );
  120.         sf_close( xAudioFile );
  121.         return false;
  122.     }
  123.     
  124.     // read codec number from sf_info
  125.     *ftIndex = 0;
  126.     for( int i = 0; i< myNumberOfCodecs; i++ )
  127.     {
  128.         if( rtpFileTypeInfo[i].AuFileFormat == mySfInfo.format_tag )
  129.         {
  130.             *ftIndex = i;
  131.             cpLog( LOG_DEBUG, "Read index %d from audio map", i );
  132.             break;
  133.         }
  134.     }
  135.     if( *ftIndex == 0 )
  136.     {
  137.         cpLog( LOG_DEBUG, "Au codec %d not known", mySfInfo.format_tag );
  138.         sf_close( xAudioFile );
  139.         return false;
  140.     }
  141.     //dirty hack of libsndfile
  142.     cpLog( LOG_DEBUG, "Filling incomplete SF_INFO structure" );
  143.     mySfInfo.pcmbitwidth = 16;
  144.     mySfInfo.bytewidth = rtpFileTypeInfo[*ftIndex].bytewidth;
  145.     sf_set_bytewidth( xAudioFile, &mySfInfo );
  146.     sf_close( xAudioFile );
  147.     if( cpLogGetPriority() >= LOG_DEBUG )
  148.     {
  149.         printSfInfo();
  150.     }
  151.     // calculate file length
  152.     if( rtpFileTypeInfo[*ftIndex].bytewidth > 2 )
  153.     {
  154.         *lengthInMs = int( mySfInfo.samples *
  155.                            rtpFileTypeInfo[*ftIndex].intervalMs );
  156.     }
  157.     else
  158.     {
  159.         *lengthInMs = int( mySfInfo.samples /
  160.                            ( (float)rtpFileTypeInfo[*ftIndex].packetSize /
  161.                              (float)rtpFileTypeInfo[*ftIndex].intervalMs ) );
  162.     }
  163.     cpLog( LOG_DEBUG, "File length is %d ms", *lengthInMs );
  164.     return true;
  165. }
  166. bool
  167. RtspFileAu::open( bool bReadWrite, int ftIndex )
  168. {
  169.     if( !bReadWrite ) // read mode
  170.     {
  171.         m_xAudioFile = sf_open_read( localFilename().getData(), &mySfInfo );
  172.         if( !m_xAudioFile )
  173.         {
  174.             cpLog( LOG_ERR, "sf_open_read %s - failed",
  175.                    localFilename().getData() );
  176.             return false;
  177.         }
  178.         //dirty hack of libsndfile
  179.         cpLog( LOG_ERR, "Filling incomplete SF_INFO structure" );
  180.         mySfInfo.pcmbitwidth = 16;
  181.         mySfInfo.bytewidth = rtpFileTypeInfo[ftIndex].bytewidth;
  182.         sf_set_bytewidth( m_xAudioFile, &mySfInfo );
  183.         myFileMode = RTSP_FILE_MODE_PLAY;
  184.     }
  185.     else // write mode
  186.     {
  187.         mySfInfo.format = SF_FORMAT_AU | SF_FORCE_OPEN;
  188.         mySfInfo.bytewidth = rtpFileTypeInfo[ftIndex].bytewidth;
  189.         m_xAudioFile = sf_open_write( localFilename().getData(), &mySfInfo );
  190.         if( !m_xAudioFile )
  191.         {
  192.             cpLog( LOG_ERR, "sf_open_write %s - failed",
  193.                    localFilename().getData() );
  194.             return false;
  195.         }
  196.         dummyWrite( m_xAudioFile, rtpFileTypeInfo[ftIndex].packetSize );
  197.         myFileMode = RTSP_FILE_MODE_REC;
  198.     }
  199.     return true;
  200. }
  201. bool
  202. RtspFileAu::close()
  203. {
  204.     if( m_xAudioFile )
  205.     {
  206.         if( sf_close( m_xAudioFile ) != 0 )
  207.         {
  208.             cpLog( LOG_ERR, "Error in sf_close()" );
  209.         }
  210.         m_xAudioFile = 0;
  211.         updateSdpFileRange();
  212.         return true;
  213.     }
  214.     return false;
  215. }
  216. int
  217. RtspFileAu::read( void* data, int max, 
  218.                   unsigned short* pSeqNum, unsigned int* pTS )
  219. {
  220.     return sf_read_raw( m_xAudioFile, data, max );
  221. }
  222. int
  223. RtspFileAu::write( void* data, int max, 
  224.                    unsigned short uSeqNum, unsigned int uTS )
  225. {
  226.     return sf_write_raw( m_xAudioFile, data, max );
  227. }
  228. long
  229. RtspFileAu::seek( const long samples, const int whence )
  230. {
  231.     return sf_seek( m_xAudioFile, samples, whence );
  232. }
  233. void
  234. RtspFileAu::printSfInfo() const
  235. {
  236.     printf( "    Sample Rate : %dn",   mySfInfo.samplerate );
  237.     printf( "    Samples     : %dn",   mySfInfo.samples );
  238.     printf( "    Channels    : %dn",   mySfInfo.channels );
  239.     printf( "    Bit Width   : %dn",   mySfInfo.pcmbitwidth );
  240.     printf( "    Format      : 0x%xn", mySfInfo.format );
  241.     printf( "    Format_tag* : 0x%xn", mySfInfo.format_tag );
  242.     printf( "    Bytewidth*  : %dn",   mySfInfo.bytewidth );
  243.     printf( "    Sections    : %dn",   mySfInfo.sections );
  244.     printf( "    Seekable    : %dn",   mySfInfo.seekable );
  245. }
  246. void
  247. RtspFileAu::dummyWrite( SNDFILE* xAudioFile, const int dummyLen )
  248. {
  249.     // write some dummy data
  250.     cpLog( LOG_DEBUG, "Writing %d bytes of dummy data", dummyLen );
  251.     char dummyBuffer[dummyLen];
  252.     memset( dummyBuffer, 0, dummyLen );
  253.     if( (int)sf_write_raw( xAudioFile, dummyBuffer, dummyLen ) != dummyLen )
  254.     {
  255.         cpLog( LOG_DEBUG, "sf_write_raw result error %d", dummyLen );
  256.     }
  257. }
  258. /* Local Variables: */
  259. /* c-file-style: "stroustrup" */
  260. /* indent-tabs-mode: nil */
  261. /* c-file-offsets: ((access-label . -) (inclass . ++)) */
  262. /* c-basic-offset: 4 */
  263. /* End: */