mp4a-mux-cfg.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:10k
源码类别:

Symbian

开发平台:

C/C++

  1. /* ***** BEGIN LICENSE BLOCK ***** 
  2.  * Version: RCSL 1.0/RPSL 1.0 
  3.  *  
  4.  * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
  5.  *      
  6.  * The contents of this file, and the files included with this file, are 
  7.  * subject to the current version of the RealNetworks Public Source License 
  8.  * Version 1.0 (the "RPSL") available at 
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed 
  10.  * the file under the RealNetworks Community Source License Version 1.0 
  11.  * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
  12.  * in which case the RCSL will apply. You may also obtain the license terms 
  13.  * directly from RealNetworks.  You may not use this file except in 
  14.  * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
  15.  * applicable to this file, the RCSL.  Please see the applicable RPSL or 
  16.  * RCSL for the rights, obligations and limitations governing use of the 
  17.  * contents of the file.  
  18.  *  
  19.  * This file is part of the Helix DNA Technology. RealNetworks is the 
  20.  * developer of the Original Code and owns the copyrights in the portions 
  21.  * it created. 
  22.  *  
  23.  * This file, and the files included with this file, is distributed and made 
  24.  * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  25.  * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  26.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
  27.  * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  28.  * 
  29.  * Technology Compatibility Kit Test Suite(s) Location: 
  30.  *    http://www.helixcommunity.org/content/tck 
  31.  * 
  32.  * Contributor(s): 
  33.  *  
  34.  * ***** END LICENSE BLOCK ***** */ 
  35. #include "hlxclib/string.h"
  36. #include "mp4a-mux-cfg.h"
  37. #include "bitstream.h"
  38. MP4AAudioSpec::MP4AAudioSpec() :
  39.     m_pConfig(0),
  40.     m_ulConfigSize(0)
  41. {}
  42. MP4AAudioSpec::MP4AAudioSpec(const MP4AAudioSpec& rhs) :
  43.     m_pConfig(0),
  44.     m_ulConfigSize(rhs.m_ulConfigSize)
  45. {
  46.     if (m_ulConfigSize)
  47.     {
  48. m_pConfig = new UINT8[m_ulConfigSize];
  49. ::memcpy(m_pConfig, rhs.m_pConfig, m_ulConfigSize);
  50.     }
  51. }
  52. MP4AAudioSpec::~MP4AAudioSpec()
  53. {
  54.     delete [] m_pConfig;
  55.     m_pConfig = 0;
  56. }
  57. MP4AAudioSpec& MP4AAudioSpec::operator=(const MP4AAudioSpec& rhs)
  58. {
  59.     if (&rhs != this)
  60.     {
  61. delete [] m_pConfig;
  62. m_pConfig = 0;
  63. m_ulConfigSize = rhs.m_ulConfigSize;
  64. if (m_ulConfigSize)
  65. {
  66.     m_pConfig = new UINT8[m_ulConfigSize];
  67.     ::memcpy(m_pConfig, rhs.m_pConfig, m_ulConfigSize); /* Flawfinder: ignore */
  68. }
  69.     }
  70.     return *this;
  71. }
  72. BOOL MP4AAudioSpec::Unpack(Bitstream& bs)
  73. {
  74.     BOOL ret = FALSE;
  75.     
  76.     ULONG32 config = bs.PeekBits(16);
  77.     ULONG32 objectType = config >> 11;
  78.     ULONG32 sampFreq = (config >> 7) & 0xf;
  79.     ULONG32 channelCfg = (config >> 3) & 0xf;
  80.     if (((objectType >= 1) && (objectType < 5) ||
  81.  (objectType >= 6) && (objectType < 8)) &&
  82. (sampFreq != 0xf) &&
  83. (channelCfg != 0))
  84.     {
  85. ULONG32 ulConfigBits = 16;
  86. delete [] m_pConfig;
  87. m_ulConfigSize = (ulConfigBits + 7) >> 3;
  88. m_pConfig = new UINT8 [m_ulConfigSize];
  89. bs.GetBits(ulConfigBits, m_pConfig);
  90. ret = TRUE;
  91.     }
  92.     
  93.     return ret;
  94. }
  95. MP4AStreamInfo::MP4AStreamInfo() :
  96.     m_ulProgram(0),
  97.     m_ulLayer(0),
  98.     m_ulLengthType(0),
  99.     m_ulBlockDelay(0),
  100.     m_bFracDelayPresent(0),
  101.     m_ulFracDelay(0),
  102.     m_ulFrameLength(0),
  103.     m_ulCELPIndex(0),
  104.     m_ulHVXCIndex(0)
  105. {}
  106. MP4AMuxConfig::MP4AMuxConfig() :
  107.     m_bAllSameTiming(FALSE),
  108.     m_ulNumSubFrames(0),
  109.     m_ulNumPrograms(0),
  110.     m_pLayerCounts(0),
  111.     m_ppStreamLookup(0),
  112.     m_ulNumStreams(0),
  113.     m_pStreamInfo(0)
  114. {}
  115. MP4AMuxConfig::~MP4AMuxConfig()
  116. {
  117.     Reset();
  118. }
  119. BOOL MP4AMuxConfig::Unpack(Bitstream& bs)
  120. {
  121.     BOOL failed = FALSE;
  122.     Reset();
  123. #if 1
  124.     // This updates StreamMuxConfig to ISO/IEC draft 14496-3:2001
  125.     ULONG32 ulAudioMuxVersion = bs.GetBits(1); // audioMuxVersion
  126.     if (ulAudioMuxVersion == 0)
  127.     {
  128.         ULONG32 ulStreamCount = 0;
  129.         m_bAllSameTiming = (bs.GetBits(1) ? TRUE : FALSE);
  130.         m_ulNumSubFrames = bs.GetBits(6) + 1; // 0-based (old version was not)
  131.         m_ulNumPrograms  = bs.GetBits(4) + 1; // 0-based (old version was not)
  132.         // Allocate arrays
  133.         m_pLayerCounts   = new ULONG32[m_ulNumPrograms];
  134.         m_ppStreamLookup = new ULONG32*[m_ulNumPrograms];
  135.         if (m_pLayerCounts && m_ppStreamLookup)
  136.         {
  137.             // Null out arrays
  138.             ULONG32 ulProg = 0;
  139.             for (ulProg = 0; ulProg < m_ulNumPrograms; ulProg++)
  140.             {
  141.         m_pLayerCounts[ulProg]   = 0;
  142.         m_ppStreamLookup[ulProg] = 0;
  143.             }
  144.             // Parse programs
  145.             for (ulProg = 0; !failed && ulProg < m_ulNumPrograms; ulProg++)
  146.             {
  147.                 // Get the number of layers
  148.                 ULONG32 ulNumLayers = bs.GetBits(3) + 1; // 0-based (old version was not)
  149.                 // Allocate stream lookup array
  150.         MP4AAudioSpec as;
  151.         m_pLayerCounts[ulProg]   = ulNumLayers;
  152.         m_ppStreamLookup[ulProg] = new ULONG32[ulNumLayers];
  153.                 if (m_ppStreamLookup[ulProg])
  154.                 {
  155.                     for (ULONG32 ulLay = 0; ulLay < ulNumLayers; ulLay++)
  156.                     {
  157.                 BOOL readAudioSpec = TRUE;
  158.                 MP4AStreamInfo streamInfo;
  159.                 m_ppStreamLookup[ulProg][ulLay] = m_ulNumStreams;
  160.                 streamInfo.SetProgram(ulProg);
  161.                 streamInfo.SetLayer(ulLay);
  162.                         if (((ulProg != 0) || (ulLay != 0)) &&
  163.                             (bs.GetBits(1) != 0))
  164.                             readAudioSpec = FALSE;
  165.                 if (readAudioSpec)
  166.                 {
  167.             if (!as.Unpack(bs))
  168.             {
  169.                 failed = TRUE;
  170.                 break;
  171.             }
  172.                 }
  173.                 streamInfo.SetAudioSpec(as);
  174.                 streamInfo.SetLengthType(bs.GetBits(3));
  175.                 switch (streamInfo.GetLengthType())
  176.                         {
  177.                             case 0:
  178.                                 bs.GetBits(8); // Buffer fullness
  179.                                 if (!m_bAllSameTiming)
  180.                                 {
  181.                                     // Get Core Frame offset
  182.                                     // XXXMEH - We always hint such that m_bAllSameTiming == TRUE,
  183.                                     // so for now we won't worry about this
  184.                                 }
  185.                 break;
  186.                             case 1:
  187.                                 streamInfo.SetFrameLength(bs.GetBits(9));
  188.                                 break;
  189.                             case 3:
  190.                             case 4:
  191.                             case 5:
  192.                                 streamInfo.SetCELPIndex(bs.GetBits(6));
  193.                                 break;
  194.                             case 6 :
  195.                             case 7 :
  196.                                 streamInfo.SetHVXCIndex(bs.GetBits(1));
  197.                                 break;
  198.                 };
  199.                         AddStream(streamInfo);
  200.                     }
  201.                 }
  202.                 else
  203.                 {
  204.                     failed = TRUE;
  205.                 }
  206.             }
  207.             // Other data present
  208.             if (bs.GetBits(1))
  209.             {
  210.                 UINT8 otherDataLenTemp = 0;
  211.                 UINT32 otherDataLenBits = 0;
  212.                 UINT8 otherDataLenEsc  = 0;
  213.                 do {
  214.                     otherDataLenBits *= 256;
  215.                     otherDataLenEsc = (UINT8)bs.GetBits(1);
  216.                     otherDataLenTemp = (UINT8)bs.GetBits(8);
  217.                     otherDataLenBits += otherDataLenTemp;
  218.                 } while (otherDataLenEsc);
  219.             }
  220.             // Crc present
  221.             if (bs.GetBits(1))
  222.             {
  223.                 bs.GetBits(8);
  224.             }
  225.         }
  226.         else
  227.         {
  228.             failed = TRUE;
  229.         }
  230.     }
  231. #else
  232.     if (bs.GetBits(1))
  233. m_bAllSameTiming = TRUE;
  234.     m_ulNumSubFrames = bs.GetBits(3);
  235.     
  236.     m_ulNumPrograms = bs.GetBits(4);
  237.     m_pLayerCounts = new ULONG32[m_ulNumPrograms];
  238.     m_ppStreamLookup = new ULONG32*[m_ulNumPrograms];
  239.     for (ULONG32 i = 0; i < m_ulNumPrograms ; i++)
  240.     {
  241. m_pLayerCounts[i] = 0;
  242. m_ppStreamLookup[i] = 0;
  243.     }
  244.     for (ULONG32 prog = 0; !failed && (prog < m_ulNumPrograms) ; prog++)
  245.     {
  246. ULONG32 ulNumLayers = bs.GetBits(3);
  247. MP4AAudioSpec as;
  248. m_pLayerCounts[prog] = ulNumLayers;
  249. m_ppStreamLookup[prog] = new ULONG32[ulNumLayers];
  250. for (ULONG32 lay = 0; lay < ulNumLayers; lay++)
  251. {
  252.     BOOL readAudioSpec = TRUE;
  253.     MP4AStreamInfo streamInfo;
  254.     m_ppStreamLookup[prog][lay] = m_ulNumStreams;
  255.     streamInfo.SetProgram(prog);
  256.     streamInfo.SetLayer(lay);
  257.     if (((prog != 0) || (lay != 0)) &&
  258. (bs.GetBits(1) != 0))
  259. readAudioSpec = FALSE;
  260.     if (readAudioSpec)
  261.     {
  262. if (!as.Unpack(bs))
  263. {
  264.     failed = TRUE;
  265.     break;
  266. }
  267.     }
  268.     streamInfo.SetAudioSpec(as);
  269.     streamInfo.SetLengthType(bs.GetBits(3));
  270.     switch (streamInfo.GetLengthType()) {
  271.     case 0 :
  272. streamInfo.SetBlockDelay(bs.GetBits(5));
  273. if (bs.GetBits(1))
  274. {
  275.     streamInfo.SetFracDelayPresent(TRUE);
  276.     streamInfo.SetFracDelay(bs.GetBits(8));
  277. }
  278. break;
  279.     case 1 :
  280. streamInfo.SetFrameLength(bs.GetBits(9));
  281. break;
  282.     case 3 :
  283.     case 4 :
  284.     case 5 :
  285. streamInfo.SetCELPIndex(bs.GetBits(6));
  286. break;
  287.     case 6 :
  288.     case 7 :
  289. streamInfo.SetHVXCIndex(bs.GetBits(1));
  290. break;
  291.     };
  292.     AddStream(streamInfo);
  293. }
  294.     }
  295. #endif
  296.     return !failed;
  297. }
  298. void MP4AMuxConfig::Reset()
  299. {
  300.     delete [] m_pLayerCounts;
  301.     m_pLayerCounts = 0;
  302.     m_ulNumStreams = 0;
  303.     if (m_ppStreamLookup)
  304.     {
  305. for (ULONG32 i = 0; i < m_ulNumPrograms; i++)
  306. {
  307.     delete [] m_ppStreamLookup[i];
  308.     m_ppStreamLookup[i] = 0;
  309. }
  310. delete [] m_ppStreamLookup;
  311. m_ppStreamLookup = 0;
  312.     }
  313.     delete [] m_pStreamInfo;
  314.     m_pStreamInfo = 0;
  315. }
  316. void MP4AMuxConfig::AddStream(const MP4AStreamInfo& info)
  317. {
  318.     MP4AStreamInfo* pTmp = new MP4AStreamInfo[m_ulNumStreams + 1];
  319.     if (m_pStreamInfo)
  320.     {
  321. for (ULONG32 i = 0; i < m_ulNumStreams; i++)
  322. {
  323.     pTmp[i] = m_pStreamInfo[i];
  324. }
  325. delete [] m_pStreamInfo;
  326.     }
  327.     
  328.     m_pStreamInfo = pTmp;
  329.     m_pStreamInfo[m_ulNumStreams] = info;
  330.     m_ulNumStreams++;
  331. }