amr-depack.cpp
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:14k
源码类别:

Symbian

开发平台:

Visual 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.  
  36. #include "hlxclib/string.h"
  37. #include "amr-depack.h"
  38. #include "amr_toc.h"
  39. #include "amr_rs_itr.h"
  40. #include "bitstream.h"
  41. AMRDepack::AMRDepack() :
  42.     m_flavor(NarrowBand),
  43.     m_ulTimestampInc(0),
  44.     m_bOctetAlign(FALSE),
  45.     m_ulModeSet(0),
  46.     m_bHasCRC(FALSE),
  47.     m_ulMaxInterleave(0),
  48.     m_ulPtime(0),
  49.     m_ulChannels(0),
  50.     m_pUserData(0),
  51.     m_pCallback(0),
  52.     m_bPacketsLost(FALSE),
  53.     m_bLastTimeValid(FALSE),
  54.     m_ulLastTimestamp(0),
  55.     m_ulIleavIndex(0),
  56.     m_ulIleavLength(0),
  57.     m_ulIleavBlockCount(0),
  58.     m_ulIleavBaseTime(0)
  59. {}
  60. AMRDepack::~AMRDepack()
  61. {}
  62. BOOL AMRDepack::Init(AMRFlavor flavor,
  63.      BOOL    bOctetAlign,
  64.      ULONG32 ulModeSet,
  65.      ULONG32 ulChangePeriod,
  66.      BOOL    bChangeNeighbor,
  67.      ULONG32 ulMaxPtime,
  68.      BOOL    bHasCRC,
  69.      BOOL    bRobustSort,
  70.      ULONG32 ulMaxInterleave,
  71.      ULONG32 ulPtime,
  72.      ULONG32 ulChannels,
  73.      OnFrameCB pFrameCB,
  74.      void* pUserData)
  75. {
  76.     BOOL ret = FALSE;
  77.     
  78.     if ((pFrameCB) &&
  79. (ulChannels < 7) &&
  80. ((flavor == NarrowBand) || (flavor == WideBand)))
  81.     {
  82. m_flavor = flavor;
  83. if (ulChannels)
  84.     m_ulChannels = ulChannels;
  85. else
  86.     m_ulChannels = 1;
  87. if (ulModeSet)
  88.     m_ulModeSet = ulModeSet;
  89. else
  90.     m_ulModeSet = 0x81ff;
  91. m_ulPtime = ulPtime;
  92. m_pCallback = pFrameCB;
  93. m_pUserData = pUserData;
  94. ULONG32 ulMaxFrameBytes = 1 + ((GetMaxFrameBits() + 7) >> 3);
  95. m_blockBuf.Init(flavor, m_ulChannels);
  96. m_ulIleavIndex = 0;
  97. m_ulIleavLength = 0;
  98. if ((bOctetAlign) ||
  99.     (bHasCRC) ||
  100.     (bRobustSort) ||
  101.     (ulMaxInterleave))
  102. {
  103.     // Octet aligned mode
  104.     
  105.     m_bOctetAlign   = TRUE;
  106.     m_bHasCRC       = bHasCRC;
  107.     m_bRobustSort   = bRobustSort;
  108.     m_ulMaxInterleave = ulMaxInterleave;
  109. }
  110. else
  111. {
  112.     m_bOctetAlign     = FALSE;
  113.     m_bHasCRC         = FALSE;
  114.     m_bRobustSort     = FALSE;
  115.     m_ulMaxInterleave = 0;
  116. }
  117. ret = TRUE;
  118.     }
  119.     return ret;
  120. }
  121. BOOL AMRDepack::Reset() // Completely reset the depacketizer state
  122. {
  123.     m_bPacketsLost = FALSE;
  124.     // Clear interleave state info
  125.     m_ulIleavIndex = 0;
  126.     m_ulIleavLength = 0;
  127.     m_ulIleavBaseTime = 0;
  128.     m_bLastTimeValid = FALSE;
  129.     m_ulLastTimestamp = 0;
  130.     return TRUE;
  131. }
  132. BOOL AMRDepack::Flush() // Indicates end of stream
  133. {
  134.     if (m_ulMaxInterleave > 0)
  135.     {
  136. DispatchBlocks(m_ulIleavBaseTime);
  137.     }
  138.     return TRUE;
  139. }
  140. BOOL AMRDepack::OnPacket(ULONG32 ulTime, 
  141.  const UINT8* pData, ULONG32 ulSize, 
  142.  BOOL bMarker)
  143. {
  144.     BOOL bFailed = FALSE;
  145.     Bitstream bs;
  146.     bs.SetBuffer(pData);
  147.     // Skip the CMR since we don't care about it
  148.     if (m_bOctetAlign)
  149.     {
  150. // 3GPP TS26.235 v5.0.0 Annex B Section B.4.4.1
  151. bs.GetBits(8);
  152.     }
  153.     else
  154.     {
  155. // 3GPP TS26.235 v5.0.0 Annex B Section B.4.3.1
  156. bs.GetBits(4);
  157.     }
  158.     if (m_ulMaxInterleave > 0)
  159.     {
  160. // 3GPP TS26.235 v5.0.0 Annex B Section B.4.4.1
  161. ULONG32 ulILL = bs.GetBits(4);
  162. ULONG32 ulILP = bs.GetBits(4);
  163. bFailed = !UpdateIleavInfo(ulILL, ulILP, ulTime);
  164.     }
  165.     
  166.     if (bFailed == FALSE)
  167.     {
  168. AMRTOCInfo tocInfo;
  169. GetTOCInfo(bs, tocInfo);
  170. if (m_bHasCRC)
  171. {
  172.     // 3GPP TS26.235 v5.0.0 Annex B Section B.4.4.2.1
  173.     SkipCRCInfo(bs, tocInfo);
  174. }
  175. // Update the block count to make sure we have
  176. // enough space in m_blockBuf for this data
  177. UpdateBlockCount(tocInfo.EntryCount() / m_ulChannels);
  178. ULONG32 ulStartBlock = 0;
  179. ULONG32 ulBlockInc = 1;
  180. // Adjust the ulStartBlock and ulBlockInc if the
  181. // data is interleaved
  182. if (m_ulMaxInterleave > 0)
  183. {
  184.     ulStartBlock = m_ulIleavIndex;
  185.     ulBlockInc = m_ulIleavLength;
  186. }
  187. if (m_bRobustSort)
  188. {
  189.     // Copy robust sorted frame data to m_blockBuf
  190.     SortedCopy(bs, ulStartBlock, ulBlockInc, tocInfo);
  191. }
  192. else
  193. {
  194.     // Copy linear frame data to m_blockBuf
  195.     LinearCopy(bs, ulStartBlock, ulBlockInc, tocInfo);
  196. }
  197. if (m_ulMaxInterleave > 0)
  198. {
  199.     // We are deinterleaving.
  200.     // Increment the interleave index now
  201.     // that we are done with this packet.
  202.     m_ulIleavIndex++;
  203.     // See if we have all the packets in this
  204.     // interleave block
  205.     if (m_ulIleavIndex == m_ulIleavLength)
  206.     {
  207. // Yep. Dispatch the frame blocks
  208. DispatchBlocks(m_ulIleavBaseTime);
  209.     }
  210. }
  211. else
  212. {
  213.     // This data is not interleaved so
  214.     // dispatch it now
  215.     DispatchBlocks(ulTime);
  216. }
  217.     }
  218.     return !bFailed;
  219. }
  220. BOOL AMRDepack::OnLoss(ULONG32 ulNumPackets) // called to indicate lost packets
  221. {
  222.     if (m_ulMaxInterleave > 0)
  223.     {
  224. ULONG32 delta = m_ulIleavLength - m_ulIleavIndex;
  225. if (ulNumPackets < delta)
  226. {
  227.     // We have lost only a few blocks in the middle
  228.     m_ulIleavIndex += ulNumPackets;
  229. }
  230. else
  231. {
  232.     // We have lost all the remaining blocks
  233.     // in the current interleave block.
  234.     // Dispatch what we have
  235.     DispatchBlocks(m_ulIleavBaseTime);
  236. }
  237.     }
  238.     else
  239. m_bPacketsLost = TRUE;
  240.     return TRUE;
  241. }
  242. void AMRDepack::SetTSSampleRate(ULONG32 ulTSSampleRate)
  243. {
  244.     // Determine the number of timestamp units to increment
  245.     // per frame.
  246.     m_ulTimestampInc = (CAMRFrameInfo::FrameDuration() * ulTSSampleRate) / 1000;
  247. }
  248. BOOL AMRDepack::UpdateIleavInfo(ULONG32 ulILL, ULONG32 ulILP, ULONG32 ulTime)
  249. {
  250.     BOOL bFailed = FALSE;
  251.     if ((ulILP > ulILL) ||
  252. ((m_ulIleavLength != 0) &&
  253.  (ulILP != m_ulIleavIndex)))
  254.     {
  255. bFailed = TRUE;
  256.     }
  257.     else if (ulILP == 0)
  258.     {
  259. // This is the expected case
  260. m_ulIleavIndex = 0;
  261. m_ulIleavLength = ulILL + 1;
  262. m_ulIleavBaseTime = ulTime;
  263.     }
  264.     else if (m_ulIleavLength == 0)
  265.     {
  266. // This case occurs when loss happens
  267. m_ulIleavIndex = ulILP;
  268. m_ulIleavLength = ulILL + 1;
  269. // We need the base time to be valid even if we
  270. // do not start at the beginning of a superblock
  271. // Each packet starts 1 frame later than
  272. // the previous one.
  273. m_ulIleavBaseTime = ulTime - (m_ulTimestampInc) * m_ulIleavIndex;
  274.     }
  275.     return !bFailed;
  276. }
  277. void AMRDepack::GetTOCInfo(Bitstream& bs, AMRTOCInfo& tocInfo)
  278. {
  279.     ULONG32 ulTocBits;
  280.     ULONG32 ulTocMask;
  281.     
  282.     ULONG32 ulShift;
  283.     if (m_bOctetAlign)
  284.     {
  285. // This header is defined in
  286. // 3GPP TS26.235 v5.0.0 Annex B Section B.4.4.2
  287. //   7   6   5   4   3   2   1   0
  288. // +---+---------------+---+---+---+
  289. // | F |       FT      | Q | P | P |
  290. // +---+---------------+---+---+---+
  291. //
  292. // F  = more frames flag
  293. // FT = frame type
  294. // Q  = quality indicator
  295. // P  = padding
  296. ulTocBits = 8;
  297. ulTocMask = 0x80;
  298. ulShift = 2;
  299.     }
  300.     else
  301.     {
  302. // This header is defined in
  303. // 3GPP TS26.235 v5.0.0 Annex B Section B.4.3.2
  304. //   5   4   3   2   1   0
  305. // +---+---------------+---+
  306. // | F |       FT      | Q |
  307. // +---+---------------+---+
  308. //
  309. // F  = more frames flag
  310. // FT = frame type
  311. // Q  = quality indicator
  312. ulTocBits = 6;
  313. ulTocMask = 0x20;
  314. ulShift = 0;
  315.     }
  316.     
  317.     BOOL bDone = FALSE;
  318.     while(!bDone)
  319.     {
  320. ULONG32 entry = bs.GetBits(ulTocBits);
  321. UINT8 type = (UINT8)(entry >> (ulShift + 1)) & 0x0f;
  322. UINT8 quality = (UINT8)(entry >> ulShift) & 0x01;
  323. tocInfo.AddInfo(type, quality);
  324. if ((entry & ulTocMask) == 0)
  325.     bDone = TRUE;
  326.     }    
  327. }
  328. void AMRDepack::SkipCRCInfo(Bitstream& bs, const AMRTOCInfo& tocInfo)
  329. {
  330.     // Skip CRCs if they are present since we don't
  331.     // care about them.
  332.     for (ULONG32 i = 0; i < tocInfo.EntryCount(); i++)
  333.     {
  334. if (tocInfo.GetType(i)  < 14)
  335.     bs.GetBits(8);
  336.     }
  337. }
  338. void AMRDepack::UpdateBlockCount(ULONG32 ulBlockCount)
  339. {
  340.     if (m_ulMaxInterleave > 0)
  341.     {
  342. if (m_ulIleavIndex == 0)
  343. {
  344.     m_ulIleavBlockCount = ulBlockCount;
  345.     
  346.     // Make sure we have enough block space in the
  347.     // buffer
  348.     m_blockBuf.SetBlockCount(m_ulIleavBlockCount * m_ulIleavLength);
  349. }
  350.     }
  351.     else
  352.     {
  353. // Make sure we have enough block space in the
  354. // buffer for this packet
  355. m_blockBuf.SetBlockCount(ulBlockCount);
  356.     }
  357. }
  358. void AMRDepack::LinearCopy(Bitstream& bs, 
  359.    ULONG32 ulStartBlock, ULONG32 ulBlockInc,
  360.    const AMRTOCInfo& tocInfo)
  361. {
  362.     ULONG32 ulBlockIndex = ulStartBlock;
  363.     ULONG32 ulFrameIndex = 0;
  364.     
  365.     for (ULONG32 j = 0; j < m_blockBuf.GetBlockCount(); j++)
  366.     {
  367. UINT8* pStart = m_blockBuf.GetBlockBuf(ulBlockIndex);
  368. ULONG32 ulFrameSize = GetFrameBlock(bs,
  369.     pStart, 
  370.     tocInfo, ulFrameIndex,
  371.     m_ulChannels);
  372. if (ulFrameSize)
  373. {
  374.     // Store frame size information
  375.     m_blockBuf.SetBlockSize(ulBlockIndex, ulFrameSize);
  376.     
  377.     // Update the block index
  378.     ulBlockIndex += ulBlockInc;
  379.     
  380.     // Update the frame index. Each frame block
  381.     // consumes m_ulChannels frames
  382.     ulFrameIndex += m_ulChannels;
  383. }
  384. else
  385.     break;
  386.     }
  387. }
  388. ULONG32 AMRDepack::GetFrameBlock(Bitstream& bs,
  389.  UINT8* pStart, 
  390.  const AMRTOCInfo& tocInfo,
  391.  ULONG32 ulStartEntry,
  392.  ULONG32 ulChannels)
  393. {
  394.     ULONG32 ulRet = 0;
  395.     ULONG32 ulEnd = ulChannels + ulStartEntry;
  396.     if (ulEnd <= tocInfo.EntryCount())
  397.     {
  398. BOOL bFailed = FALSE;
  399. UINT8* pCurrent = pStart;
  400. for (ULONG32 i = ulStartEntry; i < ulEnd; i++)
  401. {
  402.     ULONG32 ulFrameType = tocInfo.GetType(i);
  403.     
  404.     if ((ulFrameType < 9) || (ulFrameType == 15))
  405.     {
  406. ULONG32 ulFrameBits = GetFrameBits(ulFrameType);
  407. ULONG32 ulFrameBytes = (ulFrameBits + 7) >> 3;
  408. if (m_bOctetAlign)
  409. {
  410.     // Octet Aligned contains padding already
  411.     ulFrameBits = ulFrameBytes << 3;
  412. }
  413. // Create frame header.
  414. // This header is defined in
  415.                 // 3GPP TS26.235 v5.0.0 Annex B Section B.5.3
  416.                 //   7   6   5   4   3   2   1   0
  417.                 // +---+---------------+---+---+---+
  418.                 // | P |       FT      | Q | P | P |
  419.                 // +---+---------------+---+---+---+
  420.                 //
  421.                 // P  = padding
  422.                 // FT = frame type
  423.                 // Q  = quality indicator
  424. *pCurrent++ = (UINT8)((ulFrameType << 3) | 
  425.       (tocInfo.GetQuality(i) << 2));
  426. if (ulFrameBytes > 0)
  427. {
  428.     // Set last byte of frame to 0 for padding
  429.     pCurrent[ulFrameBytes - 1] = 0;
  430.     
  431.     // Copy frame bits into the buffer
  432.     bs.GetBits(ulFrameBits, pCurrent);
  433.     // Move current pointer to just past this frame
  434.     pCurrent += ulFrameBytes;
  435. }
  436.     }
  437.     else
  438.     {
  439. bFailed = TRUE;
  440. break;
  441.     }
  442. }
  443. if (bFailed == FALSE)
  444.     ulRet = pCurrent - pStart;
  445.     }
  446.     return ulRet;
  447. }
  448. void AMRDepack::SortedCopy(Bitstream& bs, 
  449.    ULONG32 ulStartBlock, ULONG32 ulBlockInc,
  450.    const AMRTOCInfo& tocInfo)
  451. {
  452.     // This function copies robust sorted data from the packet.
  453.     // Unfortunately this is not very efficient because the bytes
  454.     // of each frame are interleaved with eachother. The
  455.     // AMRRobustSortingItr class provides us with the block number
  456.     // and block byte offset for each byte in the sorted data.
  457.     AMRRobustSortingItr itr;
  458.     itr.Init(m_flavor, m_ulChannels, ulStartBlock, ulBlockInc, tocInfo);
  459.     for (;itr.More(); itr.Next())
  460.     {
  461. UINT8* pDest = m_blockBuf.GetBlockBuf(itr.Block()) + itr.Offset();
  462. // Copy the byte
  463. *pDest = (UINT8)bs.GetBits(8);
  464.     }
  465. }
  466. void AMRDepack::DispatchFrameBlock(ULONG32 ulTimestamp,
  467.    const UINT8* pFrame, ULONG32 ulFrameSize)
  468. {
  469.     // We can get duplicate frames so we need to make
  470.     // a check to see if we have already sent this frame
  471.     if (((m_bLastTimeValid == FALSE) ||
  472.  (ulTimestamp > m_ulLastTimestamp)) &&
  473. (m_pCallback))
  474.     {
  475. m_pCallback(m_pUserData,
  476.     ulTimestamp,
  477.     pFrame, ulFrameSize,
  478.     m_bPacketsLost);
  479. // Update last timestamp
  480. m_ulLastTimestamp = ulTimestamp;
  481. m_bLastTimeValid = TRUE;
  482.     }
  483.     
  484.     // Clear packet flag
  485.     m_bPacketsLost = FALSE;
  486. }
  487. void AMRDepack::DispatchBlocks(ULONG32 ulTimestamp)
  488. {
  489.     for (ULONG32 i = 0; i < m_blockBuf.GetBlockCount(); i++)
  490.     {
  491. ULONG32 ulFrameSize = m_blockBuf.GetBlockSize(i);
  492. if (ulFrameSize)
  493. {
  494.     DispatchFrameBlock(ulTimestamp, 
  495.        m_blockBuf.GetBlockBuf(i), ulFrameSize);
  496. }
  497. else
  498. {
  499.     // Signal that loss has occured
  500.     m_bPacketsLost = TRUE;
  501. }
  502. // Increment the timestamp
  503. ulTimestamp += m_ulTimestampInc;
  504.     }
  505.     
  506.     // Clear interleave state info
  507.     m_ulIleavIndex = 0;
  508.     m_ulIleavLength = 0;
  509. }