1
0

ADTSAACDecoder.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387
  1. #include "ADTSAACDecoder.h"
  2. #include "ADTSHeader.h"
  3. #include "../nsutil/pcm.h"
  4. #include <bfc/error.h>
  5. #define PRE_PADDING_MAGIC_WORD 'lluN'
  6. #define POST_PADDING_MAGIC_WORD 'tfos'
  7. #pragma pack(push, 1)
  8. struct AncillaryData
  9. {
  10. int magicWord; // set to 'lluN' for pre-delay, 'tfos' for post-delay
  11. unsigned short padding;
  12. };
  13. #pragma pack(pop)
  14. ADTSAACDecoder::ADTSAACDecoder()
  15. {
  16. predelay = 0;
  17. decoder = 0;
  18. access_unit = 0;
  19. composition_unit = 0;
  20. useFloat = false; /* we'll fix during Initialize */
  21. gain=1.0f; /* we'll fix during Initialize */
  22. channels = 2; /* we'll fix during Initialize */
  23. // get bps
  24. bitsPerSample = 16; /* we'll fix during Initialize */
  25. allowRG = false; /* we'll fix during Initialize */
  26. }
  27. int ADTSAACDecoder::Initialize(bool forceMono, bool reverse_stereo, bool allowSurround, int maxBits, bool _allowRG, bool _useFloat, bool _useCRC)
  28. {
  29. allowRG = _allowRG;
  30. useFloat = _useFloat;
  31. if (_useFloat)
  32. {
  33. bitsPerSample = 32;
  34. }
  35. else if (maxBits >= 24)
  36. {
  37. bitsPerSample = 24;
  38. }
  39. else
  40. {
  41. bitsPerSample = 16;
  42. }
  43. if (forceMono)
  44. channels = 1;
  45. else if (allowSurround)
  46. channels = 8;
  47. else
  48. channels = 2;
  49. /* with FhG's API, we can't actually create a decoder until we have the ASC.
  50. best we can do right now is create the access unit object */
  51. access_unit = CAccessUnit_Create(0, 0);
  52. if (access_unit)
  53. return adts::SUCCESS;
  54. else
  55. return adts::FAILURE;
  56. }
  57. bool ADTSAACDecoder::Open(ifc_mpeg_stream_reader *file)
  58. {
  59. if (allowRG)
  60. gain = file->MPEGStream_Gain();
  61. return true;
  62. }
  63. void ADTSAACDecoder::Close()
  64. {
  65. mp4AudioDecoder_Destroy(&decoder);
  66. decoder=0;
  67. CAccessUnit_Destroy(&access_unit);
  68. CCompositionUnit_Destroy(&composition_unit);
  69. }
  70. void ADTSAACDecoder::GetOutputParameters(size_t *numBits, int *numChannels, int *sampleRate)
  71. {
  72. CCompositionUnit_GetSamplingRate(composition_unit, (unsigned int *)sampleRate);
  73. *numChannels = channels;
  74. *numBits = bitsPerSample;
  75. }
  76. void ADTSAACDecoder::CalculateFrameSize(int *frameSize)
  77. {
  78. unsigned int samples_per_channel;
  79. if (decoder && CCompositionUnit_GetSamplesPerChannel(composition_unit, &samples_per_channel) == MP4AUDIODEC_OK)
  80. *frameSize = samples_per_channel*channels;
  81. else
  82. *frameSize = 0;
  83. }
  84. void ADTSAACDecoder::Flush(ifc_mpeg_stream_reader *file)
  85. {
  86. mp4AudioDecoder_Reset(decoder, MP4AUDIODECPARAM_DEFAULT, 0);
  87. }
  88. size_t ADTSAACDecoder::GetCurrentBitrate()
  89. {
  90. int current_bitrate;
  91. if (CCompositionUnit_GetProperty(composition_unit, CUBUFFER_AVGBITRATE, &current_bitrate) == MP4AUDIODEC_OK)
  92. {
  93. return current_bitrate/1000;
  94. }
  95. else
  96. return 0;
  97. }
  98. size_t ADTSAACDecoder::GetDecoderDelay()
  99. {
  100. return predelay;
  101. }
  102. static int ADTSSync(const uint8_t *buffer, size_t bytes_in_buffer, size_t *header_position)
  103. {
  104. for (size_t position=0;position<bytes_in_buffer;position++)
  105. {
  106. // find POTENTIAL sync
  107. if (buffer[position] == 0xFF && bytes_in_buffer - position >= 7)
  108. {
  109. ADTSHeader header;
  110. if (nsaac_adts_parse(&header, &buffer[position]) == NErr_Success)
  111. {
  112. int frame_length = header.frame_length;
  113. if (frame_length && bytes_in_buffer - position - frame_length >= 7)
  114. {
  115. ADTSHeader header2;
  116. if (nsaac_adts_parse(&header2, &buffer[position+frame_length]) == NErr_Success)
  117. {
  118. // verify that parameters match
  119. if (nsaac_adts_match(&header, &header2) != NErr_True)
  120. return NErr_Changed;
  121. // do a dummy read to advance the stream
  122. *header_position = position;
  123. return NErr_Success;
  124. }
  125. }
  126. else
  127. {
  128. /* not enough in the buffer to verify the next header */
  129. *header_position = position;
  130. return NErr_NeedMoreData;
  131. }
  132. }
  133. }
  134. }
  135. return NErr_False;
  136. }
  137. static int ReturnIsEOF(ifc_mpeg_stream_reader *file)
  138. {
  139. if (file->MPEGStream_EOF())
  140. return adts::ENDOFFILE;
  141. else
  142. return adts::NEEDMOREDATA;
  143. }
  144. int ADTSAACDecoder::Internal_Decode(ifc_mpeg_stream_reader *file, const void *input, size_t input_length, unsigned __int8 *output, size_t outputSize, size_t *outputWritten, size_t *bitrate, size_t *endCut)
  145. {
  146. CAccessUnit_Reset(access_unit);
  147. CAccessUnit_Assign(access_unit, (const unsigned char *)input, input_length);
  148. CCompositionUnit_Reset(composition_unit);
  149. MP4_RESULT result = mp4AudioDecoder_DecodeFrame(decoder, &access_unit, composition_unit);
  150. if (result == MP4AUDIODEC_OK)
  151. {
  152. /* check ancillary data for gapless data */
  153. unsigned int ancillary_fields, ancillary_bytes;
  154. if (CCompositionUnit_GetAncDataCount(composition_unit, &ancillary_fields, &ancillary_bytes) == MP4AUDIODEC_OK)
  155. {
  156. for (unsigned int i=0;i<ancillary_fields;i++)
  157. {
  158. unsigned char *ancillary_data;
  159. unsigned int ancillary_size;
  160. unsigned int ancillary_tag;
  161. CCompositionUnit_GetAncDataByPos(composition_unit, i, &ancillary_data, &ancillary_size, &ancillary_tag);
  162. if (ancillary_tag == ANCDATA_IS_AAC_DSE_TAG15 && ancillary_size == 6)
  163. {
  164. /* this is only safe on x86 because of alignment and endian */
  165. const AncillaryData *data = (const AncillaryData *)ancillary_data;
  166. if (data->magicWord == PRE_PADDING_MAGIC_WORD)
  167. {
  168. predelay = data->padding;
  169. }
  170. else if (data->magicWord == POST_PADDING_MAGIC_WORD)
  171. {
  172. *endCut = data->padding;
  173. }
  174. }
  175. }
  176. }
  177. unsigned int channels;
  178. unsigned int samples_per_channel;
  179. if (CCompositionUnit_GetSamplesPerChannel(composition_unit, &samples_per_channel) != MP4AUDIODEC_OK
  180. || CCompositionUnit_GetChannels(composition_unit, &channels) != MP4AUDIODEC_OK)
  181. return adts::FAILURE;
  182. if (samples_per_channel == 0)
  183. return adts::NEEDMOREDATA;
  184. const float *audio_output = 0;
  185. size_t num_samples = samples_per_channel * channels;
  186. size_t output_size = num_samples * (bitsPerSample/8);
  187. if (output_size > outputSize)
  188. return adts::FAILURE;
  189. *outputWritten = output_size;
  190. CCompositionUnit_GetPcmPtr(composition_unit, &audio_output);
  191. if (!useFloat)
  192. {
  193. nsutil_pcm_FloatToInt_Interleaved_Gain(output, audio_output, bitsPerSample, num_samples, gain/32768.0f);
  194. }
  195. else
  196. {
  197. for (size_t i = 0;i != num_samples;i++)
  198. ((float *)output)[i] = audio_output[i] * gain / 32768.0f;
  199. }
  200. int br;
  201. CCompositionUnit_GetProperty(composition_unit, CUBUFFER_CURRENTBITRATE, &br);
  202. *bitrate = br/1000;
  203. return adts::SUCCESS;
  204. }
  205. else
  206. return adts::FAILURE;
  207. }
  208. static void ConfigureADTS(CSAudioSpecificConfig* asc, nsaac_adts_header_t header)
  209. {
  210. asc->m_aot = (AUDIO_OBJECT_TYPE)(header->profile + 1);
  211. asc->m_channelConfiguration = header->channel_configuration;
  212. asc->m_channels = nsaac_adts_get_channel_count(header);
  213. asc->m_nrOfStreams = 1;
  214. asc->m_samplesPerFrame = 1024;
  215. asc->m_samplingFrequencyIndex = header->sample_rate_index;
  216. asc->m_samplingFrequency = nsaac_adts_get_samplerate(header);
  217. asc->m_avgBitRate = 0; /* only needed for tvq */
  218. asc->m_mpsPresentFlag = -1;
  219. asc->m_saocPresentFlag = -1;
  220. asc->m_ldmpsPresentFlag = -1;
  221. }
  222. int ADTSAACDecoder::Sync(ifc_mpeg_stream_reader *file, unsigned __int8 *output, size_t outputSize, size_t *outputWritten, size_t *bitrate)
  223. {
  224. /* ok this will be interesting. we'll peek from the input buffer and try to synchronize on an ADTS header */
  225. uint8_t peek_buffer[16384] = {0};
  226. size_t bytes_read = 0;
  227. if (file->MPEGStream_Peek(peek_buffer, sizeof(peek_buffer), &bytes_read) != 0)
  228. {
  229. return adts::FAILURE;
  230. }
  231. size_t header_position=0;
  232. int ret = ADTSSync(peek_buffer, bytes_read, &header_position);
  233. if (ret == NErr_NeedMoreData)
  234. {
  235. // this one means we found one sync but not enough to verify the next frame
  236. // if the header was at the start of the block, then unfortunately this might be the LAST adts frame in the file, so let's just pass it the decoder and hope for the best
  237. if (header_position != 0)
  238. {
  239. if (file->MPEGStream_EOF())
  240. return adts::ENDOFFILE;
  241. /* dummy read to advance the stream */
  242. file->MPEGStream_Read(peek_buffer, header_position, &header_position);
  243. return adts::NEEDMOREDATA;
  244. }
  245. }
  246. else if (ret == NErr_False)
  247. {
  248. if (file->MPEGStream_EOF())
  249. return adts::ENDOFFILE;
  250. // not even a potential sync found
  251. /* dummy read to advance the stream */
  252. file->MPEGStream_Read(peek_buffer, bytes_read, &bytes_read);
  253. return adts::NEEDMOREDATA;
  254. }
  255. else if (ret != NErr_Success)
  256. {
  257. if (file->MPEGStream_EOF())
  258. return adts::ENDOFFILE;
  259. return adts::FAILURE;
  260. }
  261. ADTSHeader header;
  262. if (nsaac_adts_parse(&header, &peek_buffer[header_position]) == NErr_Success)
  263. {
  264. CSAudioSpecificConfig asc;
  265. memset(&asc, 0, sizeof(asc));
  266. ConfigureADTS(&asc, &header);
  267. if (!decoder)
  268. {
  269. CSAudioSpecificConfig *asc_array = &asc;
  270. decoder = mp4AudioDecoder_Create(&asc_array, 1);
  271. if (decoder)
  272. {
  273. mp4AudioDecoder_SetParam(decoder, TDL_MODE, SWITCH_OFF);
  274. mp4AudioDecoder_SetParam(decoder, CONCEALMENT_ENERGYINTERPOLATION, SWITCH_OFF);
  275. composition_unit = CCompositionUnit_Create(max(asc.m_channels, 8), asc.m_samplesPerFrame * 2, asc.m_samplingFrequency, 6144, CUBUFFER_PCMTYPE_FLOAT);
  276. }
  277. if (!decoder || !composition_unit)
  278. return adts::FAILURE;
  279. }
  280. /* all this error checking might be uncessary, since in theory we did a successful peek above. but you never know ... */
  281. if (file->MPEGStream_Read(peek_buffer, header_position, &bytes_read)) /* dummy read to advance the stream */
  282. return adts::FAILURE;
  283. if (bytes_read != header_position)
  284. return ReturnIsEOF(file);
  285. if (file->MPEGStream_Read(peek_buffer, header.frame_length, &bytes_read)) /* read ADTS frame */
  286. return adts::FAILURE;
  287. if (bytes_read != header.frame_length)
  288. return ReturnIsEOF(file);
  289. if (bytes_read < 7) /* bad header data? */
  290. return adts::FAILURE;
  291. /* ok, we've created the decoder, but we should really decode the frame to see if there's VBR, PS or MPEGS in it */
  292. size_t header_size = nsaac_adts_get_header_size(&header);
  293. size_t endCut;
  294. int ret = Internal_Decode(file, peek_buffer+header_size, bytes_read-header_size, output, outputSize, outputWritten, bitrate, &endCut);
  295. if (ret == adts::SUCCESS)
  296. CCompositionUnit_GetChannels(composition_unit, &channels);
  297. return ret;
  298. }
  299. return adts::FAILURE;
  300. }
  301. int ADTSAACDecoder::Decode(ifc_mpeg_stream_reader *file, unsigned __int8 *output, size_t outputSize, size_t *outputWritten, size_t *bitrate, size_t *endCut)
  302. {
  303. uint8_t peek_buffer[8192] = {0};
  304. size_t bytes_read = 0;
  305. file->MPEGStream_Peek(peek_buffer, 7, &bytes_read);
  306. if (bytes_read != 7)
  307. return ReturnIsEOF(file);
  308. ADTSHeader header;
  309. if (nsaac_adts_parse(&header, peek_buffer) == NErr_Success)
  310. {
  311. if (header.frame_length < 7)
  312. return adts::FAILURE;
  313. file->MPEGStream_Peek(peek_buffer, header.frame_length, &bytes_read);
  314. if (bytes_read != header.frame_length)
  315. return ReturnIsEOF(file);
  316. file->MPEGStream_Read(peek_buffer, header.frame_length, &bytes_read);
  317. size_t header_size = nsaac_adts_get_header_size(&header);
  318. return Internal_Decode(file, peek_buffer+header_size, bytes_read-header_size, output, outputSize, outputWritten, bitrate, endCut);
  319. }
  320. else
  321. {
  322. /* Resynchronize */
  323. return Sync(file, output, outputSize, outputWritten, bitrate);
  324. }
  325. }
  326. int ADTSAACDecoder::GetLayer()
  327. {
  328. return 4;
  329. }
  330. void ADTSAACDecoder::Release()
  331. {
  332. delete this;
  333. }