[datatype-dev] CR: Add AMR specific boxes and sample boxes to MPEG4 Atom's list.

[datatype-dev] CR: Add AMR specific boxes and sample boxes to MPEG4 Atom's list.

Greg Wright gwright at real.com
Mon Mar 9 09:50:15 PDT 2009


I 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 ) )
  			{




More information about the Datatype-dev mailing list
 

Site Map   |   Terms of Use   |   Privacy Policy   |   Contact Us

Copyright © 1995-2007 RealNetworks, Inc. All rights reserved. RealNetworks and Helix are trademarks of RealNetworks.
All other trademarks or registered trademarks are the property of their respective holders.