⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mpegaudiodecoder.cc

📁 Linux下比较早的基于命令行的DVD播放器
💻 CC
字号:
//// Copyright (c) 2003 by Istv醤 V醨adi//// This file is part of dxr3Player, a DVD player written specifically // for the DXR3 (aka Hollywood+) decoder card.// This program is free software; you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation; either version 2 of the License, or// (at your option) any later version.//// This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the// GNU General Public License for more details.//// You should have received a copy of the GNU General Public License// along with this program; if not, write to the Free Software// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA//------------------------------------------------------------------------------#include "MPEGAudioDecoder.h"#include "AudioProcessor.h"#include "util/Log.h"#include <cstring>#include <cassert>//------------------------------------------------------------------------------using output::MPEGAudioDecoder;//------------------------------------------------------------------------------const size_t MPEGAudioDecoder::bitrateTable[2][3][16] = {    // MPEG 2.5    {        // Layer III        {                0,   8000,  16000,  24000,              32000,  40000,  48000,  56000,            64000,  80000,  96000, 112000,            128000, 144000, 160000,      0         },        // Layer II        {                0,   8000,  16000,  24000,              32000,  40000,  48000,  56000,            64000,  80000,  96000, 112000,            128000, 144000, 160000,      0         },        // Layer I        {                0,  32000,  48000,  56000,              64000,  80000,  96000, 112000,            128000, 144000, 160000, 176000,            192000, 224000, 256000,      0         }    },    // MPEG 1, MPEG 2    {        // Layer III        {                      0,  32000,  40000,  48000,              56000,  64000,  80000,  96000,            112000, 128000, 160000, 192000,            224000, 256000, 320000,      0        },        // Layer II        {                       0,  32000,  48000,  56000,              64000,  80000,  96000, 112000,           128000, 160000, 192000, 224000,            256000, 320000, 384000,      0         },        // Layer I        {                      0,  32000,  64000,  96000,            128000, 160000, 192000, 224000,            256000, 288000, 320000, 352000,            384000, 416000, 448000,      0         }    },};//------------------------------------------------------------------------------const size_t MPEGAudioDecoder::sampleRateTable[3] = { 11025, 12000, 8000 };//------------------------------------------------------------------------------inline MPEGAudioDecoder::sampleType MPEGAudioDecoder::convertSample(mad_fixed_t sample){    return sample >> (MAD_F_FRACBITS-15);}//------------------------------------------------------------------------------//------------------------------------------------------------------------------inline bool MPEGAudioDecoder::isEmpty() const{    return frameOffset==0;}//------------------------------------------------------------------------------//------------------------------------------------------------------------------MPEGAudioDecoder::MPEGAudioDecoder(AudioProcessor* audioProcessor) :    AudioDecoder(*audioProcessor),    frameOffset(0),    frameLength((size_t)-1){    reset();}//------------------------------------------------------------------------------void MPEGAudioDecoder::reset(){    mad_stream_init(&madStream);    mad_frame_init(&madFrame);    mad_synth_init(&madSynth);}//------------------------------------------------------------------------------void MPEGAudioDecoder::decodePacket(const unsigned char* data,                                    size_t length, pts_t packetPTS){    const unsigned char* end = data + length;    size_t offset = 0;    while(offset<length && !audioProcessor.isInterrupted()) {        const unsigned char* start = data + offset;        if (isEmpty()) {            audioProcessor.transferPTS(packetPTS);        }        bool hasFrame = decode(start, end);        offset = start - data;                if (hasFrame) {            audioProcessor.outputPacket();        }    }    }//------------------------------------------------------------------------------bool MPEGAudioDecoder::decode(const unsigned char*& data,                               const unsigned char* end){    while(data<end) {        while(data<end && frameOffset<2) {            if ( (frameOffset==0 && *data==0xff) ||                 (frameOffset==1 && ((*data)&0xe0)==0xe0))             {                frameBuffer[frameOffset] = *data;                ++frameOffset;            } else {                frameOffset = 0;            }            ++data;        }        while(data<end && frameOffset>=2 && frameOffset<=3) {            frameBuffer[frameOffset] = *data;            ++frameOffset;            ++data;        }        if (data>=end) return false;        if (frameOffset==4) {            frameLength = getFrameLength();                        if (frameLength<4) {                Log::error("output::MPEGAudioDecoder::decode: invalid frame");                frameOffset = 0;            }            assert(frameLength<=frameBufferSize);        }        if ( frameOffset>=4 && frameOffset<frameLength) {            copy(data, end, frameLength);        }                if (frameOffset==frameLength) {            bool frameValid = decodeFrame();            frameOffset = 0;            frameLength = (size_t)-1;                        if (frameValid) return true;        }    }    return false;}//------------------------------------------------------------------------------size_t MPEGAudioDecoder::getFrameLength(){    assert(frameOffset>=4);    unsigned versionID = (frameBuffer[1]>>3)&0x03;    unsigned layerIndex = (frameBuffer[1]>>1)&0x03;    if (layerIndex==0) return 0;    unsigned bitrateIndex = (frameBuffer[2]>>4)&0x0f;    unsigned bitrate =         bitrateTable[(versionID>>1)&0x01][layerIndex-1][bitrateIndex];           unsigned sampleRateIndex = (frameBuffer[2]>>2)&0x03;    if (sampleRateIndex>2) return 0;        unsigned sampleRate = sampleRateTable[sampleRateIndex];    if (versionID==2) sampleRate *= 2;    else if (versionID==3) sampleRate *= 4;    size_t padding = (frameBuffer[2]>>1)&0x01;    size_t length = 0;    if (layerIndex==3) { // Layer I        length = ((12 * bitrate / sampleRate)+padding)*4;    } else {        size_t slots = (layerIndex==1 && versionID<2) ? 72 : 144;         // Layer III && MPEG 2.5        length = (slots*bitrate/sampleRate) + padding;    }    Log::verboseDebug("output::MPEGAudioDecoder::getFrameLength: header data: versionID=%u, layerIndex=%u, bitrateIndex=%u, sampleRateIndex=%u\n",                      versionID, layerIndex, bitrateIndex, sampleRateIndex);    Log::verboseDebug("output::MPEGAudioDecoder::getFrameLength: header data: bitrate=%u, sampleRate=%u, padding=%u, length=%u\n",                      bitrate, sampleRate, padding, length);        AudioFormat& format = audioProcessor.getOutputFormat();    format.encoding = LPCM_LE;    format.numberOfChannels = 2;    format.sampleRate = sampleRate;        return length;}//------------------------------------------------------------------------------void MPEGAudioDecoder::copy(const unsigned char*& data,                            const unsigned char* end,                            size_t targetOffset){    unsigned tocopy      = targetOffset - frameOffset;    unsigned blockLength = end - data;        if (tocopy>blockLength) tocopy = blockLength;    memcpy(frameBuffer + frameOffset, data, tocopy);    frameOffset += tocopy;    data += tocopy;    assert(data<=end);}//------------------------------------------------------------------------------bool MPEGAudioDecoder::decodeFrame(){    mad_stream_buffer(&madStream, frameBuffer, frameLength+MAD_BUFFER_GUARD);        if (mad_header_decode(&madFrame.header, &madStream) ||        mad_frame_decode(&madFrame, &madStream))     {        if (MAD_RECOVERABLE(madStream.error)) {            Log::warning("output::MPEGAudioDecoder::decoder: recoverable frame error: %d\n", madStream.error);        } else if (madStream.error!=MAD_ERROR_BUFLEN) {            Log::error("output::MPEGAudioDecoder::decoder: unrecoverable frame error: %d\n", madStream.error);        } else {            Log::warning("output::MPEGAudioDecoder::decoder: MAD_ERROR_BUFLEN\n");        }        reset();                return false;    }    synthesizeFrame();    return true;}//------------------------------------------------------------------------------void MPEGAudioDecoder::synthesizeFrame(){    mad_synth_frame(&madSynth, &madFrame);    assert(madSynth.pcm.length<=maxOutputSamples);    sampleType* output =         reinterpret_cast<sampleType*>(audioProcessor.getOutputBuffer());    for(size_t i = 0; i<madSynth.pcm.length; ++i, output += 2) {        sampleType leftSample = convertSample(madSynth.pcm.samples[0][i]);        output[0] = leftSample;                if (MAD_NCHANNELS(&madFrame.header)==2) {            output[1] = convertSample(madSynth.pcm.samples[1][i]);        } else {            output[1] = leftSample;        }    }    audioProcessor.setOutputLength(madSynth.pcm.length * sampleSize);}//------------------------------------------------------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -