adts.cpp
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:6k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /*
  2.  * The contents of this file are subject to the Mozilla Public
  3.  * License Version 1.1 (the "License"); you may not use this file
  4.  * except in compliance with the License. You may obtain a copy of
  5.  * the License at http://www.mozilla.org/MPL/
  6.  * 
  7.  * Software distributed under the License is distributed on an "AS
  8.  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  9.  * implied. See the License for the specific language governing
  10.  * rights and limitations under the License.
  11.  * 
  12.  * The Original Code is MPEG4IP.
  13.  * 
  14.  * The Initial Developer of the Original Code is Cisco Systems Inc.
  15.  * Portions created by Cisco Systems Inc. are
  16.  * Copyright (C) Cisco Systems Inc. 2000-2002.  All Rights Reserved.
  17.  * 
  18.  * Contributor(s): 
  19.  * Dave Mackie dmackie@cisco.com
  20.  */
  21. /* 
  22.  * Notes:
  23.  *  - file formatted with tabstops == 4 spaces 
  24.  */
  25. #include <mp4av_common.h>
  26. /*
  27.  * ADTS Header: 
  28.  *  MPEG-2 version 56 bits (byte aligned) 
  29.  *  MPEG-4 version 58 bits (not byte aligned)
  30.  *
  31.  * syncword 12 bits
  32.  * id 1 bit
  33.  * layer 2 bits
  34.  * protection_absent 1 bit
  35.  * profile 2 bits
  36.  * sampling_frequency_index 4 bits
  37.  * private 1 bit
  38.  * channel_configuraton 3 bits
  39.  * original 1 bit
  40.  * home 1 bit
  41.  * emphasis 2 bits
  42.  * copyright_id 1 bit
  43.  * copyright_id_start 1 bit
  44.  * aac_frame_length 13 bits
  45.  * adts_buffer_fullness 11 bits
  46.  * num_raw_data_blocks 2 bits
  47.  *
  48.  * if (protection_absent == 0)
  49.  * crc_check 16 bits
  50.  */
  51. u_int32_t AdtsSamplingRates[NUM_ADTS_SAMPLING_RATES] = {
  52. 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 
  53. 16000, 12000, 11025, 8000, 7350, 0, 0, 0
  54. };
  55. /*
  56.  * compute ADTS frame size
  57.  */
  58. extern "C" u_int16_t MP4AV_AdtsGetFrameSize(u_int8_t* pHdr)
  59. {
  60. /* extract the necessary fields from the header */
  61. u_int8_t isMpeg4 = !(pHdr[1] & 0x08);
  62. u_int16_t frameLength;
  63. if (isMpeg4) {
  64. frameLength = (((u_int16_t)pHdr[4]) << 5) | (pHdr[5] >> 3); 
  65. } else { /* MPEG-2 */
  66. frameLength = (((u_int16_t)(pHdr[3] & 0x3)) << 11) 
  67. | (((u_int16_t)pHdr[4]) << 3) | (pHdr[5] >> 5); 
  68. }
  69. return frameLength;
  70. }
  71. /*
  72.  * Compute length of ADTS header in bits
  73.  */
  74. extern "C" u_int16_t MP4AV_AdtsGetHeaderBitSize(u_int8_t* pHdr)
  75. {
  76. u_int8_t isMpeg4 = !(pHdr[1] & 0x08);
  77. u_int8_t hasCrc = !(pHdr[1] & 0x01);
  78. u_int16_t hdrSize;
  79. if (isMpeg4) {
  80. hdrSize = 58;
  81. } else {
  82. hdrSize = 56;
  83. }
  84. if (hasCrc) {
  85. hdrSize += 16;
  86. }
  87. return hdrSize;
  88. }
  89. extern "C" u_int16_t MP4AV_AdtsGetHeaderByteSize(u_int8_t* pHdr)
  90. {
  91. return (MP4AV_AdtsGetHeaderBitSize(pHdr) + 7) / 8;
  92. }
  93. extern "C" u_int8_t MP4AV_AdtsGetVersion(u_int8_t* pHdr)
  94. {
  95. return (pHdr[1] & 0x08) >> 3;
  96. }
  97. extern "C" u_int8_t MP4AV_AdtsGetProfile(u_int8_t* pHdr)
  98. {
  99. return (pHdr[2] & 0xc0) >> 6;
  100. }
  101. extern "C" u_int8_t MP4AV_AdtsGetSamplingRateIndex(u_int8_t* pHdr)
  102. {
  103. return (pHdr[2] & 0x3c) >> 2;
  104. }
  105. extern "C" u_int8_t MP4AV_AdtsFindSamplingRateIndex(u_int32_t samplingRate)
  106. {
  107. for (u_int8_t i = 0; i < NUM_ADTS_SAMPLING_RATES; i++) {
  108. if (samplingRate == AdtsSamplingRates[i]) {
  109. return i;
  110. }
  111. }
  112. return NUM_ADTS_SAMPLING_RATES - 1;
  113. }
  114. extern "C" u_int32_t MP4AV_AdtsGetSamplingRate(u_int8_t* pHdr)
  115. {
  116. return AdtsSamplingRates[MP4AV_AdtsGetSamplingRateIndex(pHdr)];
  117. }
  118. extern "C" u_int8_t MP4AV_AdtsGetChannels(u_int8_t* pHdr)
  119. {
  120. return ((pHdr[2] & 0x1) << 2) | ((pHdr[3] & 0xc0) >> 6);
  121. }
  122. extern "C" bool MP4AV_AdtsMakeFrameFromMp4Sample(
  123. MP4FileHandle mp4File,
  124. MP4TrackId trackId,
  125. MP4SampleId sampleId,
  126. u_int8_t** ppAdtsData,
  127. u_int32_t* pAdtsDataLength)
  128. {
  129. static MP4FileHandle lastMp4File = MP4_INVALID_FILE_HANDLE;
  130. static MP4TrackId lastMp4TrackId = MP4_INVALID_TRACK_ID;
  131. static bool isMpeg2;
  132. static u_int8_t profile;
  133. static u_int32_t samplingFrequency;
  134. static u_int8_t channels;
  135. if (mp4File != lastMp4File || trackId != lastMp4TrackId) {
  136. // changed cached file and track info
  137. lastMp4File = mp4File;
  138. lastMp4TrackId = trackId;
  139. u_int8_t audioType = MP4GetTrackAudioType(mp4File, trackId);
  140. if (MP4_IS_MPEG2_AAC_AUDIO_TYPE(audioType)) {
  141. isMpeg2 = true;
  142. profile = audioType - MP4_MPEG2_AAC_MAIN_AUDIO_TYPE;
  143. } else if (audioType == MP4_MPEG4_AUDIO_TYPE) {
  144. isMpeg2 = false;
  145. profile = MP4GetTrackAudioMpeg4Type(mp4File, trackId) - 1;
  146. } else {
  147. lastMp4File = MP4_INVALID_FILE_HANDLE;
  148. lastMp4TrackId = MP4_INVALID_TRACK_ID;
  149. return false;
  150. }
  151. u_int8_t* pConfig = NULL;
  152. u_int32_t configLength;
  153. MP4GetTrackESConfiguration(
  154. mp4File, 
  155. trackId,
  156. &pConfig,
  157. &configLength);
  158. if (pConfig == NULL || configLength < 2) {
  159. lastMp4File = MP4_INVALID_FILE_HANDLE;
  160. lastMp4TrackId = MP4_INVALID_TRACK_ID;
  161. return false;
  162. }
  163. samplingFrequency = MP4AV_AacConfigGetSamplingRate(pConfig);
  164. channels = MP4AV_AacConfigGetChannels(pConfig);
  165. }
  166. bool rc;
  167. u_int8_t* pSample = NULL;
  168. u_int32_t sampleSize = 0;
  169. rc = MP4ReadSample(
  170. mp4File,
  171. trackId,
  172. sampleId,
  173. &pSample,
  174. &sampleSize);
  175. if (!rc) {
  176. return false;
  177. }
  178. rc = MP4AV_AdtsMakeFrame(
  179. pSample,
  180. sampleSize,
  181. isMpeg2,
  182. profile,
  183. samplingFrequency,
  184. channels,
  185. ppAdtsData,
  186. pAdtsDataLength);
  187. free(pSample);
  188. return rc;
  189. }
  190. extern "C" bool MP4AV_AdtsMakeFrame(
  191. u_int8_t* pData,
  192. u_int16_t dataLength,
  193. bool isMpeg2,
  194. u_int8_t profile,
  195. u_int32_t samplingFrequency,
  196. u_int8_t channels,
  197. u_int8_t** ppAdtsData,
  198. u_int32_t* pAdtsDataLength)
  199. {
  200. *pAdtsDataLength = (isMpeg2 ? 7 : 8) + dataLength;
  201. CMemoryBitstream adts;
  202. try {
  203. adts.AllocBytes(*pAdtsDataLength);
  204. *ppAdtsData = adts.GetBuffer();
  205. // build adts header
  206. adts.PutBits(0xFFF, 12); // syncword
  207. adts.PutBits(isMpeg2, 1); // id
  208. adts.PutBits(0, 2); // layer
  209. adts.PutBits(1, 1); // protection_absent
  210. adts.PutBits(profile, 2); // profile
  211. adts.PutBits(
  212. MP4AV_AdtsFindSamplingRateIndex(samplingFrequency),
  213. 4); // sampling_frequency_index
  214. adts.PutBits(0, 1); // private
  215. adts.PutBits(channels, 3); // channel_configuration
  216. adts.PutBits(0, 1); // original
  217. adts.PutBits(0, 1); // home
  218. adts.PutBits(0, 2); // emphasis
  219. adts.PutBits(0, 1); // copyright_id
  220. adts.PutBits(0, 1); // copyright_id_start
  221. adts.PutBits(*pAdtsDataLength, 13); // aac_frame_length
  222. adts.PutBits(0x7FF, 11); // adts_buffer_fullness
  223. adts.PutBits(1, 2); // num_raw_data_blocks
  224. // copy audio frame data
  225. adts.PutBytes(pData, dataLength);
  226. }
  227. catch (int e) {
  228. return false;
  229. }
  230. return true;
  231. }