Add AC-3 support, fix audio seeking

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@29839 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
David McPaul
2009-03-31 21:02:12 +00:00
parent 653dac15d2
commit 81ed336ed1
6 changed files with 110 additions and 7 deletions
@@ -105,8 +105,14 @@ bool AtomBase::MoveToEnd()
uint64 AtomBase::getBytesRemaining() uint64 AtomBase::getBytesRemaining()
{ {
off_t EndPosition = streamOffset + atomSize; off_t EndPosition = streamOffset + atomSize;
off_t CurrPosition = getStream()->Position();
return (EndPosition - getStream()->Position()); if (CurrPosition > EndPosition) {
printf("ERROR: Read past atom boundary by %Ld bytes\n",CurrPosition - EndPosition);
return 0;
}
return (EndPosition - CurrPosition);
} }
void AtomBase::DisplayAtoms() void AtomBase::DisplayAtoms()
@@ -310,7 +316,8 @@ bool AtomContainer::AddChild(AtomBase *pChildAtom)
{ {
if (pChildAtom) { if (pChildAtom) {
pChildAtom->setParent(this); pChildAtom->setParent(this);
atomChildren[TotalChildren++] = pChildAtom; atomChildren.push_back(pChildAtom);
TotalChildren++;
return true; return true;
} }
return false; return false;
@@ -32,7 +32,7 @@
#include <MediaFormats.h> #include <MediaFormats.h>
#include <SupportDefs.h> #include <SupportDefs.h>
#include <map> #include <vector>
/* /*
@@ -60,7 +60,7 @@ public
class AtomBase; class AtomBase;
typedef AtomBase* AtomBasePtr; typedef AtomBase* AtomBasePtr;
typedef std::map<uint32, AtomBasePtr, std::less<uint32> > AtomArray; typedef std::vector<AtomBasePtr> AtomArray;
class AtomBase { class AtomBase {
@@ -96,7 +96,8 @@ bool
MP4FileReader::AddChild(AtomBase *childAtom) MP4FileReader::AddChild(AtomBase *childAtom)
{ {
if (childAtom) { if (childAtom) {
atomChildren[TotalChildren++] = childAtom; atomChildren.push_back(childAtom);
TotalChildren++;
return true; return true;
} }
return false; return false;
@@ -197,6 +197,18 @@ AtomBase *getAtom(BPositionIO *pStream)
return new WAVEAtom(pStream, aStreamOffset, aAtomType, aRealAtomSize); return new WAVEAtom(pStream, aStreamOffset, aAtomType, aRealAtomSize);
} }
if (aAtomType == uint32('dac3')) {
return new DAC3Atom(pStream, aStreamOffset, aAtomType, aRealAtomSize);
}
if (aAtomType == uint32('dec3')) {
return new DEC3Atom(pStream, aStreamOffset, aAtomType, aRealAtomSize);
}
if (aAtomType == uint32('avcC')) {
return new DecoderConfigAtom(pStream, aStreamOffset, aAtomType, aRealAtomSize);
}
return new AtomBase(pStream, aStreamOffset, aAtomType, aRealAtomSize); return new AtomBase(pStream, aStreamOffset, aAtomType, aRealAtomSize);
} }
@@ -757,6 +769,7 @@ void STSZAtom::OnProcessMetaData()
char *STSZAtom::OnGetAtomName() char *STSZAtom::OnGetAtomName()
{ {
printf("SS=%ld Count=%ld ",SampleSize,SampleCount);
return "Sample Size Atom"; return "Sample Size Atom";
} }
@@ -1197,6 +1210,65 @@ void WAVEAtom::OnOverrideVideoDescription(VideoDescription *pVideoDescription)
// Nothing to override // Nothing to override
} }
DAC3Atom::DAC3Atom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : DecoderConfigAtom(pStream, pstreamOffset, patomType, patomSize)
{
}
DAC3Atom::~DAC3Atom()
{
}
void DAC3Atom::OnProcessMetaData()
{
DecoderConfigAtom::OnProcessMetaData();
}
void DAC3Atom::OnOverrideAudioDescription(AudioDescription *pAudioDescription)
{
pAudioDescription->codecSubType = 'dac3';
pAudioDescription->FrameSize = 1536;
}
void DAC3Atom::OnOverrideVideoDescription(VideoDescription *pVideoDescription)
{
// Nothing to override
}
char *DAC3Atom::OnGetAtomName()
{
return "Digital AC3";
}
DEC3Atom::DEC3Atom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : DecoderConfigAtom(pStream, pstreamOffset, patomType, patomSize)
{
}
DEC3Atom::~DEC3Atom()
{
}
void DEC3Atom::OnProcessMetaData()
{
DecoderConfigAtom::OnProcessMetaData();
}
void DEC3Atom::OnOverrideAudioDescription(AudioDescription *pAudioDescription)
{
pAudioDescription->codecSubType = 'dec3';
pAudioDescription->FrameSize = 1536;
}
void DEC3Atom::OnOverrideVideoDescription(VideoDescription *pVideoDescription)
{
// Nothing to override
}
char *DEC3Atom::OnGetAtomName()
{
return "Digital EAC3";
}
STSDAtom::STSDAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : FullAtom(pStream, pstreamOffset, patomType, patomSize) STSDAtom::STSDAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : FullAtom(pStream, pstreamOffset, patomType, patomSize)
{ {
theHeader.NoEntries = 0; theHeader.NoEntries = 0;
@@ -1251,6 +1323,7 @@ void STSDAtom::ReadDecoderConfig(uint8 **pDecoderConfig, size_t *pDecoderConfigS
delete aAtomBase; delete aAtomBase;
} else { } else {
// Unknown atom bad // Unknown atom bad
printf("Unknown atom %s\n",aAtomBase->getAtomName());
delete aAtomBase; delete aAtomBase;
} }
} }
@@ -558,6 +558,28 @@ public:
}; };
// Atom class for reading the dac3 atom
class DAC3Atom : public DecoderConfigAtom {
public:
DAC3Atom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize);
virtual ~DAC3Atom();
void OnProcessMetaData();
char *OnGetAtomName();
void OnOverrideAudioDescription(AudioDescription *pAudioDescription);
void OnOverrideVideoDescription(VideoDescription *pVideoDescription);
};
// Atom class for reading the dec3 atom
class DEC3Atom : public DecoderConfigAtom {
public:
DEC3Atom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize);
virtual ~DEC3Atom();
void OnProcessMetaData();
char *OnGetAtomName();
void OnOverrideAudioDescription(AudioDescription *pAudioDescription);
void OnOverrideVideoDescription(VideoDescription *pVideoDescription);
};
// Atom class for reading the Media Handler atom // Atom class for reading the Media Handler atom
class HDLRAtom : public FullAtom { class HDLRAtom : public FullAtom {
public: public:
@@ -568,13 +568,13 @@ mp4Reader::Seek(void *cookie, uint32 flags, int64 *frame, bigtime_t *time)
if (flags & B_MEDIA_SEEK_TO_TIME) { if (flags & B_MEDIA_SEEK_TO_TIME) {
// frame = (time * rate) / fps / 1000000LL // frame = (time * rate) / fps / 1000000LL
*frame = ((*time * mp4cookie->frames_per_sec_rate) / (int64)mp4cookie->frames_per_sec_scale) / 1000000LL; *frame = ((*time * mp4cookie->frames_per_sec_rate) / (int64)mp4cookie->frames_per_sec_scale) / 1000000LL;
mp4cookie->frame_pos = *frame / mp4cookie->frame_size; mp4cookie->frame_pos = *frame;
} }
if (flags & B_MEDIA_SEEK_TO_FRAME) { if (flags & B_MEDIA_SEEK_TO_FRAME) {
// time = frame * 1000000LL * fps / rate // time = frame * 1000000LL * fps / rate
*time = (*frame * 1000000LL * (int64)mp4cookie->frames_per_sec_scale) / mp4cookie->frames_per_sec_rate; *time = (*frame * 1000000LL * (int64)mp4cookie->frames_per_sec_scale) / mp4cookie->frames_per_sec_rate;
mp4cookie->frame_pos = *frame / mp4cookie->frame_size; mp4cookie->frame_pos = *frame;
} }
TRACE("mp4Reader::Seek: seekTo%s%s%s%s, time %Ld, frame %Ld\n", TRACE("mp4Reader::Seek: seekTo%s%s%s%s, time %Ld, frame %Ld\n",