Newer
Older
monitord / lame-3.97 / dshow / .svn / text-base / Encoder.cpp.svn-base
@root root on 23 Jan 2012 11 KB Migration from SVN revision 455
  1. /*
  2. * LAME MP3 encoder for DirectShow
  3. * LAME encoder wrapper
  4. *
  5. * Copyright (c) 2000-2005 Marie Orlova, Peter Gubanov, Vitaly Ivanov, Elecard Ltd.
  6. *
  7. * This library is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Library General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 2 of the License, or (at your option) any later version.
  11. *
  12. * This library is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Library General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Library General Public
  18. * License along with this library; if not, write to the
  19. * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  20. * Boston, MA 02111-1307, USA.
  21. */
  22.  
  23. #include <streams.h>
  24. #include "Encoder.h"
  25.  
  26.  
  27. //////////////////////////////////////////////////////////////////////
  28. // Construction/Destruction
  29. //////////////////////////////////////////////////////////////////////
  30. CEncoder::CEncoder() :
  31. m_bInpuTypeSet(FALSE),
  32. m_bOutpuTypeSet(FALSE),
  33. m_bFinished(FALSE),
  34. m_outOffset(0),
  35. m_outReadOffset(0),
  36. m_frameCount(0),
  37. pgf(NULL)
  38. {
  39. m_outFrameBuf = new unsigned char[OUT_BUFFER_SIZE];
  40. }
  41.  
  42. CEncoder::~CEncoder()
  43. {
  44. Close();
  45.  
  46. if (m_outFrameBuf)
  47. delete [] m_outFrameBuf;
  48. }
  49.  
  50. //////////////////////////////////////////////////////////////////////
  51. // SetInputType - check if given input type is supported
  52. //////////////////////////////////////////////////////////////////////
  53. HRESULT CEncoder::SetInputType(LPWAVEFORMATEX lpwfex, bool bJustCheck)
  54. {
  55. CAutoLock l(&m_lock);
  56.  
  57. if (lpwfex->wFormatTag == WAVE_FORMAT_PCM)
  58. {
  59. if (lpwfex->nChannels == 1 || lpwfex->nChannels == 2)
  60. {
  61. if (lpwfex->nSamplesPerSec == 48000 ||
  62. lpwfex->nSamplesPerSec == 44100 ||
  63. lpwfex->nSamplesPerSec == 32000 ||
  64. lpwfex->nSamplesPerSec == 24000 ||
  65. lpwfex->nSamplesPerSec == 22050 ||
  66. lpwfex->nSamplesPerSec == 16000 ||
  67. lpwfex->nSamplesPerSec == 12000 ||
  68. lpwfex->nSamplesPerSec == 11025 ||
  69. lpwfex->nSamplesPerSec == 8000)
  70. {
  71. if (lpwfex->wBitsPerSample == 16)
  72. {
  73. if (!bJustCheck)
  74. {
  75. memcpy(&m_wfex, lpwfex, sizeof(WAVEFORMATEX));
  76. m_bInpuTypeSet = true;
  77. }
  78.  
  79. return S_OK;
  80. }
  81. }
  82. }
  83. }
  84.  
  85. if (!bJustCheck)
  86. m_bInpuTypeSet = false;
  87.  
  88. return E_INVALIDARG;
  89. }
  90.  
  91. //////////////////////////////////////////////////////////////////////
  92. // SetOutputType - try to initialize encoder with given output type
  93. //////////////////////////////////////////////////////////////////////
  94. HRESULT CEncoder::SetOutputType(MPEG_ENCODER_CONFIG &mabsi)
  95. {
  96. CAutoLock l(&m_lock);
  97.  
  98. m_mabsi = mabsi;
  99. m_bOutpuTypeSet = true;
  100.  
  101. return S_OK;
  102. }
  103.  
  104. //////////////////////////////////////////////////////////////////////
  105. // SetDefaultOutputType - sets default MPEG audio properties according
  106. // to input type
  107. //////////////////////////////////////////////////////////////////////
  108. HRESULT CEncoder::SetDefaultOutputType(LPWAVEFORMATEX lpwfex)
  109. {
  110. CAutoLock l(&m_lock);
  111.  
  112. if(lpwfex->nChannels == 1 || m_mabsi.bForceMono)
  113. m_mabsi.ChMode = MONO;
  114.  
  115. if((lpwfex->nSamplesPerSec < m_mabsi.dwSampleRate) || (lpwfex->nSamplesPerSec % m_mabsi.dwSampleRate != 0))
  116. m_mabsi.dwSampleRate = lpwfex->nSamplesPerSec;
  117.  
  118. return S_OK;
  119. }
  120.  
  121. //////////////////////////////////////////////////////////////////////
  122. // Init - initialized or reiniyialized encoder SDK with given input
  123. // and output settings
  124. //////////////////////////////////////////////////////////////////////
  125. HRESULT CEncoder::Init()
  126. {
  127. CAutoLock l(&m_lock);
  128.  
  129. m_outOffset = 0;
  130. m_outReadOffset = 0;
  131.  
  132. m_bFinished = FALSE;
  133.  
  134. m_frameCount = 0;
  135.  
  136. if (!pgf)
  137. {
  138. if (!m_bInpuTypeSet || !m_bOutpuTypeSet)
  139. return E_UNEXPECTED;
  140.  
  141. // Init Lame library
  142. // note: newer, safer interface which doesn't
  143. // allow or require direct access to 'gf' struct is being written
  144. // see the file 'API' included with LAME.
  145. if (pgf = lame_init())
  146. {
  147. pgf->num_channels = m_wfex.nChannels;
  148.  
  149. pgf->in_samplerate = m_wfex.nSamplesPerSec;
  150. pgf->out_samplerate = m_mabsi.dwSampleRate;
  151. if ((pgf->out_samplerate >= 32000) && (m_mabsi.dwBitrate < 32))
  152. pgf->brate = 32;
  153. else
  154. pgf->brate = m_mabsi.dwBitrate;
  155.  
  156. pgf->VBR = m_mabsi.vmVariable;
  157. pgf->VBR_min_bitrate_kbps = m_mabsi.dwVariableMin;
  158. pgf->VBR_max_bitrate_kbps = m_mabsi.dwVariableMax;
  159.  
  160. pgf->copyright = m_mabsi.bCopyright;
  161. pgf->original = m_mabsi.bOriginal;
  162. pgf->error_protection = m_mabsi.bCRCProtect;
  163.  
  164. pgf->bWriteVbrTag = m_mabsi.dwXingTag;
  165. pgf->strict_ISO = m_mabsi.dwStrictISO;
  166. pgf->VBR_hard_min = m_mabsi.dwEnforceVBRmin;
  167.  
  168. if (pgf->num_channels == 2 && !m_mabsi.bForceMono)
  169. {
  170. int act_br = pgf->VBR ? pgf->VBR_min_bitrate_kbps + pgf->VBR_max_bitrate_kbps / 2 : pgf->brate;
  171.  
  172. // Disabled. It's for user's consideration now
  173. //int rel = pgf->out_samplerate / (act_br + 1);
  174. //pgf->mode = rel < 200 ? m_mabsi.ChMode : JOINT_STEREO;
  175.  
  176. pgf->mode = m_mabsi.ChMode;
  177. }
  178. else
  179. pgf->mode = MONO;
  180.  
  181. if (pgf->mode == JOINT_STEREO)
  182. pgf->force_ms = m_mabsi.dwForceMS;
  183. else
  184. pgf->force_ms = 0;
  185.  
  186. pgf->mode_fixed = m_mabsi.dwModeFixed;
  187.  
  188. if (m_mabsi.dwVoiceMode != 0)
  189. {
  190. pgf->lowpassfreq = 12000;
  191. pgf->VBR_max_bitrate_kbps = 160;
  192. }
  193.  
  194. if (m_mabsi.dwKeepAllFreq != 0)
  195. {
  196. pgf->lowpassfreq = -1;
  197. pgf->highpassfreq = -1;
  198. }
  199.  
  200. pgf->quality = m_mabsi.dwQuality;
  201. pgf->VBR_q = m_mabsi.dwVBRq;
  202.  
  203. lame_init_params(pgf);
  204.  
  205. // encoder delay compensation
  206. {
  207. short * start_padd = (short *)calloc(48, pgf->num_channels * sizeof(short));
  208.  
  209. if (pgf->num_channels == 2)
  210. lame_encode_buffer_interleaved(pgf, start_padd, 48, m_outFrameBuf, OUT_BUFFER_SIZE);
  211. else
  212. lame_encode_buffer(pgf, start_padd, start_padd, 48, m_outFrameBuf, OUT_BUFFER_SIZE);
  213.  
  214. free(start_padd);
  215. }
  216.  
  217. return S_OK;
  218. }
  219.  
  220. return E_FAIL;
  221. }
  222.  
  223. return S_OK;
  224. }
  225.  
  226. //////////////////////////////////////////////////////////////////////
  227. // Close - closes encoder
  228. //////////////////////////////////////////////////////////////////////
  229. HRESULT CEncoder::Close()
  230. {
  231. CAutoLock l(&m_lock);
  232.  
  233. if (pgf)
  234. {
  235. lame_close(pgf);
  236. pgf = NULL;
  237. }
  238.  
  239. return S_OK;
  240. }
  241.  
  242. //////////////////////////////////////////////////////////////////////
  243. // Encode - encodes data placed on pdata and returns
  244. // the number of processed bytes
  245. //////////////////////////////////////////////////////////////////////
  246. int CEncoder::Encode(const short * pdata, int data_size)
  247. {
  248. CAutoLock l(&m_lock);
  249.  
  250. if (!pgf || !m_outFrameBuf || !pdata || data_size < 0 || (data_size & (sizeof(short) - 1)))
  251. return -1;
  252.  
  253. // some data left in the buffer, shift to start
  254. if (m_outReadOffset > 0)
  255. {
  256. if (m_outOffset > m_outReadOffset)
  257. memmove(m_outFrameBuf, m_outFrameBuf + m_outReadOffset, m_outOffset - m_outReadOffset);
  258.  
  259. m_outOffset -= m_outReadOffset;
  260. }
  261.  
  262. m_outReadOffset = 0;
  263.  
  264.  
  265.  
  266. m_bFinished = FALSE;
  267.  
  268. int bytes_processed = 0;
  269.  
  270. while (1)
  271. {
  272. int nsamples = (data_size - bytes_processed) / (sizeof(short) * pgf->num_channels);
  273.  
  274. if (nsamples <= 0)
  275. break;
  276.  
  277. if (nsamples > 1152)
  278. nsamples = 1152;
  279.  
  280. if (m_outOffset >= OUT_BUFFER_MAX)
  281. break;
  282.  
  283. int out_bytes = 0;
  284.  
  285. if (pgf->num_channels == 2)
  286. out_bytes = lame_encode_buffer_interleaved(
  287. pgf,
  288. (short *)(pdata + (bytes_processed / sizeof(short))),
  289. nsamples,
  290. m_outFrameBuf + m_outOffset,
  291. OUT_BUFFER_SIZE - m_outOffset);
  292. else
  293. out_bytes = lame_encode_buffer(
  294. pgf,
  295. pdata + (bytes_processed / sizeof(short)),
  296. pdata + (bytes_processed / sizeof(short)),
  297. nsamples,
  298. m_outFrameBuf + m_outOffset,
  299. OUT_BUFFER_SIZE - m_outOffset);
  300.  
  301. if (out_bytes < 0)
  302. return -1;
  303.  
  304. m_outOffset += out_bytes;
  305. bytes_processed += nsamples * pgf->num_channels * sizeof(short);
  306. }
  307.  
  308. return bytes_processed;
  309. }
  310.  
  311. //
  312. // Finsh - flush the buffered samples
  313. //
  314. HRESULT CEncoder::Finish()
  315. {
  316. CAutoLock l(&m_lock);
  317.  
  318. if (!pgf || !m_outFrameBuf || (m_outOffset >= OUT_BUFFER_MAX))
  319. return E_FAIL;
  320.  
  321. m_outOffset += lame_encode_flush(pgf, m_outFrameBuf + m_outOffset, OUT_BUFFER_SIZE - m_outOffset);
  322.  
  323. m_bFinished = TRUE;
  324.  
  325. return S_OK;
  326. }
  327.  
  328.  
  329. int getFrameLength(const unsigned char * pdata)
  330. {
  331. if (!pdata || pdata[0] != 0xff || (pdata[1] & 0xe0) != 0xe0)
  332. return -1;
  333.  
  334. const int sample_rate_tab[4][4] =
  335. {
  336. {11025,12000,8000,1},
  337. {1,1,1,1},
  338. {22050,24000,16000,1},
  339. {44100,48000,32000,1}
  340. };
  341.  
  342. #define MPEG_VERSION_RESERVED 1
  343. #define MPEG_VERSION_1 3
  344.  
  345. #define LAYER_III 1
  346.  
  347. #define BITRATE_FREE 0
  348. #define BITRATE_RESERVED 15
  349.  
  350. #define SRATE_RESERVED 3
  351.  
  352. #define EMPHASIS_RESERVED 2
  353.  
  354. int version_id = (pdata[1] & 0x18) >> 3;
  355. int layer = (pdata[1] & 0x06) >> 1;
  356. int bitrate_id = (pdata[2] & 0xF0) >> 4;
  357. int sample_rate_id = (pdata[2] & 0x0C) >> 2;
  358. int padding = (pdata[2] & 0x02) >> 1;
  359. int emphasis = pdata[3] & 0x03;
  360.  
  361. if (version_id != MPEG_VERSION_RESERVED &&
  362. layer == LAYER_III &&
  363. bitrate_id != BITRATE_FREE &&
  364. bitrate_id != BITRATE_RESERVED &&
  365. sample_rate_id != SRATE_RESERVED &&
  366. emphasis != EMPHASIS_RESERVED)
  367. {
  368. int spf = (version_id == MPEG_VERSION_1) ? 1152 : 576;
  369. int sample_rate = sample_rate_tab[version_id][sample_rate_id];
  370. int bitrate = dwBitRateValue[version_id != MPEG_VERSION_1][bitrate_id - 1] * 1000;
  371.  
  372. return (bitrate * spf) / (8 * sample_rate) + padding;
  373. }
  374.  
  375. return -1;
  376. }
  377.  
  378.  
  379. int CEncoder::GetFrame(const unsigned char ** pframe)
  380. {
  381. if (!pgf || !m_outFrameBuf || !pframe)
  382. return -1;
  383.  
  384. while ((m_outOffset - m_outReadOffset) > 4)
  385. {
  386. int frame_length = getFrameLength(m_outFrameBuf + m_outReadOffset);
  387.  
  388. if (frame_length < 0)
  389. {
  390. m_outReadOffset++;
  391. }
  392. else if (frame_length <= (m_outOffset - m_outReadOffset))
  393. {
  394. *pframe = m_outFrameBuf + m_outReadOffset;
  395. m_outReadOffset += frame_length;
  396.  
  397. m_frameCount++;
  398.  
  399. // don't deliver the first and the last frames
  400. if (m_frameCount != 1 && !(m_bFinished && (m_outOffset - m_outReadOffset) < 5))
  401. return frame_length;
  402. }
  403. else
  404. break;
  405. }
  406.  
  407. return 0;
  408. }
  409.  
  410.  
  411.  
  412.  
  413.  
  414.  
  415.  
  416.  
  417.  
  418.  
  419.  
  420.  
  421.  
  422.  
  423.  
  424.  
  425.  
  426.  
  427.  
  428.  
  429.