📄 dtsdecoder.cc
字号:
//// Copyright (c) 2004 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 "DTSDecoder.h"#include "AudioProcessor.h"// This is needed for GCC 2.95, otherwise it is declared // in <unistd.h>extern "C" {void swab(const void* from, void* to, ssize_t n);}//------------------------------------------------------------------------------using output::DTSDecoder;//------------------------------------------------------------------------------inline bool DTSDecoder::isEmpty() const{ return frameOffset==0;}//------------------------------------------------------------------------------DTSDecoder::DTSDecoder(AudioProcessor* audioProcessor) : AudioDecoder(*audioProcessor), frameOffset(0), frameLength((size_t)-1){}//------------------------------------------------------------------------------void DTSDecoder::reset(){ frameOffset = 0; frameLength = (size_t)-1;}//------------------------------------------------------------------------------void DTSDecoder::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 DTSDecoder::decode(const unsigned char*& data, const unsigned char* end){ static const unsigned char syncWord[4] = { 0x7f, 0xfe, 0x80, 0x01 }; static const unsigned headerLength = 10; unsigned sampleRate; while(data<end) { while(data<end && frameOffset < sizeof(syncWord)) { if ( *data == syncWord[frameOffset] ) { frameBuffer[frameOffset] = *data; ++frameOffset; } else { frameOffset = 0; } ++data; } if (data>=end) return false; if( frameOffset >= sizeof(syncWord) && frameOffset < headerLength ) { copy(data, end, headerLength); } if (frameOffset==headerLength) { size_t nblks = ((frameBuffer[4] & 0x01)<<6) | (frameBuffer[5]>>2); nblks += 1; numberOfSamples = nblks * 32; if (numberOfSamples!=512 && numberOfSamples!=1024 && numberOfSamples!=2048) { Log::debug("output::DTSDecoder::decode: invalid number of samples: %u\n", numberOfSamples); frameOffset = 0; } } if (frameOffset==headerLength) { frameLength = ((frameBuffer[5]&0x03)<<12)|(frameBuffer[6]<<4)|(frameBuffer[7]>>4); if (frameLength>8192 || frameLength<96) { Log::debug("output::DTSDecoder::decode: invalid frame size: %u\n", frameLength); frameOffset = 0; } } if (frameOffset==headerLength) { sampleRate = (frameBuffer[8]>>2)&0x0f; if (sampleRate!=13) { Log::debug("output::DTSDecoder::decode: invalid sample rate value: %u\n", sampleRate); frameOffset = 0; } } if (frameOffset==headerLength) { Log::verboseDebug("DTS frame with length=%u, # of samples=%u, sampleRate=%u\n", frameLength, numberOfSamples, sampleRate); AudioFormat& format = audioProcessor.getOutputFormat(); format.encoding = DTS; format.sampleRate = 48000; format.numberOfChannels = 2; } if (data>=end) return false; if ( frameOffset>=headerLength && frameOffset<frameLength) { copy(data, end, frameLength); } if (frameOffset==frameLength) { prepareFrameForHardwareDecoding(); frameOffset = 0; frameLength = (size_t)-1; return true; } } return false;}//------------------------------------------------------------------------------void DTSDecoder::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);}//------------------------------------------------------------------------------void DTSDecoder::prepareFrameForHardwareDecoding(){ unsigned char* output = audioProcessor.getOutputBuffer(); output[0] = 0x72; output[1] = 0xf8; output[2] = 0x1f; output[3] = 0x4e; switch(numberOfSamples) { case 512: output[4] = 0x0b; break; case 1024: output[5] = 0x0c; break; case 2048: output[4] = 0x0d; break; default: output[4] = 0x00; } output[5] = 0x00; output[6] = (frameLength<<3) & 0xff; output[7] = (frameLength>>5) & 0xff; swab(frameBuffer, output+8, frameLength); memset(output + 8 + frameLength, 0, numberOfSamples*4 - 8 - frameLength); audioProcessor.setOutputLength(numberOfSamples*4);}//------------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -