cog/Libraries/DecMPA/Files/src/MPAFrameFinder.h

202 lines
4.2 KiB
C++

/* DecMPA - simple MPEG Audio decoding library.
Copyright (C) 2002 Hauke Duden
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
For more information look at the file License.txt in this package.
email: hazard_hd@users.sourceforge.net
*/
#ifndef _MPAFRAMEFINDER_H_
#define _MPAFRAMEFINDER_H_
#include "IFileAccess.h"
#include "mpegAudioFrame/mpegAudioHeader.h"
#include "MemBuffer.h"
class CMPAFrameFinder
{
public:
CMPAFrameFinder();
~CMPAFrameFinder();
inline void SetLookAheadFrames(int nFrames);
inline void SetAllowFrequencyChanges(bool bAllow);
inline int GetLookAheadFrames();
inline bool GetAllowFrequencyChanges();
//if false, the finder needs more input data or the stream
//invalid
bool ReadNextFrame();
inline bool IsStreamInvalid();
inline bool KnowsCharacteristics();
inline bool HasFrame();
inline void* GetFrameData();
inline int GetFrameSize();
inline double GetAvgFrameSize();
inline MpegAudioHeader* GetFrameHeader();
void SetInput(void* pBuffer,int nBytes,long nStreamPosition);
bool ReadInput(IFileAccess* pAccess);
//throw away buffered data and find next frame
void Flush();
//start with a completely blank slate for a new data stream
void Restart();
inline long GetFirstFramePosition();
protected:
struct HeaderRecord
{
MpegAudioHeader Header;
long nPosition;
HeaderRecord* pNext;
};
bool FindCharacteristics();
bool FindConsistentHeaders();
bool CanHaveConsistentHeaders(HeaderRecord* pRecord,int nHeaderCount);
bool HasConsistentHeaders(HeaderRecord* pCheckRecord,HeaderRecord* pRecord,int nHeadersNeeded);
bool AreHeadersConsistent(HeaderRecord* pFirst,HeaderRecord* pSecond);
bool IsConformingHeader(MpegAudioHeader* pHeader);
void FindNextSync();
void ReadHeader();
void CheckHeader();
void ReadFrame();
void ResetState();
void DeleteHeaderRecords();
static bool IsValidHeader(MpegAudioHeader* pHeader);
CMemBuffer m_OutBuffer;
CMemBuffer* m_pInBuffer;
CMemBuffer m_MyInBuffer;
CMemBuffer m_UserInBuffer;
int m_State;
int m_nLookAheadFrames;
bool m_bAllowFrequencyChanges;
int m_nLayer;
int m_nInputStereo;
int m_nFrequency;
int m_nLayer25;
int m_nVersion;
MpegAudioHeader m_Header;
int m_nFrameSize;
long m_nReadStartPosition;
long m_nFirstFramePosition;
enum
{
STATE_FINDCHARACTERISTICS=0,
STATE_FINDSYNC,
STATE_READHEADER,
STATE_CHECKHEADER,
STATE_READFRAME,
STATE_HAVEFRAME
};
HeaderRecord* m_pFirstHeader;
HeaderRecord* m_pLastHeader;
HeaderRecord* m_pNewHeaderRecord;
bool m_bStreamInvalid;
};
inline void CMPAFrameFinder::SetLookAheadFrames(int nFrames)
{
if(nFrames<0)
nFrames=0;
m_nLookAheadFrames=nFrames;
}
inline void CMPAFrameFinder::SetAllowFrequencyChanges(bool bAllow)
{
m_bAllowFrequencyChanges=bAllow;
}
inline int CMPAFrameFinder::GetLookAheadFrames()
{
return m_nLookAheadFrames;
}
inline bool CMPAFrameFinder::GetAllowFrequencyChanges()
{
return m_bAllowFrequencyChanges;
}
inline bool CMPAFrameFinder::HasFrame()
{
return (m_State==STATE_HAVEFRAME);
}
inline void* CMPAFrameFinder::GetFrameData()
{
return m_OutBuffer.GetPtr();
}
inline int CMPAFrameFinder::GetFrameSize()
{
return m_OutBuffer.GetPos();
}
inline double CMPAFrameFinder::GetAvgFrameSize()
{
return m_Header.GetAvgFrameSize();
}
inline MpegAudioHeader* CMPAFrameFinder::GetFrameHeader()
{
return &m_Header;
}
inline bool CMPAFrameFinder::IsStreamInvalid()
{
return m_bStreamInvalid;
}
inline bool CMPAFrameFinder::KnowsCharacteristics()
{
return (m_State>STATE_FINDCHARACTERISTICS);
}
inline long CMPAFrameFinder::GetFirstFramePosition()
{
return m_nFirstFramePosition;
}
#endif