home *** CD-ROM | disk | FTP | other *** search
/ Computer Shopper 275 / DPCS0111DVD.ISO / Toolkit / Audio-Visual / VirtualDub / Source / VirtualDub-1.9.10-src.7z / src / Riza / source / ac_mpeg.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2009-09-14  |  12.3 KB  |  487 lines

  1. //    VirtualDub - Video processing and capture application
  2. //    A/V interface library
  3. //    Copyright (C) 1998-2007 Avery Lee
  4. //
  5. //    This program is free software; you can redistribute it and/or modify
  6. //    it under the terms of the GNU General Public License as published by
  7. //    the Free Software Foundation; either version 2 of the License, or
  8. //    (at your option) any later version.
  9. //
  10. //    This program is distributed in the hope that it will be useful,
  11. //    but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. //    GNU General Public License for more details.
  14. //
  15. //    You should have received a copy of the GNU General Public License
  16. //    along with this program; if not, write to the Free Software
  17. //    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  
  19. #include <vd2/system/VDRingBuffer.h>
  20. #include <vd2/system/vdstl.h>
  21. #include <vd2/system/vdalloc.h>
  22. #include <vd2/system/math.h>
  23. #include <vd2/Riza/audiocodec.h>
  24. #include <vd2/Priss/decoder.h>
  25.  
  26. class VDAudioDecompressorMPEG : public IVDAudioCodec, public IVDMPEGAudioBitsource {
  27. public:
  28.     VDAudioDecompressorMPEG();
  29.     ~VDAudioDecompressorMPEG();
  30.  
  31.     bool Init(const VDWaveFormat *srcFormat, const VDWaveFormat *dstFormat, bool doALaw);
  32.     void Shutdown();
  33.  
  34.     bool IsEnded() const;
  35.  
  36.     unsigned    GetInputLevel() const;
  37.     unsigned    GetInputSpace() const;
  38.     unsigned    GetOutputLevel() const;
  39.     const VDWaveFormat *GetOutputFormat() const;
  40.     unsigned    GetOutputFormatSize() const;
  41.  
  42.     void        Restart();
  43.     bool        Convert(bool flush, bool requireOutput);
  44.  
  45.     void        *LockInputBuffer(unsigned& bytes);
  46.     void        UnlockInputBuffer(unsigned bytes);
  47.     const void    *LockOutputBuffer(unsigned& bytes);
  48.     void        UnlockOutputBuffer(unsigned bytes);
  49.     unsigned    CopyOutput(void *dst, unsigned bytes);
  50.  
  51. protected:
  52.     int            read(void *buffer, int bytes);
  53.  
  54.     bool    mbEnded;
  55.     uint32    mSamplesPerFrameL1L2;        // 576 or 1152 * channels
  56.     uint32    mSamplesPerFrameL3;
  57.     uint32    mSamplesInNextFrame;
  58.     uint32    mDiscardedBytes;
  59.     uint32    mFillSamples;
  60.     double    mDstToSrcDataRatio;
  61.  
  62.     enum {
  63.         kHeaderCheckMask = 0xFFF80C00        // check sync, MPEG-2.5 (sync 11), MPEG-2 (id), and sampling rate bits
  64.     };
  65.  
  66.     uint32    mHeaderCheckValue;
  67.  
  68.     enum State {
  69.         kStateHeader,
  70.         kStateFill,
  71.         kStateData
  72.     } mState;
  73.  
  74.     vdautoptr<IVDMPEGAudioDecoder>    mpDecoder;
  75.  
  76.     vdfastvector<uint8>        mInputBuffer;
  77.     uint32                    mInputBufferReadPt;
  78.     uint32                    mInputBufferWritePt;
  79.     uint32                    mInputBufferHighWatermark;
  80.     VDRingBuffer<sint16>    mOutputBuffer;
  81.     vdstructex<VDWaveFormat>    mSrcFormat;
  82.     vdstructex<VDWaveFormat>    mDstFormat;
  83.  
  84.     sint16 mDecodeBuffer[1152 * 2];
  85. };
  86.  
  87. IVDAudioCodec *VDCreateAudioDecompressorMPEG(const VDWaveFormat *srcFormat, const VDWaveFormat *dstFormat) {
  88.     vdautoptr<VDAudioDecompressorMPEG> codec(new VDAudioDecompressorMPEG);
  89.  
  90.     if (!codec->Init(srcFormat, dstFormat, false))
  91.         return NULL;
  92.  
  93.     return codec.release();
  94. }
  95.  
  96. VDAudioDecompressorMPEG::VDAudioDecompressorMPEG()
  97.     : mbEnded(false)
  98.     , mDiscardedBytes(0)
  99.     , mFillSamples(0)
  100.     , mSamplesPerFrameL1L2(0)
  101.     , mSamplesPerFrameL3(0)
  102.     , mSamplesInNextFrame(0)
  103.     , mState(kStateHeader)
  104.     , mpDecoder(VDCreateMPEGAudioDecoder())
  105. {
  106.     mpDecoder->SetSource(this);
  107.     mpDecoder->Init();
  108. }
  109.  
  110. VDAudioDecompressorMPEG::~VDAudioDecompressorMPEG() {
  111. }
  112.  
  113. bool VDAudioDecompressorMPEG::Init(const VDWaveFormat *srcFormat, const VDWaveFormat *dstFormat, bool doALaw) {
  114.     if (srcFormat->mTag != VDWaveFormat::kTagMPEGLayer3 && srcFormat->mTag != VDWaveFormat::kTagMPEG1)
  115.         return false;
  116.  
  117.     // validate incoming sampling rate
  118.     bool is_mpeg2 = false;
  119.     bool is_mpeg25 = false;
  120.     int samplingRateCode = 0;
  121.  
  122.     switch(srcFormat->mSamplingRate) {
  123.         case 8000:
  124.             is_mpeg2 = true;
  125.             is_mpeg25 = true;
  126.             samplingRateCode = 2;
  127.             break;
  128.  
  129.         case 11025:
  130.             is_mpeg2 = true;
  131.             is_mpeg25 = true;
  132.             samplingRateCode = 0;
  133.             break;
  134.  
  135.         case 12000:
  136.             is_mpeg2 = true;
  137.             is_mpeg25 = true;
  138.             samplingRateCode = 1;
  139.             break;
  140.  
  141.         case 16000:
  142.             is_mpeg2 = true;
  143.             is_mpeg25 = false;
  144.             samplingRateCode = 2;
  145.             break;
  146.  
  147.         case 22050:
  148.             is_mpeg2 = true;
  149.             is_mpeg25 = false;
  150.             samplingRateCode = 0;
  151.             break;
  152.  
  153.         case 24000:
  154.             is_mpeg2 = true;
  155.             is_mpeg25 = false;
  156.             samplingRateCode = 1;
  157.             break;
  158.  
  159.         case 32000:
  160.             is_mpeg2 = false;
  161.             is_mpeg25 = false;
  162.             samplingRateCode = 2;
  163.             break;
  164.  
  165.         case 44100:
  166.             is_mpeg2 = false;
  167.             is_mpeg25 = false;
  168.             samplingRateCode = 0;
  169.             break;
  170.  
  171.         case 48000:
  172.             is_mpeg2 = false;
  173.             is_mpeg25 = false;
  174.             samplingRateCode = 1;
  175.             break;
  176.     }
  177.  
  178.     if (srcFormat->mChannels != 1 && srcFormat->mChannels != 2)
  179.         return false;
  180.  
  181.     if (dstFormat) {
  182.         if (dstFormat->mTag != VDWaveFormat::kTagPCM)
  183.             return false;
  184.  
  185.         if (dstFormat->mChannels != srcFormat->mChannels)
  186.             return false;
  187.  
  188.         if (dstFormat->mSamplingRate != srcFormat->mSamplingRate)
  189.             return false;
  190.  
  191.         if (dstFormat->mSampleBits == 16) {
  192.             if (dstFormat->mBlockSize != dstFormat->mChannels * 2)
  193.                 return false;
  194.  
  195.             if (dstFormat->mDataRate != dstFormat->mChannels * dstFormat->mSamplingRate * 2)
  196.                 return false;
  197.         } else {
  198.             return false;
  199.         }
  200.  
  201.         mDstFormat.assign(dstFormat, sizeof(VDWaveFormat) + dstFormat->mExtraSize);
  202.     } else {
  203.         mDstFormat.resize(sizeof(VDWaveFormat));
  204.         mDstFormat->mTag = VDWaveFormat::kTagPCM;
  205.         mDstFormat->mChannels = srcFormat->mChannels;
  206.         mDstFormat->mSamplingRate = srcFormat->mSamplingRate;
  207.         mDstFormat->mSampleBits = 16;
  208.         mDstFormat->mBlockSize = 2 * srcFormat->mChannels;
  209.         mDstFormat->mDataRate = mDstFormat->mBlockSize * mDstFormat->mSamplingRate;
  210.         mDstFormat->mExtraSize = 0;
  211.     }
  212.  
  213.     mSamplesPerFrameL1L2    = 1152 * mDstFormat->mChannels;
  214.     mSamplesPerFrameL3        = 576 * mDstFormat->mChannels;
  215.     if (mDstFormat->mSamplingRate >= 32000)
  216.         mSamplesPerFrameL3 <<= 1;
  217.  
  218.     mSrcFormat.assign(srcFormat, sizeof(VDWaveFormat) + srcFormat->mExtraSize);
  219.  
  220.     mDstToSrcDataRatio = (double)mDstFormat->mDataRate / (double)mSrcFormat->mDataRate;
  221.  
  222.     mInputBuffer.resize(65536);
  223.     mInputBufferHighWatermark = 0xe000;
  224.     mInputBufferReadPt = 0;
  225.     mInputBufferWritePt = 0;
  226.  
  227.     mOutputBuffer.Init(1152 * mDstFormat->mBlockSize);
  228.  
  229.     mHeaderCheckValue = 0xFFE00000;
  230.  
  231.     if (!is_mpeg25)
  232.         mHeaderCheckValue |= 0x00100000;
  233.  
  234.     if (!is_mpeg2)
  235.         mHeaderCheckValue |= 0x00080000;
  236.  
  237.     mHeaderCheckValue |= samplingRateCode << 10;
  238.  
  239.     return true;
  240. }
  241.  
  242. void VDAudioDecompressorMPEG::Shutdown() {
  243.     mSrcFormat.clear();
  244.     mDstFormat.clear();
  245.     mInputBuffer.clear();
  246.     mOutputBuffer.Shutdown();
  247.     mpDecoder = NULL;
  248. }
  249.  
  250. bool VDAudioDecompressorMPEG::IsEnded() const {
  251.     return mbEnded;
  252. }
  253.  
  254. unsigned VDAudioDecompressorMPEG::GetInputLevel() const {
  255.     return mInputBufferWritePt - mInputBufferReadPt;
  256. }
  257.  
  258. unsigned VDAudioDecompressorMPEG::GetInputSpace() const {
  259.     return mInputBuffer.size() - mInputBufferWritePt;
  260. }
  261.  
  262. unsigned VDAudioDecompressorMPEG::GetOutputLevel() const {
  263.     return mOutputBuffer.getLevel();
  264. }
  265.  
  266. const VDWaveFormat *VDAudioDecompressorMPEG::GetOutputFormat() const {
  267.     return mDstFormat.data();
  268. }
  269.  
  270. unsigned VDAudioDecompressorMPEG::GetOutputFormatSize() const {
  271.     return mDstFormat.size();
  272. }
  273.  
  274. void VDAudioDecompressorMPEG::Restart() {
  275.     mInputBufferReadPt = 0;
  276.     mInputBufferWritePt = 0;
  277.     mOutputBuffer.Flush();
  278.     mbEnded = false;
  279.     mState = kStateHeader;
  280.     mpDecoder->Reset();
  281.     mDiscardedBytes = 0;
  282.     mFillSamples = 0;
  283. }
  284.  
  285. bool VDAudioDecompressorMPEG::Convert(bool flush, bool requireOutput) {
  286.     bool didSomething = false;
  287.  
  288.     for(;;) {
  289.         if (mState == kStateHeader) {
  290.             int actual = mInputBufferWritePt - mInputBufferReadPt;
  291.             int readpt = mInputBufferReadPt;
  292.             const uint8 *src = mInputBuffer.data();
  293.  
  294.             // shift in bytes until we see a valid header (this will always be at
  295.             // least four bytes).
  296.             const int size = mInputBuffer.size();
  297.             uint32 hdr = 0;
  298.             int i = 0;
  299.             bool valid = false;
  300.  
  301.             while(i < actual) {
  302.                 ++i;
  303.                 hdr = (hdr << 8) + src[readpt++];
  304.                 if (readpt >= size)
  305.                     readpt = 0;
  306.  
  307.                 if ((hdr & kHeaderCheckMask) == mHeaderCheckValue) {
  308.                     // MPEG-1.5 isn't valid
  309.                     if ((hdr & 0x00180000) == 0x00080000)
  310.                         continue;
  311.  
  312.                     // check for valid bitrate
  313.                     if (!(hdr & 0x0000F000))
  314.                         continue;
  315.  
  316.                     // check for valid layer
  317.                     if ((hdr & 0x00060000) == 0)
  318.                         continue;
  319.  
  320.                     // check for layer III
  321.                     if ((hdr & 0x00060000) == 0x00020000)
  322.                         mSamplesInNextFrame = mSamplesPerFrameL3;
  323.                     else
  324.                         mSamplesInNextFrame = mSamplesPerFrameL1L2;
  325.  
  326.                     // all good
  327.                     valid = true;
  328.                     break;
  329.                 }
  330.             }
  331.  
  332.             // consume unused bytes
  333.             if (i > 4) {
  334.                 didSomething = true;
  335.                 mInputBufferReadPt += (i - 4);
  336.                 mDiscardedBytes += (i-4);
  337.             }
  338.  
  339.             if (valid) {
  340.                 didSomething = true;
  341.                 try {
  342.                     mpDecoder->ReadHeader();
  343.  
  344.                     if (mDiscardedBytes) {
  345.                         mFillSamples = (uint32)VDRoundToInt64((double)mDiscardedBytes * mDstToSrcDataRatio * 0.5);
  346.                         mFillSamples -= mFillSamples % mDstFormat->mChannels;
  347.                         mDiscardedBytes = 0;
  348.                     }
  349.  
  350.                 } catch(int) {
  351.                     mDiscardedBytes += 4;
  352.                     break;
  353.                 }
  354.  
  355.                 if (mFillSamples)
  356.                     mState = kStateFill;
  357.                 else
  358.                     mState = kStateData;
  359.             } else
  360.                 break;
  361.         } else if (mState == kStateFill) {
  362.             if (!mFillSamples) {
  363.                 mState = kStateData;
  364.                 didSomething = true;
  365.                 continue;
  366.             }
  367.  
  368.             int actual;
  369.             sint16 *dst = mOutputBuffer.LockWrite(VDClampToSint32(mFillSamples), actual);
  370.  
  371.             if (!actual)
  372.                 break;
  373.  
  374.             didSomething = true;
  375.             memset(dst, 0, sizeof(dst[0]) * actual);
  376.             mOutputBuffer.UnlockWrite(actual);
  377.             mFillSamples -= actual;
  378.         } else {
  379.             // check that we have enough room for the destination frame
  380.             if (mOutputBuffer.getSpace() < (int)mSamplesInNextFrame)
  381.                 break;
  382.  
  383.             // check that we have enough source bytes to feed the decoder
  384.             uint32 dataSize = mpDecoder->GetFrameDataSize();
  385.  
  386.             if (mInputBufferWritePt - mInputBufferReadPt < (int)dataSize)
  387.                 break;
  388.  
  389.             // decode the frame
  390.             didSomething = true;
  391.  
  392.             mpDecoder->SetDestination(mDecodeBuffer);
  393.  
  394.             int samples = 0;
  395.             int samplesToFill = (int)mSamplesInNextFrame;
  396.             uint32 saveReadPt = mInputBufferReadPt;
  397.             try {
  398.                 if (mpDecoder->DecodeFrame()) {
  399.                     samples = mpDecoder->GetSampleCount();
  400.                 } else {
  401.                     // Nothing wrong with the frame, but not enough bits in the bit reservoir to decode it.
  402.                     // Just conceal the frame, but don't discard bits.
  403.                     mpDecoder->ConcealFrame();
  404.                 }
  405.             } catch(int) {
  406.                 mpDecoder->ConcealFrame();
  407.  
  408.                 // rewind read
  409.                 mInputBufferReadPt = saveReadPt;
  410.  
  411.                 // mark header for bad frame as discarded
  412.                 mDiscardedBytes += 4;
  413.  
  414.                 // don't output samples
  415.                 samplesToFill = 0;
  416.             }
  417.  
  418.             if (samples < samplesToFill)
  419.                 memset(mDecodeBuffer + samples, 0, (samplesToFill - samples)*sizeof(sint16));
  420.  
  421.             mOutputBuffer.Write(mDecodeBuffer, samplesToFill);
  422.  
  423.             mState = kStateHeader;
  424.         }
  425.     }
  426.  
  427.     if (!didSomething && flush && mInputBufferWritePt == mInputBufferReadPt && mOutputBuffer.empty())
  428.         mbEnded = true;
  429.  
  430.     if (mInputBufferReadPt >= mInputBufferHighWatermark) {
  431.         uint8 *p = mInputBuffer.data();
  432.         memmove(p, p + mInputBufferReadPt, mInputBufferWritePt - mInputBufferReadPt);
  433.         mInputBufferWritePt -= mInputBufferReadPt;
  434.         mInputBufferReadPt = 0;
  435.     }
  436.  
  437.     return didSomething;
  438. }
  439.  
  440. void *VDAudioDecompressorMPEG::LockInputBuffer(unsigned& bytes) {
  441.     bytes = mInputBuffer.size() - mInputBufferWritePt;
  442.     return mInputBuffer.data() + mInputBufferWritePt;
  443. }
  444.  
  445. void VDAudioDecompressorMPEG::UnlockInputBuffer(unsigned bytes) {
  446.     mInputBufferWritePt += bytes;
  447.     VDASSERT(mInputBufferWritePt <= mInputBuffer.size());
  448. }
  449.  
  450. const void *VDAudioDecompressorMPEG::LockOutputBuffer(unsigned& bytes) {
  451.     int actual;
  452.     const sint16 *p = mOutputBuffer.LockReadAll(actual);
  453.     bytes = actual << 1;
  454.     return p;
  455. }
  456.  
  457. void VDAudioDecompressorMPEG::UnlockOutputBuffer(unsigned bytes) {
  458.     VDASSERT(!(bytes & 1));
  459.     mOutputBuffer.UnlockRead(bytes >> 1);
  460. }
  461.  
  462. unsigned VDAudioDecompressorMPEG::CopyOutput(void *dst, unsigned bytes) {
  463.     uint32 samples = bytes >> 1;
  464.     if (!dst) {
  465.         int actual;
  466.         mOutputBuffer.LockRead(samples, actual);
  467.         mOutputBuffer.UnlockRead(actual);
  468.         return actual * 2;
  469.     }
  470.  
  471.     return mOutputBuffer.Read((sint16 *)dst, samples) * 2;
  472. }
  473.  
  474. int VDAudioDecompressorMPEG::read(void *buffer, int bytes) {
  475.     int maxread = mInputBufferWritePt - mInputBufferReadPt;
  476.  
  477.     if (bytes > maxread)
  478.         bytes = maxread;
  479.  
  480.     if (bytes) {
  481.         memcpy(buffer, mInputBuffer.data() + mInputBufferReadPt, bytes);
  482.         mInputBufferReadPt += bytes;
  483.     }
  484.  
  485.     return bytes;
  486. }
  487.