[datatype-dev] CR: Add AMR specific boxes and sample boxes to MPEG4 Atom's list.
Greg Wright gwright at real.comI need support for writing 3GP files with AMR content.
Solution
---------
Since our MPEG4 file writer does both 3GPP and MPEG4 I added
the 3GPP specialized MPEG4 boxes there.
I also added a 3GPP stream handler to use those new atoms.
AMR WB+ is mentioned, but no support is added at this time.
Support is only added, right now, for:
SAMR
SAWB
dARM
and currently, SAWB is commented out until I have a encoder
to test with.
--greg.
===================================================================
RCS file: /cvsroot/datatype/mp4/filewriter/Umakefil,v
retrieving revision 1.7
diff -u -w -r1.7 Umakefil
--- Umakefil 26 Sep 2008 16:40:52 -0000 1.7
+++ Umakefil 9 Mar 2009 17:37:46 -0000
@@ -50,6 +50,7 @@
'm4avsh.cpp',
'avcsh.cpp',
'h263sh.cpp',
+ 'amrsh.cpp',
'blist.cpp',
'mp4sm.cpp',
'mp4atomgateway.cpp'
===================================================================
RCS file: /cvsroot/datatype/mp4/filewriter/mp4atoms.h,v
retrieving revision 1.8
diff -u -w -r1.8 mp4atoms.h
--- mp4atoms.h 14 Oct 2008 20:05:10 -0000 1.8
+++ mp4atoms.h 9 Mar 2009 17:37:46 -0000
@@ -1697,6 +1697,10 @@
};
+
+
+
+
// atom: s263
// container: stsd
// purpose: h263 video sample description entry
@@ -1708,6 +1712,9 @@
}
};
+
+
+
// atom: uuid
// container: stsd
// purpose: identifies file creator (iPod compatibility)
@@ -2559,4 +2566,94 @@
UINT32 m_uiBytesWritten;
};
+
+
+
+
+////////////////////////////////////////////////////
+//
+// BEGIN: AMR NB, WB, WB+ MPEG4 (3GPP) Atoms Section
+//
+////////////////////////////////////////////////////
+
+
+
+// 3GPP AMRSpecificBox, part of the AMRSampleEntry box. The same AMRSpecificBox
+// is used for both the sample entry box for AMR-NB and AMR-WB.
+class CMP4Atom_dAMR : public CMP4Atom
+{
+ public:
+ CMP4Atom_dAMR() :
+ CMP4Atom(MP4_BUILD_ATOMID('d','a','m','r')),
+ m_ulDecoderInfoSize(0),
+ m_pDecoderInfo(NULL)
+ {
+ }
+
+ ~CMP4Atom_dAMR()
+ {
+ HX_VECTOR_DELETE(m_pDecoderInfo);
+ }
+
+ STDMETHOD_(UINT32, GetCurrentSize ) (THIS_ BOOL bIncludeChildren = FALSE)
+ {
+ return 8 + m_ulDecoderInfoSize;
+ }
+
+ STDMETHOD( WriteToBuffer ) (THIS_ UCHAR*& pBuffer, BOOL bIncludeChildren=FALSE)
+ {
+ HX_RESULT retVal = HXR_OK;
+ if( pBuffer )
+ {
+ CMP4Atom::WriteToBufferAndInc( pBuffer, GetCurrentSize() );
+ CMP4Atom::WriteToBufferAndInc( pBuffer, m_ulAtomID );
+ CMP4Atom::WriteToBufferAndInc( pBuffer, m_pDecoderInfo, m_ulDecoderInfoSize);
+ if( bIncludeChildren )
+ {
+ ChildrenWriteToBuffer( pBuffer );
+ }
+ }
+ return retVal;
+ }
+
+ void SetDecoderInfo(UINT8* pData, int size)
+ {
+ HX_VECTOR_DELETE(m_pDecoderInfo);
+ m_pDecoderInfo = new UINT8[size];
+ memcpy(m_pDecoderInfo, pData, size);
+ m_ulDecoderInfoSize = size;
+ }
+
+ private:
+
+ UINT32 m_ulDecoderInfoSize;
+ UINT8* m_pDecoderInfo;
+};
+
+
+// 3GPP AMRSampleEntry
+class CMP4Atom_sAMR : public CMP4Atom_AudioSampleEntry
+{
+ public:
+ CMP4Atom_sAMR() : CMP4Atom_AudioSampleEntry(MP4_BUILD_ATOMID('s','a','m','r'))
+ {
+ }
+};
+
+class CMP4Atom_sAWB : public CMP4Atom_AudioSampleEntry
+{
+ public:
+ CMP4Atom_sAWB() : CMP4Atom_AudioSampleEntry(MP4_BUILD_ATOMID('s','a','w','b'))
+ {
+ }
+};
+
+////////////////////////////////////////////////////
+//
+// END: AMR NB, WB MPEG4 (3GPP) Atoms Section
+//
+////////////////////////////////////////////////////
+
+
+
#endif /* _MP4ATOMS_H_ */
Index: mp4sm.cpp
===================================================================
RCS file: /cvsroot/datatype/mp4/filewriter/mp4sm.cpp,v
retrieving revision 1.7
diff -u -w -r1.7 mp4sm.cpp
--- mp4sm.cpp 1 Oct 2008 17:09:15 -0000 1.7
+++ mp4sm.cpp 9 Mar 2009 17:37:46 -0000
@@ -2141,6 +2141,9 @@
case MP4_BUILD_ATOMID('h', '2', '6', '3'):
return BuildH263StsdEntry(pStsd, usStreamNum);
break;
+ case MP4_BUILD_ATOMID('a', 'm', 'r', ' '):
+ return BuildAMRStsdEntry(pStsd, usStreamNum);
+ break;
default:
return HXR_INVALID_PARAMETER;
break;
@@ -2371,6 +2374,57 @@
return retVal;
}
+HX_RESULT CMP4StreamMixer::BuildAMRStsdEntry( CMP4Atom_stsd* pStsd, UINT16 usStreamNum )
+{
+ IHXValues* pStreamHeader = m_pStreamInfo[usStreamNum].m_pStreamHeader;
+ HX_RESULT retVal = HXR_OK;
+ IHXBuffer* pDecoderInfo = NULL;
+ IHXBuffer* pMimeType = NULL;
+ const char* pszMimeType = NULL;
+
+ CMP4Atom_AudioSampleEntry* pSAMR = NULL;
+
+ //XXXgfw Need to finish this before we can support AMR-WB....
+// //Create either a NB or WB sampel entry box depending on the mime type.
+// retVal = pStreamHeader->GetPropertyBuffer("MimeType", pMimeType);
+// HX_ASSERT(SUCCEEDED(retVal));
+// if( SUCCEEDED(retVal) )
+// {
+// pszMimeType = (char*)pMimeType->GetBuffer();
+// if( strstr( "WB", pszMimeType) != 0 )
+// {
+// pSAMR = new CMP4Atom_sAWB();
+// }
+// else
+// {
+ pSAMR = new CMP4Atom_sAMR();
+// }
+// }
+ HX_RELEASE(pMimeType);
+ HX_ASSERT(NULL!=pSAMR);
+
+ if( pSAMR && SUCCEEDED(retVal) )
+ {
+ //This is out 'opauqe data' coming from the AMR codec filter.
+ retVal = pStreamHeader->GetPropertyBuffer("DecoderInfo", pDecoderInfo);
+
+ UCHAR* pBuf = pDecoderInfo->GetBuffer();
+ UINT32 len = pDecoderInfo->GetSize();
+
+ //The specific box is common to both the NB and WB
+ //sample entry boxes.
+ CMP4Atom_dAMR* pDAMR = new CMP4Atom_dAMR();
+ if( pDAMR )
+ {
+ pDAMR->SetDecoderInfo( pBuf, len );
+ pSAMR->AddChild( pDAMR );
+ }
+ pStsd->AddChild( pSAMR );
+ }
+ HX_RELEASE( pDecoderInfo );
+ return retVal;
+}
+
HX_RESULT CMP4StreamMixer::UpdateTrackDuration( UINT16 usStreamNo, UINT32 ulDuration )
{
Index: mp4sm.h
===================================================================
RCS file: /cvsroot/datatype/mp4/filewriter/mp4sm.h,v
retrieving revision 1.5
diff -u -w -r1.5 mp4sm.h
--- mp4sm.h 1 Oct 2008 17:09:15 -0000 1.5
+++ mp4sm.h 9 Mar 2009 17:37:46 -0000
@@ -101,6 +101,7 @@
HX_RESULT BuildMP4VStsdEntry( CMP4Atom_stsd* pStsd, UINT16 usStreamNum );
HX_RESULT BuildAVC1StsdEntry( CMP4Atom_stsd* pStsd, UINT16 usStreamNum );
HX_RESULT BuildH263StsdEntry( CMP4Atom_stsd* pStsd, UINT16 usStreamNum );
+ HX_RESULT BuildAMRStsdEntry( CMP4Atom_stsd* pStsd, UINT16 usStreamNum );
// 3GP Utilities
void Meta3GP_SetLanguageEncoding(C3GPAtom_LangBase* pAtom, const char* propertySpec = 0);
Index: mp4wrtr.cpp
===================================================================
RCS file: /cvsroot/datatype/mp4/filewriter/mp4wrtr.cpp,v
retrieving revision 1.9
diff -u -w -r1.9 mp4wrtr.cpp
--- mp4wrtr.cpp 26 Sep 2008 16:40:52 -0000 1.9
+++ mp4wrtr.cpp 9 Mar 2009 17:37:46 -0000
@@ -74,6 +74,7 @@
#include "m4avsh.h"
#include "avcsh.h"
#include "h263sh.h"
+#include "amrsh.h"
//stream mixer
#include "mp4sm.h"
@@ -713,6 +714,20 @@
}
}
+ //3GPP AMR Stream Handler.
+ if( FAILED( retVal ) )
+ {
+ HX_RELEASE( pTempHandler );
+ retVal = HXR_OUTOFMEMORY;
+ pTempHandler = new CAMRStreamHandler( m_pContext, m_pStreamMixer );
+
+ if( pTempHandler )
+ {
+ pTempHandler->AddRef();
+ retVal = TestForMimeSupport( pTempHandler, pStreamMimeType );
+ }
+ }
+
//default NULL stream handler, always true
if ( FAILED( retVal ) )
{