PageRenderTime 47ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 0ms

/src/lib/Transcoding/FaadWrapper.cpp

https://bitbucket.org/robertmassaioli/fuppes-fork
C++ | 858 lines | 655 code | 144 blank | 59 comment | 127 complexity | d48b53663b0eabba4eb125e0ee07c624 MD5 | raw file
Possible License(s): GPL-2.0, AGPL-1.0
  1. // vim: set ts=2 sw=2 sts=2 et:
  2. /***************************************************************************
  3. * FaadWrapper.cpp
  4. *
  5. * FUPPES - Free UPnP Entertainment Service
  6. *
  7. * Copyright (C) 2007-2008 Ulrich Völkel <u-voelkel@users.sourceforge.net>
  8. ****************************************************************************/
  9. /*
  10. * This program is free software; you can redistribute it and/or modify
  11. * it under the terms of the GNU General Public License
  12. * as published by the Free Software Foundation; either version 2
  13. * of the License, or (at your option) any later version.
  14. *
  15. * This program is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU General Public License along
  21. * with this program; if not, write to the Free Software Foundation, Inc.,
  22. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  23. */
  24. /*
  25. * this file contains code from FAAD2 version 2.0
  26. *
  27. * FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
  28. * Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
  29. *
  30. * This program is free software; you can redistribute it and/or modify
  31. * it under the terms of the GNU General Public License as published by
  32. * the Free Software Foundation; either version 2 of the License, or
  33. * (at your option) any later version.
  34. */
  35. #include "lib/Transcoding/FaadWrapper.h"
  36. #ifndef DISABLE_TRANSCODING
  37. #ifdef HAVE_FAAD
  38. #ifdef _WIN32
  39. #include <io.h>
  40. #include <fcntl.h>
  41. #endif
  42. #include <string.h>
  43. #include "lib/SharedLog.h"
  44. #include "lib/SharedConfig.h"
  45. static int adts_sample_rates[] = {96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350, 0, 0, 0};
  46. int CFaadWrapper::adts_parse(int *bitrate, float *length)
  47. {
  48. int frames, frame_length;
  49. int t_framelength = 0;
  50. int samplerate;
  51. float frames_per_sec, bytes_per_frame;
  52. // Read all frames to ensure correct time and bitrate
  53. for (frames = 0; ; frames++)
  54. {
  55. if (m_nBufferSize > 7)
  56. {
  57. // check syncword
  58. if (!((m_Buffer[0] == 0xFF) && ((m_Buffer[1] & 0xF6) == 0xF0)))
  59. {
  60. break;
  61. }
  62. if (frames == 0)
  63. {
  64. samplerate = adts_sample_rates[(m_Buffer[2] & 0x3c) >> 2];
  65. }
  66. frame_length = ((((unsigned int)m_Buffer[3] & 0x3)) << 11)
  67. | (((unsigned int)m_Buffer[4]) << 3) | (m_Buffer[5] >> 5);
  68. t_framelength += frame_length;
  69. if (frame_length > (int)m_nBufferSize)
  70. {
  71. break;
  72. }
  73. m_nBytesConsumed = frame_length;
  74. FillBuffer();
  75. }
  76. else
  77. {
  78. break;
  79. }
  80. }
  81. frames_per_sec = (float)samplerate / 1024.0f;
  82. if (frames != 0)
  83. {
  84. bytes_per_frame = (float)t_framelength / (float)(frames * 1000);
  85. }
  86. else
  87. {
  88. bytes_per_frame = 0;
  89. }
  90. *bitrate = (int)(8. * bytes_per_frame * frames_per_sec + 0.5);
  91. if (frames_per_sec != 0)
  92. {
  93. *length = (float)frames / frames_per_sec;
  94. }
  95. else
  96. {
  97. *length = 1;
  98. }
  99. return 1;
  100. }
  101. #ifdef HAVE_MP4FF_H
  102. uint32_t read_callback(void *user_data, void *buffer, uint32_t length)
  103. {
  104. return fread(buffer, 1, length, (FILE *)user_data);
  105. }
  106. uint32_t seek_callback(void *user_data, uint64_t position)
  107. {
  108. return fseek((FILE *)user_data, position, SEEK_SET);
  109. }
  110. #endif // HAVE_MP4FF_H
  111. int CFaadWrapper::write_audio_16bit(char *p_PcmOut, void *sample_buffer, unsigned int samples)
  112. {
  113. unsigned int i;
  114. short *sample_buffer16 = (short *)sample_buffer;
  115. char *data = (char *)malloc(samples * 16 * sizeof(char) / 8);
  116. if(m_nOutEndianess == E_LITTLE_ENDIAN)
  117. {
  118. for (i = 0; i < samples; i++)
  119. {
  120. data[i * 2] = (char)(sample_buffer16[i] & 0xFF);
  121. data[i * 2 + 1] = (char)((sample_buffer16[i] >> 8) & 0xFF);
  122. }
  123. }
  124. else if(m_nOutEndianess == E_BIG_ENDIAN)
  125. {
  126. for (i = 0; i < samples; i++)
  127. {
  128. data[i * 2] = (char)((sample_buffer16[i] >> 8) & 0xFF);
  129. data[i * 2 + 1] = (char)(sample_buffer16[i] & 0xFF);
  130. }
  131. }
  132. memcpy(p_PcmOut, data, samples * 16 * sizeof(char) / 8);
  133. if (data)
  134. {
  135. free(data);
  136. }
  137. return samples * 16 * sizeof(char) / 8;
  138. }
  139. int CFaadWrapper::DecodeAACfile(char *p_PcmOut)
  140. {
  141. void *sample_buffer;
  142. do
  143. {
  144. sample_buffer = m_faacDecDecode(hDecoder, &frameInfo, m_Buffer, m_nBufferSize);
  145. if (frameInfo.error > 0)
  146. {
  147. fprintf(stderr, "decode Error: %s\n",
  148. m_faacDecGetErrorMessage(frameInfo.error));
  149. return -1;
  150. }
  151. m_nBytesConsumed = frameInfo.bytesconsumed;
  152. FillBuffer();
  153. if (first_time && !frameInfo.error)
  154. {
  155. // print some channel info
  156. //print_channel_info(&frameInfo);
  157. first_time = false;
  158. }
  159. if ((frameInfo.error == 0) && (frameInfo.samples > 0))
  160. {
  161. write_audio_16bit(p_PcmOut, sample_buffer, frameInfo.samples);
  162. }
  163. }
  164. while (frameInfo.samples == 0 && m_nBufferSize > 0);
  165. if(frameInfo.samples > 0)
  166. {
  167. return frameInfo.samples / 2;
  168. }
  169. else
  170. {
  171. return -1;
  172. }
  173. }
  174. #ifdef HAVE_MP4FF_H
  175. int CFaadWrapper::GetAACTrack(mp4ff_t *infile)
  176. {
  177. // find AAC track
  178. int i, rc;
  179. int numTracks = m_mp4ff_total_tracks(infile);
  180. printf("num tracks: %d\n", numTracks);
  181. for (i = 0; i < numTracks; i++)
  182. {
  183. unsigned char *buff = NULL;
  184. unsigned int buff_size = 0;
  185. mp4AudioSpecificConfig mp4ASC;
  186. m_mp4ff_get_decoder_config(infile, i, &buff, &buff_size);
  187. if (buff)
  188. {
  189. rc = m_AudioSpecificConfig(buff, buff_size, &mp4ASC);
  190. free(buff);
  191. if (rc < 0)
  192. {
  193. continue;
  194. }
  195. return i;
  196. }
  197. }
  198. // can't decode this
  199. return -1;
  200. }
  201. #endif // HAVE_MP4FF_H
  202. unsigned long srates[] =
  203. {
  204. 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000,
  205. 12000, 11025, 8000
  206. };
  207. #ifdef HAVE_MP4FF_H
  208. int CFaadWrapper::DecodeMP4file(char *p_PcmOut)
  209. {
  210. void *sample_buffer;
  211. unsigned char *buffer;
  212. unsigned int buffer_size;
  213. if(sampleId == numSamples)
  214. {
  215. return -1;
  216. }
  217. do
  218. {
  219. int rc;
  220. long dur;
  221. unsigned int sample_count;
  222. unsigned int delay = 0;
  223. // get acces unit from MP4 file
  224. buffer = NULL;
  225. buffer_size = 0;
  226. dur = m_mp4ff_get_sample_duration(infile, track, sampleId);
  227. rc = m_mp4ff_read_sample(infile, track, sampleId, &buffer, &buffer_size);
  228. if (rc == 0)
  229. {
  230. fprintf(stderr, "Reading from MP4 file failed.\n");
  231. return -1;
  232. }
  233. sample_buffer = m_faacDecDecode(hDecoder, &frameInfo, buffer, buffer_size);
  234. if (buffer)
  235. {
  236. free(buffer);
  237. }
  238. if (sampleId == 0)
  239. {
  240. dur = 0;
  241. }
  242. if (useAacLength || (timescale != samplerate))
  243. {
  244. sample_count = frameInfo.samples;
  245. }
  246. else
  247. {
  248. sample_count = (unsigned int)(dur * frameInfo.channels);
  249. if (!useAacLength && !initial && (sampleId < numSamples / 2) && (sample_count != frameInfo.samples))
  250. {
  251. fprintf(stderr, "MP4 seems to have incorrect frame duration, using values from AAC data.\n");
  252. useAacLength = 1;
  253. sample_count = frameInfo.samples;
  254. }
  255. }
  256. if (initial && (sample_count < framesize * frameInfo.channels) && (frameInfo.samples > sample_count))
  257. {
  258. delay = frameInfo.samples - sample_count;
  259. }
  260. if (first_time && !frameInfo.error)
  261. {
  262. // print some channel info
  263. //print_channel_info(&frameInfo);
  264. first_time = false;
  265. }
  266. if (sample_count > 0)
  267. {
  268. initial = 0;
  269. }
  270. if ((frameInfo.error == 0) && (sample_count > 0))
  271. {
  272. write_audio_16bit(p_PcmOut, sample_buffer, sample_count);
  273. }
  274. if (frameInfo.error > 0)
  275. {
  276. fprintf(stderr, "Warning: %s\n",
  277. m_faacDecGetErrorMessage(frameInfo.error));
  278. }
  279. }
  280. while (frameInfo.samples == 0 && initial);
  281. sampleId++;
  282. if(frameInfo.samples > 0)
  283. {
  284. return frameInfo.samples / 2;
  285. }
  286. else
  287. {
  288. return -1;
  289. }
  290. }
  291. #endif // HAVE_MP4FF_H
  292. CFaadWrapper::CFaadWrapper()
  293. {
  294. numSamples = 0;
  295. hDecoder = NULL;
  296. m_pFileHandle = NULL;
  297. m_LibHandle = NULL;
  298. #ifdef HAVE_MP4FF_H
  299. m_mp4ffLibHandle = NULL;
  300. mp4cb = NULL;
  301. infile = NULL;
  302. #endif // HAVE_MP4FF_H
  303. }
  304. CFaadWrapper::~CFaadWrapper()
  305. {
  306. if(hDecoder)
  307. {
  308. m_faacDecClose(hDecoder);
  309. }
  310. #ifdef HAVE_MP4FF_H
  311. if(infile)
  312. {
  313. m_mp4ff_close(infile);
  314. }
  315. if(mp4cb)
  316. {
  317. free(mp4cb);
  318. }
  319. #endif // HAVE_MP4FF_H
  320. if(m_LibHandle)
  321. {
  322. FuppesCloseLibrary(m_LibHandle);
  323. }
  324. #ifdef HAVE_MP4FF_H
  325. if(m_mp4ffLibHandle)
  326. {
  327. FuppesCloseLibrary(m_mp4ffLibHandle);
  328. }
  329. #endif // HAVE_MP4FF_H
  330. CloseFile();
  331. }
  332. bool CFaadWrapper::LoadLib()
  333. {
  334. #ifdef WIN32
  335. string sLibName = "libfaad-0.dll";
  336. #else
  337. string sLibName = "libfaad.so.0";
  338. #endif
  339. if(!CSharedConfig::Shared()->transcodingSettings->FaadLibName().empty())
  340. {
  341. sLibName = CSharedConfig::Shared()->transcodingSettings->FaadLibName();
  342. }
  343. CSharedLog::Log(L_EXT, __FILE__, __LINE__, "try opening %s", sLibName.c_str());
  344. m_LibHandle = FuppesLoadLibrary(sLibName);
  345. if(!m_LibHandle)
  346. {
  347. CSharedLog::Log(L_EXT, __FILE__, __LINE__, "cannot open library %s", sLibName.c_str());
  348. printf("[WARNING :: AACDecoder] cannot open library %s\n", sLibName.c_str());
  349. return false;
  350. }
  351. m_faacDecOpen = (faacDecOpen_t)FuppesGetProcAddress(m_LibHandle, "faacDecOpen");
  352. if(!m_faacDecOpen)
  353. {
  354. CSharedLog::Log(L_EXT, __FILE__, __LINE__, "cannot load symbol 'faacDecOpen'");
  355. return false;
  356. }
  357. m_faacDecGetErrorMessage = (faacDecGetErrorMessage_t)FuppesGetProcAddress(m_LibHandle, "faacDecGetErrorMessage");
  358. if(!m_faacDecGetErrorMessage)
  359. {
  360. CSharedLog::Log(L_EXT, __FILE__, __LINE__, "cannot load symbol 'faacDecGetErrorMessage'");
  361. return false;
  362. }
  363. m_faacDecGetCurrentConfiguration = (faacDecGetCurrentConfiguration_t)FuppesGetProcAddress(m_LibHandle, "faacDecGetCurrentConfiguration");
  364. if(!m_faacDecGetCurrentConfiguration)
  365. {
  366. CSharedLog::Log(L_EXT, __FILE__, __LINE__, "cannot load symbol 'faacDecGetCurrentConfiguration'");
  367. }
  368. m_faacDecSetConfiguration = (faacDecSetConfiguration_t)FuppesGetProcAddress(m_LibHandle, "faacDecSetConfiguration");
  369. if(!m_faacDecSetConfiguration)
  370. {
  371. CSharedLog::Log(L_EXT, __FILE__, __LINE__, "cannot load symbol 'faacDecSetConfiguration'");
  372. }
  373. m_faacDecInit = (faacDecInit_t)FuppesGetProcAddress(m_LibHandle, "faacDecInit");
  374. if(!m_faacDecInit)
  375. {
  376. CSharedLog::Log(L_EXT, __FILE__, __LINE__, "cannot load symbol 'faacDecInit'");
  377. }
  378. m_faacDecInit2 = (faacDecInit2_t)FuppesGetProcAddress(m_LibHandle, "faacDecInit2");
  379. if(!m_faacDecInit2)
  380. {
  381. CSharedLog::Log(L_EXT, __FILE__, __LINE__, "cannot load symbol 'faacDecInit2'");
  382. return false;
  383. }
  384. m_faacDecDecode = (faacDecDecode_t)FuppesGetProcAddress(m_LibHandle, "faacDecDecode");
  385. if(!m_faacDecDecode)
  386. {
  387. CSharedLog::Log(L_EXT, __FILE__, __LINE__, "cannot load symbol 'faacDecDecode'");
  388. return false;
  389. }
  390. m_faacDecClose = (faacDecClose_t)FuppesGetProcAddress(m_LibHandle, "faacDecClose");
  391. if(!m_faacDecClose)
  392. {
  393. CSharedLog::Log(L_EXT, __FILE__, __LINE__, "cannot load symbol 'faacDecClose'");
  394. return false;
  395. }
  396. m_AudioSpecificConfig = (AudioSpecificConfig_t)FuppesGetProcAddress(m_LibHandle, "AudioSpecificConfig");
  397. if(!m_AudioSpecificConfig)
  398. {
  399. m_AudioSpecificConfig = (AudioSpecificConfig_t)FuppesGetProcAddress(m_LibHandle, "faacDecAudioSpecificConfig");
  400. if(!m_AudioSpecificConfig)
  401. {
  402. CSharedLog::Log(L_EXT, __FILE__, __LINE__, "cannot load symbol '(faacDec)AudioSpecificConfig'");
  403. return false;
  404. }
  405. }
  406. #ifdef HAVE_MP4FF_H
  407. #ifdef WIN32
  408. sLibName = "libmp4ff-0.dll";
  409. #else
  410. sLibName = "libmp4ff.so.0";
  411. #endif
  412. /*if(!CSharedConfig::Shared()->Mp4ffLibName().empty()) {
  413. sLibName = CSharedConfig::Shared()->Mp4ffLibName();
  414. }*/
  415. CSharedLog::Shared()->Log(L_EXT, "try opening " + sLibName, __FILE__, __LINE__);
  416. m_mp4ffLibHandle = FuppesLoadLibrary(sLibName);
  417. if(!m_mp4ffLibHandle)
  418. {
  419. CSharedLog::Log(L_EXT, __FILE__, __LINE__, "cannot open library %s", sLibName.c_str());
  420. printf("[WARNING :: AACDecoder] cannot open library %s\n", sLibName.c_str());
  421. return false;
  422. }
  423. m_mp4ff_read_sample = (mp4ff_read_sample_t)FuppesGetProcAddress(m_mp4ffLibHandle, "mp4ff_read_sample");
  424. if(!m_mp4ff_read_sample)
  425. {
  426. CSharedLog::Log(L_EXT, __FILE__, __LINE__, "cannot load symbol 'mp4ff_read_sample'");
  427. return false;
  428. }
  429. m_mp4ff_time_scale = (mp4ff_time_scale_t)FuppesGetProcAddress(m_mp4ffLibHandle, "mp4ff_time_scale");
  430. if(!m_mp4ff_time_scale)
  431. {
  432. CSharedLog::Log(L_EXT, __FILE__, __LINE__, "cannot load symbol 'mp4ff_time_scale'");
  433. return false;
  434. }
  435. m_mp4ff_num_samples = (mp4ff_num_samples_t)FuppesGetProcAddress(m_mp4ffLibHandle, "mp4ff_num_samples");
  436. if(!m_mp4ff_num_samples)
  437. {
  438. CSharedLog::Log(L_EXT, __FILE__, __LINE__, "cannot load symbol 'mp4ff_num_samples'");
  439. return false;
  440. }
  441. m_mp4ff_open_read = (mp4ff_open_read_t)FuppesGetProcAddress(m_mp4ffLibHandle, "mp4ff_open_read");
  442. if(!m_mp4ff_open_read)
  443. {
  444. CSharedLog::Log(L_EXT, __FILE__, __LINE__, "cannot load symbol 'mp4ff_open_read'");
  445. return false;
  446. }
  447. m_mp4ff_close = (mp4ff_close_t)FuppesGetProcAddress(m_mp4ffLibHandle, "mp4ff_close");
  448. if(!m_mp4ff_close)
  449. {
  450. CSharedLog::Log(L_EXT, __FILE__, __LINE__, "cannot load symbol 'mp4ff_close'");
  451. return false;
  452. }
  453. m_mp4ff_get_decoder_config = (mp4ff_get_decoder_config_t)FuppesGetProcAddress(m_mp4ffLibHandle, "mp4ff_get_decoder_config");
  454. if(!m_mp4ff_get_decoder_config)
  455. {
  456. CSharedLog::Log(L_EXT, __FILE__, __LINE__, "cannot load symbol 'mp4ff_get_decoder_config'");
  457. return false;
  458. }
  459. m_mp4ff_total_tracks = (mp4ff_total_tracks_t)FuppesGetProcAddress(m_mp4ffLibHandle, "mp4ff_total_tracks");
  460. if(!m_mp4ff_total_tracks)
  461. {
  462. CSharedLog::Log(L_EXT, __FILE__, __LINE__, "cannot load symbol 'mp4ff_total_tracks'");
  463. return false;
  464. }
  465. m_mp4ff_get_sample_duration = (mp4ff_get_sample_duration_t)FuppesGetProcAddress(m_mp4ffLibHandle, "mp4ff_get_sample_duration");
  466. if(!m_mp4ff_get_sample_duration)
  467. {
  468. CSharedLog::Log(L_EXT, __FILE__, __LINE__, "cannot load symbol 'mp4ff_get_sample_duration'");
  469. return false;
  470. }
  471. #endif // HAVE_MP4FF_H
  472. return true;
  473. }
  474. bool CFaadWrapper::OpenFile(string p_sFileName, CAudioDetails *pAudioDetails)
  475. {
  476. if((m_pFileHandle = fopen(p_sFileName.c_str(), "rb")) == NULL)
  477. {
  478. fprintf(stderr, "Cannot open %s\n", p_sFileName.c_str());
  479. return false;
  480. }
  481. #ifdef _WIN32
  482. _setmode(_fileno(m_pFileHandle), _O_BINARY);
  483. #endif
  484. fseek(m_pFileHandle, 0, SEEK_END);
  485. m_nFileLength = ftell(m_pFileHandle);
  486. m_nFileRest = m_nFileLength;
  487. fseek(m_pFileHandle, 0, SEEK_SET);
  488. m_nBufferSize = FAAD_MIN_STREAMSIZE * FAAD_MAX_CHANNELS;
  489. if(!(m_Buffer = (unsigned char *)malloc(m_nBufferSize)))
  490. {
  491. fprintf(stderr, "Memory allocation error\n");
  492. return false;
  493. }
  494. m_nBufferSize = fread(m_Buffer, 1, m_nBufferSize, m_pFileHandle);
  495. m_nFileRest -= m_nBufferSize;
  496. m_nBytesConsumed = 0;
  497. if(m_Buffer[4] == 'f' && m_Buffer[5] == 't' && m_Buffer[6] == 'y' && m_Buffer[7] == 'p')
  498. {
  499. printf("is mp4\n");
  500. m_bIsMp4 = true;
  501. first_time = true;
  502. fseek(m_pFileHandle, 0, SEEK_SET);
  503. #ifdef HAVE_MP4FF_H
  504. return InitMp4Decoder();
  505. #endif // HAVE_MP4FF_H
  506. }
  507. else
  508. {
  509. m_bIsMp4 = false;
  510. first_time = true;
  511. return InitAACDecoder();
  512. }
  513. return false;
  514. }
  515. void CFaadWrapper::CloseFile()
  516. {
  517. if(m_pFileHandle)
  518. {
  519. fclose(m_pFileHandle);
  520. }
  521. }
  522. long CFaadWrapper::DecodeInterleaved(char *p_PcmOut, int p_nBufferSize, int *p_nBytesRead)
  523. {
  524. if(m_bIsMp4)
  525. {
  526. #ifdef HAVE_MP4FF_H
  527. return DecodeMP4file(p_PcmOut);
  528. #else
  529. return -1;
  530. #endif // HAVE_MP4FF_H
  531. }
  532. else
  533. {
  534. return DecodeAACfile(p_PcmOut);
  535. }
  536. }
  537. unsigned int CFaadWrapper::NumPcmSamples()
  538. {
  539. printf("num samples %ld\n", numSamples);
  540. return 0; //numSamples;
  541. }
  542. void CFaadWrapper::FillBuffer()
  543. {
  544. int nRead = 0;
  545. if(m_nBytesConsumed > 0)
  546. {
  547. //printf("consumed %d bytes\n", m_nBytesConsumed);
  548. memmove(m_Buffer, &m_Buffer[m_nBytesConsumed], m_nBufferSize - m_nBytesConsumed);
  549. nRead = fread(&m_Buffer[m_nBufferSize - m_nBytesConsumed], 1, m_nBytesConsumed, m_pFileHandle);
  550. //printf("read %d bytes rest %d bytes\n", nRead, m_nFileRest);
  551. m_nFileRest -= nRead;
  552. if(nRead < m_nBytesConsumed)
  553. {
  554. m_nBufferSize = m_nBufferSize - m_nBytesConsumed + nRead;
  555. //printf("buffer size %d bytes\n", m_nBufferSize);
  556. }
  557. m_nBytesConsumed = 0;
  558. }
  559. }
  560. bool CFaadWrapper::InitAACDecoder()
  561. {
  562. unsigned long samplerate;
  563. //uint32_t samplerate;
  564. unsigned char channels;
  565. int header_type = 0;
  566. int bitrate = 0;
  567. float length = 0;
  568. hDecoder = m_faacDecOpen();
  569. config = m_faacDecGetCurrentConfiguration(hDecoder);
  570. config->defObjectType = LC;
  571. config->outputFormat = FAAD_FMT_16BIT;
  572. config->downMatrix = 1;
  573. config->useOldADTSFormat = 0;
  574. config->dontUpSampleImplicitSBR = 1;
  575. m_faacDecSetConfiguration(hDecoder, config);
  576. int tagsize = 0;
  577. if(!memcmp(m_Buffer, "ID3", 3))
  578. {
  579. // high bit is not used
  580. tagsize = (m_Buffer[6] << 21) | (m_Buffer[7] << 14) |
  581. (m_Buffer[8] << 7) | (m_Buffer[9] << 0);
  582. tagsize += 10;
  583. }
  584. // get AAC infos for printing
  585. header_type = 0;
  586. if ((m_Buffer[0] == 0xFF) && ((m_Buffer[1] & 0xF6) == 0xF0))
  587. {
  588. adts_parse(&bitrate, &length);
  589. fseek(m_pFileHandle, tagsize, SEEK_SET);
  590. m_nBufferSize = fread(m_Buffer, 1, FAAD_MIN_STREAMSIZE * FAAD_MAX_CHANNELS, m_pFileHandle);
  591. m_nFileRest = m_nFileLength - tagsize - FAAD_MIN_STREAMSIZE * FAAD_MAX_CHANNELS;
  592. header_type = 1;
  593. }
  594. else if (memcmp(m_Buffer, "ADIF", 4) == 0)
  595. {
  596. int skip_size = (m_Buffer[4] & 0x80) ? 9 : 0;
  597. bitrate = ((unsigned int)(m_Buffer[4 + skip_size] & 0x0F) << 19) |
  598. ((unsigned int)m_Buffer[5 + skip_size] << 11) |
  599. ((unsigned int)m_Buffer[6 + skip_size] << 3) |
  600. ((unsigned int)m_Buffer[7 + skip_size] & 0xE0);
  601. length = (float)m_nFileLength;
  602. if (length != 0)
  603. {
  604. length = ((float)length * 8.f) / ((float)bitrate) + 0.5f;
  605. }
  606. bitrate = (int)((float)bitrate / 1000.0f + 0.5f);
  607. header_type = 2;
  608. }
  609. if ((m_nBytesConsumed = m_faacDecInit(hDecoder, m_Buffer, m_nBufferSize, &samplerate, &channels)) < 0)
  610. {
  611. fprintf(stderr, "Error initializing decoder library.\n");
  612. return false;
  613. }
  614. FillBuffer();
  615. // print AAC file info
  616. switch (header_type)
  617. {
  618. case 0:
  619. fprintf(stderr, "RAW\n\n");
  620. break;
  621. case 1:
  622. fprintf(stderr, "ADTS, %.3f sec, %d kbps, %d Hz\n\n",
  623. length, bitrate, samplerate);
  624. break;
  625. case 2:
  626. fprintf(stderr, "ADIF, %.3f sec, %d kbps, %d Hz\n\n",
  627. length, bitrate, samplerate);
  628. break;
  629. }
  630. }
  631. #ifdef HAVE_MP4FF_H
  632. bool CFaadWrapper::InitMp4Decoder()
  633. {
  634. unsigned char channels;
  635. mp4AudioSpecificConfig mp4ASC;
  636. unsigned char *buffer;
  637. unsigned int buffer_size;
  638. // for gapless decoding
  639. useAacLength = 1;
  640. initial = 1;
  641. // initialise the callback structure
  642. mp4cb = (mp4ff_callback_t *)malloc(sizeof(mp4ff_callback_t));
  643. mp4cb->read = read_callback;
  644. mp4cb->seek = seek_callback;
  645. mp4cb->user_data = m_pFileHandle;
  646. hDecoder = m_faacDecOpen();
  647. // set configuration
  648. config = m_faacDecGetCurrentConfiguration(hDecoder);
  649. config->outputFormat = FAAD_FMT_16BIT;
  650. config->downMatrix = 1;
  651. config->dontUpSampleImplicitSBR = 1;
  652. m_faacDecSetConfiguration(hDecoder, config);
  653. infile = m_mp4ff_open_read(mp4cb);
  654. if (!infile)
  655. {
  656. // unable to open file
  657. fprintf(stderr, "Error opening input file\n");
  658. return false;
  659. }
  660. if ((track = GetAACTrack(infile)) < 0)
  661. {
  662. fprintf(stderr, "Unable to find correct AAC sound track in the MP4 file.\n");
  663. return false;
  664. }
  665. buffer = NULL;
  666. buffer_size = 0;
  667. m_mp4ff_get_decoder_config(infile, track, &buffer, &buffer_size);
  668. if(m_faacDecInit2(hDecoder, buffer, buffer_size, &samplerate, &channels) < 0)
  669. {
  670. // If some error initializing occured, skip the file
  671. fprintf(stderr, "Error initializing decoder library.\n");
  672. return false;
  673. }
  674. timescale = m_mp4ff_time_scale(infile, track);
  675. framesize = 1024;
  676. useAacLength = 0;
  677. if(buffer)
  678. {
  679. if (m_AudioSpecificConfig(buffer, buffer_size, &mp4ASC) >= 0)
  680. {
  681. if (mp4ASC.frameLengthFlag == 1)
  682. {
  683. framesize = 960;
  684. }
  685. if (mp4ASC.sbr_present_flag == 1)
  686. {
  687. framesize *= 2;
  688. }
  689. }
  690. free(buffer);
  691. }
  692. // print some mp4 file info
  693. fprintf(stderr, "input file info:\n\n");
  694. char *tag = NULL, *item = NULL;
  695. int k, j;
  696. char *ot[6] = { "NULL", "MAIN AAC", "LC AAC", "SSR AAC", "LTP AAC", "HE AAC" };
  697. long samples = m_mp4ff_num_samples(infile, track);
  698. float f = 1024.0;
  699. float seconds;
  700. if (mp4ASC.sbr_present_flag == 1)
  701. {
  702. f = f * 2.0;
  703. }
  704. seconds = (float)samples * (float)(f - 1.0) / (float)mp4ASC.samplingFrequency;
  705. fprintf(stderr, "%s\t%.3f secs, %d ch, %d Hz\n\n", ot[(mp4ASC.objectTypeIndex > 5) ? 0 : mp4ASC.objectTypeIndex],
  706. seconds, mp4ASC.channelsConfiguration, mp4ASC.samplingFrequency);
  707. numSamples = m_mp4ff_num_samples(infile, track);
  708. printf("num samples %d\n", numSamples);
  709. sampleId = 0;
  710. return true;
  711. }
  712. #endif // HAVE_MP4FF_H
  713. #endif // HAVE_FAAD
  714. #endif // DISABLE_TRANSCODING