shithub: aacdec

Download patch

ref: ea1e898cfc7519e0f539007ed771c2329dc32d2e
parent: d7fd5cfc180d6f110527f5ccebeb7d6463570dd8
author: menno <menno>
date: Fri Aug 30 16:52:43 EDT 2002

Added option to convert aac file to mp4

--- /dev/null
+++ b/plugins/in_mp4/aac2mp4.c
@@ -1,0 +1,85 @@
+/*
+** FAAD - Freeware Advanced Audio Decoder
+** Copyright (C) 2002 M. Bakker
+**  
+** 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.
+**
+** $Id: aac2mp4.c,v 1.1 2002/08/30 20:52:42 menno Exp $
+**/
+
+#include <mpeg4ip.h>
+#include <mp4.h>
+#include "mp4av.h"
+
+#include "aac2mp4.h"
+
+int covert_aac_to_mp4(char *inputFileName)
+{
+    int Mp4TimeScale = 90000;
+    int allMpeg4Streams = 0;
+    MP4FileHandle mp4File;
+    FILE* inFile;
+    char mp4FileName[256];
+    char* extension, *type;
+    MP4TrackId createdTrackId = MP4_INVALID_TRACK_ID;
+
+    lstrcpy(mp4FileName, inputFileName);
+    extension = strrchr(mp4FileName, '.');
+    lstrcpy(extension, ".mp4");
+
+    mp4File = MP4Create(mp4FileName, 0, 0, 0);
+    if (mp4File)
+    {
+        MP4SetTimeScale(mp4File, Mp4TimeScale);
+    } else {
+        return 1;
+    }
+
+    inFile = fopen(inputFileName, "rb");
+
+	if (inFile == NULL)
+    {
+        MP4Close(mp4File);
+        return 2;
+    }
+
+    createdTrackId = AacCreator(mp4File, inFile);
+
+    if (createdTrackId == MP4_INVALID_TRACK_ID)
+    {
+        fclose(inFile);
+        MP4Close(mp4File);
+        return 3;
+    }
+
+    type = MP4GetTrackType(mp4File, createdTrackId);
+
+    if (!strcmp(type, MP4_AUDIO_TRACK_TYPE))
+    {
+        allMpeg4Streams &=
+            (MP4GetTrackAudioType(mp4File, createdTrackId)
+            == MP4_MPEG4_AUDIO_TYPE);
+    }
+
+    if (inFile)
+    {
+        fclose(inFile);
+    }
+
+    MP4Close(mp4File);
+    MP4MakeIsmaCompliant(mp4FileName, 0, allMpeg4Streams);
+
+    return 0;
+}
\ No newline at end of file
--- /dev/null
+++ b/plugins/in_mp4/aac2mp4.h
@@ -1,0 +1,36 @@
+/*
+** FAAD - Freeware Advanced Audio Decoder
+** Copyright (C) 2002 M. Bakker
+**  
+** 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.
+**
+** $Id: aac2mp4.h,v 1.1 2002/08/30 20:52:43 menno Exp $
+**/
+
+#ifndef AAC2MP4_H__
+#define AAC2MP4_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+int covert_aac_to_mp4(char *inputFileName);
+MP4TrackId AacCreator(MP4FileHandle mp4File, FILE* inFile);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
\ No newline at end of file
--- a/plugins/in_mp4/aacinfo.c
+++ b/plugins/in_mp4/aacinfo.c
@@ -16,7 +16,7 @@
 ** along with this program; if not, write to the Free Software 
 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 **
-** $Id: aacinfo.c,v 1.2 2002/08/15 17:41:44 menno Exp $
+** $Id: aacinfo.c,v 1.3 2002/08/30 20:52:43 menno Exp $
 **/
 
 #define WIN32_LEAN_AND_MEAN
@@ -125,9 +125,12 @@
 
     if (frames > 0)
     {
+        float sec_per_frame, bytes_per_frame;
         info->sampling_rate = sample_rates[sr_idx];
-        info->bitrate = (int)(((t_framelength / frames) * (info->sampling_rate/1024.0)) +0.5)*8;
-        info->length = (int)((float)(frames/frames_per_sec))*1000;
+        sec_per_frame = (float)info->sampling_rate/1024.0;
+        bytes_per_frame = (float)t_framelength / (float)frames;
+        info->bitrate = 8 * (int)floor(bytes_per_frame * sec_per_frame);
+        info->length = (int)floor((float)frames/frames_per_sec)*1000;
     } else {
         info->sampling_rate = 4;
         info->bitrate = 128000;
--- /dev/null
+++ b/plugins/in_mp4/aactrack.cpp
@@ -1,0 +1,265 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ * 
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ * 
+ * The Original Code is MPEG4IP.
+ * 
+ * The Initial Developer of the Original Code is Cisco Systems Inc.
+ * Portions created by Cisco Systems Inc. are
+ * Copyright (C) Cisco Systems Inc. 2000, 2001.  All Rights Reserved.
+ * 
+ * Contributor(s): 
+ *		Dave Mackie		[email protected]
+ */
+
+/* 
+ * Notes:
+ *  - file formatted with tabstops == 4 spaces 
+ */
+
+#include <mpeg4ip.h>
+#include <mp4.h>
+#include "mp4av.h"
+
+#include "aac2mp4.h"
+
+#define ADTS_HEADER_MAX_SIZE 10 /* bytes */
+
+static u_int8_t firstHeader[ADTS_HEADER_MAX_SIZE];
+
+/* 
+ * hdr must point to at least ADTS_HEADER_MAX_SIZE bytes of memory 
+ */
+static bool LoadNextAdtsHeader(FILE* inFile, u_int8_t* hdr)
+{
+	u_int state = 0;
+	u_int dropped = 0;
+	u_int hdrByteSize = ADTS_HEADER_MAX_SIZE;
+
+	while (1) {
+		/* read a byte */
+		u_int8_t b;
+
+		if (fread(&b, 1, 1, inFile) == 0) {
+			return false;
+		}
+
+		/* header is complete, return it */
+		if (state == hdrByteSize - 1) {
+			hdr[state] = b;
+			if (dropped > 0) {
+				fprintf(stderr, "Warning: dropped %u input bytes\n", dropped);
+			}
+			return true;
+		}
+
+		/* collect requisite number of bytes, no constraints on data */
+		if (state >= 2) {
+			hdr[state++] = b;
+		} else {
+			/* have first byte, check if we have 1111X00X */
+			if (state == 1) {
+				if ((b & 0xF6) == 0xF0) {
+					hdr[state] = b;
+					state = 2;
+					/* compute desired header size */
+					hdrByteSize = MP4AV_AdtsGetHeaderByteSize(hdr);
+				} else {
+					state = 0;
+				}
+			}
+			/* initial state, looking for 11111111 */
+			if (state == 0) {
+				if (b == 0xFF) {
+					hdr[state] = b;
+					state = 1;
+				} else {
+					 /* else drop it */ 
+					dropped++;
+				}
+			}
+		}
+	}
+}
+
+/*
+ * Load the next frame from the file
+ * into the supplied buffer, which better be large enough!
+ *
+ * Note: Frames are padded to byte boundaries
+ */
+static bool LoadNextAacFrame(FILE* inFile, u_int8_t* pBuf, u_int32_t* pBufSize, bool stripAdts)
+{
+	u_int16_t frameSize;
+	u_int16_t hdrBitSize, hdrByteSize;
+	u_int8_t hdrBuf[ADTS_HEADER_MAX_SIZE];
+
+	/* get the next AAC frame header, more or less */
+	if (!LoadNextAdtsHeader(inFile, hdrBuf)) {
+		return false;
+	}
+	
+	/* get frame size from header */
+	frameSize = MP4AV_AdtsGetFrameSize(hdrBuf);
+
+	/* get header size in bits and bytes from header */
+	hdrBitSize = MP4AV_AdtsGetHeaderBitSize(hdrBuf);
+	hdrByteSize = MP4AV_AdtsGetHeaderByteSize(hdrBuf);
+	
+	/* adjust the frame size to what remains to be read */
+	frameSize -= hdrByteSize;
+
+	if (stripAdts) {
+		if ((hdrBitSize % 8) == 0) {
+			/* header is byte aligned, i.e. MPEG-2 ADTS */
+			/* read the frame data into the buffer */
+			if (fread(pBuf, 1, frameSize, inFile) != frameSize) {
+				return false;
+			}
+			(*pBufSize) = frameSize;
+		} else {
+			/* header is not byte aligned, i.e. MPEG-4 ADTS */
+			int i;
+			u_int8_t newByte;
+			int upShift = hdrBitSize % 8;
+			int downShift = 8 - upShift;
+
+			pBuf[0] = hdrBuf[hdrBitSize / 8] << upShift;
+
+			for (i = 0; i < frameSize; i++) {
+				if (fread(&newByte, 1, 1, inFile) != 1) {
+					return false;
+				}
+				pBuf[i] |= (newByte >> downShift);
+				pBuf[i+1] = (newByte << upShift);
+			}
+			(*pBufSize) = frameSize + 1;
+		}
+	} else { /* don't strip ADTS headers */
+		memcpy(pBuf, hdrBuf, hdrByteSize);
+		if (fread(&pBuf[hdrByteSize], 1, frameSize, inFile) != frameSize) {
+			return false;
+		}
+	}
+
+	return true;
+}
+
+static bool GetFirstHeader(FILE* inFile)
+{
+	/* read file until we find an audio frame */
+	fpos_t curPos;
+
+	/* already read first header */
+	if (firstHeader[0] == 0xff) {
+		return true;
+	}
+
+	/* remember where we are */
+	fgetpos(inFile, &curPos);
+	
+	/* go back to start of file */
+	rewind(inFile);
+
+	if (!LoadNextAdtsHeader(inFile, firstHeader)) {
+		return false;
+	}
+
+	/* reposition the file to where we were */
+	fsetpos(inFile, &curPos);
+
+	return true;
+}
+
+MP4TrackId AacCreator(MP4FileHandle mp4File, FILE* inFile)
+{
+	// collect all the necessary meta information
+	u_int32_t samplesPerSecond;
+	u_int8_t mpegVersion;
+	u_int8_t profile;
+	u_int8_t channelConfig;
+
+	if (!GetFirstHeader(inFile)) {
+		return MP4_INVALID_TRACK_ID;
+	}
+
+	samplesPerSecond = MP4AV_AdtsGetSamplingRate(firstHeader);
+	mpegVersion = MP4AV_AdtsGetVersion(firstHeader);
+	profile = MP4AV_AdtsGetProfile(firstHeader);
+	channelConfig = MP4AV_AdtsGetChannels(firstHeader);
+
+	u_int8_t audioType = MP4_INVALID_AUDIO_TYPE;
+	switch (mpegVersion) {
+	case 0:
+		audioType = MP4_MPEG4_AUDIO_TYPE;
+		break;
+	case 1:
+		switch (profile) {
+		case 0:
+			audioType = MP4_MPEG2_AAC_MAIN_AUDIO_TYPE;
+			break;
+		case 1:
+			audioType = MP4_MPEG2_AAC_LC_AUDIO_TYPE;
+			break;
+		case 2:
+			audioType = MP4_MPEG2_AAC_SSR_AUDIO_TYPE;
+			break;
+		case 3:
+			return MP4_INVALID_TRACK_ID;
+		}
+		break;
+	}
+
+	// add the new audio track
+	MP4TrackId trackId = 
+		MP4AddAudioTrack(mp4File, 
+			samplesPerSecond, 1024, audioType);
+
+	if (trackId == MP4_INVALID_TRACK_ID) {
+		return MP4_INVALID_TRACK_ID;
+	}
+
+	if (MP4GetNumberOfTracks(mp4File, MP4_AUDIO_TRACK_TYPE) == 1) {
+		MP4SetAudioProfileLevel(mp4File, 0x0F);
+	}
+
+	u_int8_t* pConfig = NULL;
+	u_int32_t configLength = 0;
+
+	MP4AV_AacGetConfiguration(
+		&pConfig,
+		&configLength,
+		profile,
+		samplesPerSecond,
+		channelConfig);
+
+	if (!MP4SetTrackESConfiguration(mp4File, trackId, 
+	  pConfig, configLength)) {
+		MP4DeleteTrack(mp4File, trackId);
+		return MP4_INVALID_TRACK_ID;
+	}
+
+	// parse the ADTS frames, and write the MP4 samples
+	u_int8_t sampleBuffer[8 * 1024];
+	u_int32_t sampleSize = sizeof(sampleBuffer);
+	MP4SampleId sampleId = 1;
+
+	while (LoadNextAacFrame(inFile, sampleBuffer, &sampleSize, true)) {
+		if (!MP4WriteSample(mp4File, trackId, sampleBuffer, sampleSize)) {
+			MP4DeleteTrack(mp4File, trackId);
+			return MP4_INVALID_TRACK_ID;
+		}
+		sampleId++;
+		sampleSize = sizeof(sampleBuffer);
+	}
+
+	return trackId;
+}
+
--- a/plugins/in_mp4/in_mp4.c
+++ b/plugins/in_mp4/in_mp4.c
@@ -16,7 +16,7 @@
 ** along with this program; if not, write to the Free Software 
 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 **
-** $Id: in_mp4.c,v 1.17 2002/08/18 18:18:37 menno Exp $
+** $Id: in_mp4.c,v 1.18 2002/08/30 20:52:43 menno Exp $
 **/
 
 #define WIN32_LEAN_AND_MEAN
@@ -32,6 +32,7 @@
 #include "utils.h"
 #include "config.h"
 #include "aacinfo.h"
+#include "aac2mp4.h"
 
 static long priority_table[] = {
     0,
@@ -170,6 +171,13 @@
 
     switch (message) {
     case WM_INITDIALOG:
+        EnableWindow(GetDlgItem(hwndDlg,IDC_CONVERT), FALSE) ;
+        ShowWindow(GetDlgItem(hwndDlg,IDC_CONVERT), SW_HIDE);
+        EnableWindow(GetDlgItem(hwndDlg,IDC_CONVERT1), FALSE) ;
+        ShowWindow(GetDlgItem(hwndDlg,IDC_CONVERT1), SW_HIDE);
+        EnableWindow(GetDlgItem(hwndDlg,IDC_CONVERT2), FALSE) ;
+        ShowWindow(GetDlgItem(hwndDlg,IDC_CONVERT2), SW_HIDE);
+
         file = MP4Read(info_fn, 0);
 
         if (!file)
@@ -230,16 +238,33 @@
                                    WPARAM wParam, LPARAM lParam)
 {
     faadAACInfo aacInfo;
-    char *info_text;
+    char *info_text, *header_string;
 
     switch (message) {
     case WM_INITDIALOG:
+        EnableWindow(GetDlgItem(hwndDlg,IDC_USERDATA), FALSE) ;
+        ShowWindow(GetDlgItem(hwndDlg,IDC_USERDATA), SW_HIDE);
+
         info_text = malloc(1024*sizeof(char));
 
         get_AAC_format(info_fn, &aacInfo);
 
-        sprintf(info_text, "%s AAC %s, %d sec, %d kbps, %d Hz",
+        switch (aacInfo.headertype)
+        {
+        case 0: /* RAW */
+            header_string = "";
+            break;
+        case 1: /* ADIF */
+            header_string = " ADIF";
+            break;
+        case 2: /* ADTS */
+            header_string = " ADTS";
+            break;
+        }
+
+        sprintf(info_text, "%s AAC %s%s, %d sec, %d kbps, %d Hz",
             (aacInfo.version==2)?"MPEG-2":"MPEG-4", get_ot_string(aacInfo.object_type),
+            header_string,
             (int)((float)aacInfo.length/1000.0), (int)((float)aacInfo.bitrate/1000.0+0.5),
             aacInfo.sampling_rate);
 
@@ -250,7 +275,18 @@
         return TRUE;
 
     case WM_COMMAND:
-        switch (LOWORD(wParam)) {
+        switch (LOWORD(wParam))
+        {
+        case IDC_CONVERT:
+            {
+                int ret = covert_aac_to_mp4(info_fn);
+                if (ret)
+                {
+                    MessageBox(hwndDlg, "An error occured!", "An error occured!", MB_OK);
+                    return FALSE;
+                }
+                return TRUE;
+            }
         case IDCANCEL:
         case IDOK:
             EndDialog(hwndDlg, wParam);
@@ -330,7 +366,7 @@
 void about(HWND hwndParent)
 {
     MessageBox(hwndParent,
-        "AudioCoding.com MPEG-4 General Audio player " FAAD2_VERSION "\n"
+        "AudioCoding.com MPEG-4 General Audio player " FAAD2_VERSION " compiled on " __DATE__ ".\n"
         "Visit the website for more info.\n"
         "Copyright 2002 AudioCoding.com",
         "About",
@@ -971,7 +1007,7 @@
 static In_Module module =
 {
     IN_VER,
-    "AudioCoding.com MPEG-4 General Audio player: " FAAD2_VERSION,
+    "AudioCoding.com MPEG-4 General Audio player: " FAAD2_VERSION " compiled on " __DATE__,
     0,  // hMainWindow
     0,  // hDllInstance
     "MP4\0MPEG-4 Files (*.MP4)\0AAC\0AAC Files (*.AAC)\0"
--- a/plugins/in_mp4/in_mp4.rc
+++ b/plugins/in_mp4/in_mp4.rc
@@ -61,7 +61,11 @@
     DEFPUSHBUTTON   "OK",IDOK,246,186,50,14
     LTEXT           "Static",IDC_INFOTEXT,14,17,275,47,0,WS_EX_CLIENTEDGE
     GROUPBOX        "Track info",IDC_STATIC,7,7,289,64
-    GROUPBOX        "User data",IDC_STATIC,7,77,289,104
+    GROUPBOX        "User data",IDC_USERDATA,7,76,289,104
+    PUSHBUTTON      "Convert Now!",IDC_CONVERT,111,150,81,14
+    GROUPBOX        "Convert to MP4",IDC_CONVERT2,7,81,289,99
+    CTEXT           "You can convert this file to MP4 if you like. This does not involve re-encoding, only the container format is changed. Advantages of MP4 files are that they are playable by a lot more players and they will have a lot of support in the future.",
+                    IDC_CONVERT1,24,102,255,27
 END
 
 IDD_CONFIG DIALOGEX 0, 0, 151, 108
--- a/plugins/in_mp4/in_mp4.vcproj
+++ b/plugins/in_mp4/in_mp4.vcproj
@@ -135,9 +135,15 @@
 			Name="Source Files"
 			Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
 			<File
+				RelativePath="aac2mp4.c">
+			</File>
+			<File
 				RelativePath="aacinfo.c">
 			</File>
 			<File
+				RelativePath="aactrack.cpp">
+			</File>
+			<File
 				RelativePath=".\config.c">
 			</File>
 			<File
@@ -144,6 +150,18 @@
 				RelativePath=".\in_mp4.c">
 			</File>
 			<File
+				RelativePath="mbs.cpp">
+			</File>
+			<File
+				RelativePath="mp4av_aac.cpp">
+			</File>
+			<File
+				RelativePath="mp4av_adts.cpp">
+			</File>
+			<File
+				RelativePath="mp4av_audio.cpp">
+			</File>
+			<File
 				RelativePath=".\utils.c">
 			</File>
 		</Filter>
@@ -150,6 +168,9 @@
 		<Filter
 			Name="Header Files"
 			Filter="h;hpp;hxx;hm;inl">
+			<File
+				RelativePath="aac2mp4.h">
+			</File>
 			<File
 				RelativePath="aacinfo.h">
 			</File>
--- /dev/null
+++ b/plugins/in_mp4/mbs.cpp
@@ -1,0 +1,93 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ * 
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ * 
+ * The Original Code is MPEG4IP.
+ * 
+ * The Initial Developer of the Original Code is Cisco Systems Inc.
+ * Portions created by Cisco Systems Inc. are
+ * Copyright (C) Cisco Systems Inc. 2001-2002.  All Rights Reserved.
+ * 
+ * Contributor(s): 
+ *		Dave Mackie		[email protected]
+ */
+
+#include "mp4av_common.h"
+
+void CMemoryBitstream::AllocBytes(u_int32_t numBytes) 
+{
+	m_pBuf = (u_int8_t*)calloc(numBytes, 1);
+	if (!m_pBuf) {
+		throw ENOMEM;
+	}
+	m_bitPos = 0;
+	m_numBits = numBytes << 3;
+}
+
+void CMemoryBitstream::SetBytes(u_int8_t* pBytes, u_int32_t numBytes) 
+{
+	m_pBuf = pBytes;
+	m_bitPos = 0;
+	m_numBits = numBytes << 3;
+}
+
+void CMemoryBitstream::PutBytes(u_int8_t* pBytes, u_int32_t numBytes)
+{
+	u_int32_t numBits = numBytes << 3;
+
+	if (numBits + m_bitPos > m_numBits) {
+		throw EIO;
+	}
+
+	if ((m_bitPos & 7) == 0) {
+		memcpy(&m_pBuf[m_bitPos >> 3], pBytes, numBytes);
+		m_bitPos += numBits;
+	} else {
+		for (u_int32_t i = 0; i < numBytes; i++) {
+			PutBits(pBytes[i], 8);
+		}
+	}
+}
+
+void CMemoryBitstream::PutBits(u_int32_t bits, u_int32_t numBits)
+{
+	if (numBits + m_bitPos > m_numBits) {
+		throw EIO;
+	}
+	if (numBits > 32) {
+		throw EIO;
+	}
+
+	for (int8_t i = numBits - 1; i >= 0; i--) {
+		m_pBuf[m_bitPos >> 3] |= ((bits >> i) & 1) << (7 - (m_bitPos & 7));
+		m_bitPos++;
+	}
+}
+
+u_int32_t CMemoryBitstream::GetBits(u_int32_t numBits)
+{
+	if (numBits + m_bitPos > m_numBits) {
+		throw EIO;
+	}
+	if (numBits > 32) {
+		throw EIO;
+	}
+
+	u_int32_t bits = 0;
+
+	for (u_int8_t i = 0; i < numBits; i++) {
+		bits <<= 1;
+		bits |= (m_pBuf[m_bitPos >> 3] >> (7 - (m_bitPos & 7))) & 1;
+		m_bitPos++;
+	}
+
+	return bits;
+}
+
--- /dev/null
+++ b/plugins/in_mp4/mbs.h
@@ -1,0 +1,81 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ * 
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ * 
+ * The Original Code is MPEG4IP.
+ * 
+ * The Initial Developer of the Original Code is Cisco Systems Inc.
+ * Portions created by Cisco Systems Inc. are
+ * Copyright (C) Cisco Systems Inc. 2001-2002.  All Rights Reserved.
+ * 
+ * Contributor(s): 
+ *		Dave Mackie		[email protected]
+ */
+
+#ifndef __MBS_INCLUDED__
+#define __MBS_INCLUDED__ 
+
+class CMemoryBitstream {
+public:
+	CMemoryBitstream() {
+		m_pBuf = NULL;
+		m_bitPos = 0;
+		m_numBits = 0;
+	}
+
+	void AllocBytes(u_int32_t numBytes);
+
+	void SetBytes(u_int8_t* pBytes, u_int32_t numBytes);
+
+	void PutBytes(u_int8_t* pBytes, u_int32_t numBytes);
+
+	void PutBits(u_int32_t bits, u_int32_t numBits);
+
+	u_int32_t GetBits(u_int32_t numBits);
+
+	void SkipBytes(u_int32_t numBytes) {
+		SkipBits(numBytes << 3);
+	}
+
+	void SkipBits(u_int32_t numBits) {
+		SetBitPosition(GetBitPosition() + numBits);
+	}
+
+	u_int32_t GetBitPosition() {
+		return m_bitPos;
+	}
+
+	void SetBitPosition(u_int32_t bitPos) {
+		if (bitPos > m_numBits) {
+			throw;
+		}
+		m_bitPos = bitPos;
+	}
+
+	u_int8_t* GetBuffer() {
+		return m_pBuf;
+	}
+
+	u_int32_t GetNumberOfBytes() {
+		return (GetNumberOfBits() + 7) / 8;
+	}
+
+	u_int32_t GetNumberOfBits() {
+		return m_numBits;
+	}
+
+protected:
+	u_int8_t*	m_pBuf;
+	u_int32_t	m_bitPos;
+	u_int32_t	m_numBits;
+};
+
+#endif /* __MBS_INCLUDED__ */ 
+
--- /dev/null
+++ b/plugins/in_mp4/mp4av.h
@@ -1,0 +1,42 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ * 
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ * 
+ * The Original Code is MPEG4IP.
+ * 
+ * The Initial Developer of the Original Code is Cisco Systems Inc.
+ * Portions created by Cisco Systems Inc. are
+ * Copyright (C) Cisco Systems Inc. 2001-2002.  All Rights Reserved.
+ * 
+ * Contributor(s): 
+ *		Dave Mackie		[email protected]
+ */
+
+#ifndef __MP4AV_INCLUDED__
+#define __MP4AV_INCLUDED__ 
+
+#include <mp4.h>
+
+#ifdef __cplusplus
+/* exploit C++ ability of default values for function parameters */
+#define DEFAULT_PARM(x)	=x
+#else
+#define DEFAULT_PARM(x)
+#endif
+
+/* MP4AV library API */
+#include "mp4av_aac.h"
+#include "mp4av_adts.h"
+#include "mp4av_audio.h"
+
+#undef DEFAULT_PARM
+
+#endif /* __MP4AV_INCLUDED__ */ 
+
--- /dev/null
+++ b/plugins/in_mp4/mp4av_aac.cpp
@@ -1,0 +1,133 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ * 
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ * 
+ * The Original Code is MPEG4IP.
+ * 
+ * The Initial Developer of the Original Code is Cisco Systems Inc.
+ * Portions created by Cisco Systems Inc. are
+ * Copyright (C) Cisco Systems Inc. 2000-2002.  All Rights Reserved.
+ * 
+ * Contributor(s): 
+ *		Dave Mackie		[email protected]
+ */
+
+/* 
+ * Notes:
+ *  - file formatted with tabstops == 4 spaces 
+ */
+
+#include "mp4av_common.h"
+
+/*
+ * AAC Config in ES:
+ *
+ * AudioObjectType 			5 bits
+ * samplingFrequencyIndex 	4 bits
+ * if (samplingFrequencyIndex == 0xF)
+ *	samplingFrequency	24 bits 
+ * channelConfiguration 	4 bits
+ * GA_SpecificConfig
+ * 	FrameLengthFlag 		1 bit 1024 or 960
+ * 	DependsOnCoreCoder		1 bit (always 0)
+ * 	ExtensionFlag 			1 bit (always 0)
+ */
+
+extern "C" u_int8_t MP4AV_AacConfigGetSamplingRateIndex(u_int8_t* pConfig)
+{
+	return ((pConfig[0] << 1) | (pConfig[1] >> 7)) & 0xF;
+}
+
+extern "C" u_int32_t MP4AV_AacConfigGetSamplingRate(u_int8_t* pConfig)
+{
+	u_int8_t index =
+		MP4AV_AacConfigGetSamplingRateIndex(pConfig);
+
+	if (index == 0xF) {
+		return (pConfig[1] & 0x7F) << 17
+			| pConfig[2] << 9
+			| pConfig[3] << 1
+			| (pConfig[4] >> 7);
+	}
+	return AdtsSamplingRates[index];
+}
+
+extern "C" u_int16_t MP4AV_AacConfigGetSamplingWindow(u_int8_t* pConfig)
+{
+	u_int8_t adjust = 0;
+
+	if (MP4AV_AacConfigGetSamplingRateIndex(pConfig) == 0xF) {
+		adjust = 3;
+	}
+
+	if ((pConfig[1 + adjust] >> 2) & 0x1) {
+		return 960;
+	}
+	return 1024;
+}
+
+extern "C" u_int8_t MP4AV_AacConfigGetChannels(u_int8_t* pConfig)
+{
+	u_int8_t adjust = 0;
+
+	if (MP4AV_AacConfigGetSamplingRateIndex(pConfig) == 0xF) {
+		adjust = 3;
+	}
+	return (pConfig[1 + adjust] >> 3) & 0xF;
+}
+
+extern "C" bool MP4AV_AacGetConfigurationFromAdts(
+	u_int8_t** ppConfig,
+	u_int32_t* pConfigLength,
+	u_int8_t* pHdr)
+{
+	return MP4AV_AacGetConfiguration(
+		ppConfig,
+		pConfigLength,
+		MP4AV_AdtsGetProfile(pHdr),
+		MP4AV_AdtsGetSamplingRate(pHdr),
+		MP4AV_AdtsGetChannels(pHdr));
+}
+
+extern "C" bool MP4AV_AacGetConfiguration(
+	u_int8_t** ppConfig,
+	u_int32_t* pConfigLength,
+	u_int8_t profile,
+	u_int32_t samplingRate,
+	u_int8_t channels)
+{
+	/* create the appropriate decoder config */
+
+	u_int8_t* pConfig = (u_int8_t*)malloc(2);
+
+	if (pConfig == NULL) {
+		return false;
+	}
+
+	u_int8_t samplingRateIndex = 
+		MP4AV_AdtsFindSamplingRateIndex(samplingRate);
+
+	pConfig[0] =
+		((profile + 1) << 3) | ((samplingRateIndex & 0xe) >> 1);
+	pConfig[1] =
+		((samplingRateIndex & 0x1) << 7) | (channels << 3);
+
+	/* LATER this option is not currently used in MPEG4IP
+	if (samplesPerFrame == 960) {
+		pConfig[1] |= (1 << 2);
+	}
+	*/
+
+	*ppConfig = pConfig;
+	*pConfigLength = 2;
+
+	return true;
+}
+
--- /dev/null
+++ b/plugins/in_mp4/mp4av_aac.h
@@ -1,0 +1,61 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ * 
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ * 
+ * The Original Code is MPEG4IP.
+ * 
+ * The Initial Developer of the Original Code is Cisco Systems Inc.
+ * Portions created by Cisco Systems Inc. are
+ * Copyright (C) Cisco Systems Inc. 2000-2002.  All Rights Reserved.
+ * 
+ * Contributor(s): 
+ *		Dave Mackie		[email protected]
+ */
+
+#ifndef __MP4AV_AAC_INCLUDED__
+#define __MP4AV_AAC_INCLUDED__
+
+#define MP4AV_AAC_MAIN_PROFILE	0
+#define MP4AV_AAC_LC_PROFILE	1
+#define MP4AV_AAC_SSR_PROFILE	2
+#define MP4AV_AAC_LTP_PROFILE	3
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+u_int8_t MP4AV_AacConfigGetSamplingRateIndex(
+	u_int8_t* pConfig);
+
+u_int32_t MP4AV_AacConfigGetSamplingRate(
+	u_int8_t* pConfig);
+
+u_int16_t MP4AV_AacConfigGetSamplingWindow(
+	u_int8_t* pConfig);
+
+u_int8_t MP4AV_AacConfigGetChannels(
+	u_int8_t* pConfig);
+
+bool MP4AV_AacGetConfigurationFromAdts(
+	u_int8_t** ppConfig,
+	u_int32_t* pConfigLength,
+	u_int8_t* pAdtsHdr);
+
+bool MP4AV_AacGetConfiguration(
+	u_int8_t** ppConfig,
+	u_int32_t* pConfigLength,
+	u_int8_t profile,
+	u_int32_t samplingRate,
+	u_int8_t channels);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __MP4AV_AAC_INCLUDED__ */
--- /dev/null
+++ b/plugins/in_mp4/mp4av_adts.cpp
@@ -1,0 +1,271 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ * 
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ * 
+ * The Original Code is MPEG4IP.
+ * 
+ * The Initial Developer of the Original Code is Cisco Systems Inc.
+ * Portions created by Cisco Systems Inc. are
+ * Copyright (C) Cisco Systems Inc. 2000-2002.  All Rights Reserved.
+ * 
+ * Contributor(s): 
+ *		Dave Mackie		[email protected]
+ */
+
+/* 
+ * Notes:
+ *  - file formatted with tabstops == 4 spaces 
+ */
+
+#include "mp4av_common.h"
+
+/*
+ * ADTS Header: 
+ *  MPEG-2 version 56 bits (byte aligned) 
+ *  MPEG-4 version 58 bits (not byte aligned)
+ *
+ * syncword						12 bits
+ * id							1 bit
+ * layer						2 bits
+ * protection_absent			1 bit
+ * profile						2 bits
+ * sampling_frequency_index		4 bits
+ * private						1 bit
+ * channel_configuraton			3 bits
+ * original						1 bit
+ * home							1 bit
+ * emphasis						2 bits
+ * copyright_id					1 bit
+ * copyright_id_start			1 bit
+ * aac_frame_length				13 bits
+ * adts_buffer_fullness			11 bits
+ * num_raw_data_blocks			2 bits
+ *
+ * if (protection_absent == 0)
+ *	crc_check					16 bits
+ */
+
+u_int32_t AdtsSamplingRates[NUM_ADTS_SAMPLING_RATES] = {
+	96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 
+	16000, 12000, 11025, 8000, 7350, 0, 0, 0
+};
+
+/*
+ * compute ADTS frame size
+ */
+extern "C" u_int16_t MP4AV_AdtsGetFrameSize(u_int8_t* pHdr)
+{
+	/* extract the necessary fields from the header */
+	u_int8_t isMpeg4 = !(pHdr[1] & 0x08);
+	u_int16_t frameLength;
+
+	if (isMpeg4) {
+		frameLength = (((u_int16_t)pHdr[4]) << 5) | (pHdr[5] >> 3); 
+	} else { /* MPEG-2 */
+		frameLength = (((u_int16_t)(pHdr[3] & 0x3)) << 11) 
+			| (((u_int16_t)pHdr[4]) << 3) | (pHdr[5] >> 5); 
+	}
+	return frameLength;
+}
+
+/*
+ * Compute length of ADTS header in bits
+ */
+extern "C" u_int16_t MP4AV_AdtsGetHeaderBitSize(u_int8_t* pHdr)
+{
+	u_int8_t isMpeg4 = !(pHdr[1] & 0x08);
+	u_int8_t hasCrc = !(pHdr[1] & 0x01);
+	u_int16_t hdrSize;
+
+	if (isMpeg4) {
+		hdrSize = 58;
+	} else {
+		hdrSize = 56;
+	}
+	if (hasCrc) {
+		hdrSize += 16;
+	}
+	return hdrSize;
+}
+
+extern "C" u_int16_t MP4AV_AdtsGetHeaderByteSize(u_int8_t* pHdr)
+{
+	return (MP4AV_AdtsGetHeaderBitSize(pHdr) + 7) / 8;
+}
+
+extern "C" u_int8_t MP4AV_AdtsGetVersion(u_int8_t* pHdr)
+{
+	return (pHdr[1] & 0x08) >> 3;
+}
+
+extern "C" u_int8_t MP4AV_AdtsGetProfile(u_int8_t* pHdr)
+{
+	return (pHdr[2] & 0xc0) >> 6;
+}
+
+extern "C" u_int8_t MP4AV_AdtsGetSamplingRateIndex(u_int8_t* pHdr)
+{
+	return (pHdr[2] & 0x3c) >> 2;
+}
+
+extern "C" u_int8_t MP4AV_AdtsFindSamplingRateIndex(u_int32_t samplingRate)
+{
+	for (u_int8_t i = 0; i < NUM_ADTS_SAMPLING_RATES; i++) {
+		if (samplingRate == AdtsSamplingRates[i]) {
+			return i;
+		}
+	}
+	return NUM_ADTS_SAMPLING_RATES - 1;
+}
+
+extern "C" u_int32_t MP4AV_AdtsGetSamplingRate(u_int8_t* pHdr)
+{
+	return AdtsSamplingRates[MP4AV_AdtsGetSamplingRateIndex(pHdr)];
+}
+
+extern "C" u_int8_t MP4AV_AdtsGetChannels(u_int8_t* pHdr)
+{
+	return ((pHdr[2] & 0x1) << 2) | ((pHdr[3] & 0xc0) >> 6);
+}
+
+extern "C" bool MP4AV_AdtsMakeFrameFromMp4Sample(
+	MP4FileHandle mp4File,
+	MP4TrackId trackId,
+	MP4SampleId sampleId,
+	u_int8_t** ppAdtsData,
+	u_int32_t* pAdtsDataLength)
+{
+	static MP4FileHandle lastMp4File = MP4_INVALID_FILE_HANDLE;
+	static MP4TrackId lastMp4TrackId = MP4_INVALID_TRACK_ID;
+	static bool isMpeg2;
+	static u_int8_t profile;
+	static u_int32_t samplingFrequency;
+	static u_int8_t channels;
+
+	if (mp4File != lastMp4File || trackId != lastMp4TrackId) {
+
+		// changed cached file and track info
+
+		lastMp4File = mp4File;
+		lastMp4TrackId = trackId;
+
+		u_int8_t audioType = MP4GetTrackAudioType(mp4File, trackId);
+
+		if (MP4_IS_MPEG2_AAC_AUDIO_TYPE(audioType)) {
+			isMpeg2 = true;
+			profile = audioType - MP4_MPEG2_AAC_MAIN_AUDIO_TYPE;
+		} else if (audioType == MP4_MPEG4_AUDIO_TYPE) {
+			isMpeg2 = false;
+			profile = MP4GetTrackAudioMpeg4Type(mp4File, trackId) - 1;
+		} else {
+			lastMp4File = MP4_INVALID_FILE_HANDLE;
+			lastMp4TrackId = MP4_INVALID_TRACK_ID;
+			return false;
+		}
+
+		u_int8_t* pConfig = NULL;
+		u_int32_t configLength;
+
+		MP4GetTrackESConfiguration(
+			mp4File, 
+			trackId,
+			&pConfig,
+			&configLength);
+
+		if (pConfig == NULL || configLength < 2) {
+			lastMp4File = MP4_INVALID_FILE_HANDLE;
+			lastMp4TrackId = MP4_INVALID_TRACK_ID;
+			return false;
+		}
+
+		samplingFrequency = MP4AV_AacConfigGetSamplingRate(pConfig);
+
+		channels = MP4AV_AacConfigGetChannels(pConfig);
+
+	}
+
+	bool rc;
+	u_int8_t* pSample = NULL;
+	u_int32_t sampleSize = 0;
+
+	rc = MP4ReadSample(
+		mp4File,
+		trackId,
+		sampleId,
+		&pSample,
+		&sampleSize);
+
+	if (!rc) {
+		return false;
+	}
+
+	rc = MP4AV_AdtsMakeFrame(
+		pSample,
+		sampleSize,
+		isMpeg2,
+		profile,
+		samplingFrequency,
+		channels,
+		ppAdtsData,
+		pAdtsDataLength);
+
+	free(pSample);
+
+	return rc;
+}
+
+extern "C" bool MP4AV_AdtsMakeFrame(
+	u_int8_t* pData,
+	u_int16_t dataLength,
+	bool isMpeg2,
+	u_int8_t profile,
+	u_int32_t samplingFrequency,
+	u_int8_t channels,
+	u_int8_t** ppAdtsData,
+	u_int32_t* pAdtsDataLength)
+{
+	*pAdtsDataLength = (isMpeg2 ? 7 : 8) + dataLength;
+
+	CMemoryBitstream adts;
+
+	try {
+		adts.AllocBytes(*pAdtsDataLength);
+		*ppAdtsData = adts.GetBuffer();
+
+		// build adts header
+		adts.PutBits(0xFFF, 12);		// syncword
+		adts.PutBits(isMpeg2, 1);		// id
+		adts.PutBits(0, 2);				// layer
+		adts.PutBits(1, 1);				// protection_absent
+		adts.PutBits(profile, 2);		// profile
+		adts.PutBits(
+			MP4AV_AdtsFindSamplingRateIndex(samplingFrequency),
+			4);							// sampling_frequency_index
+		adts.PutBits(0, 1);				// private
+		adts.PutBits(channels, 3);		// channel_configuration
+		adts.PutBits(0, 1);				// original
+		adts.PutBits(0, 1);				// home
+		adts.PutBits(0, 2);				// emphasis
+		adts.PutBits(0, 1);				// copyright_id
+		adts.PutBits(0, 1);				// copyright_id_start
+		adts.PutBits(*pAdtsDataLength, 13);	// aac_frame_length
+		adts.PutBits(0x7FF, 11);		// adts_buffer_fullness
+		adts.PutBits(1, 2);				// num_raw_data_blocks
+
+		// copy audio frame data
+		adts.PutBytes(pData, dataLength);
+	}
+	catch (int e) {
+		return false;
+	}
+
+	return true;
+}
+
--- /dev/null
+++ b/plugins/in_mp4/mp4av_adts.h
@@ -1,0 +1,86 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ * 
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ * 
+ * The Original Code is MPEG4IP.
+ * 
+ * The Initial Developer of the Original Code is Cisco Systems Inc.
+ * Portions created by Cisco Systems Inc. are
+ * Copyright (C) Cisco Systems Inc. 2000-2002.  All Rights Reserved.
+ * 
+ * Contributor(s): 
+ *		Dave Mackie		[email protected]
+ */
+
+#ifndef __MP4AV_ADTS_INCLUDED__
+#define __MP4AV_ADTS_INCLUDED__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define NUM_ADTS_SAMPLING_RATES	16
+
+extern u_int32_t AdtsSamplingRates[NUM_ADTS_SAMPLING_RATES];
+
+bool MP4AV_AdtsGetNextFrame(
+	u_int8_t* pSrc, 
+	u_int32_t srcLength,
+	u_int8_t** ppFrame, 
+	u_int32_t* pFrameSize);
+
+u_int16_t MP4AV_AdtsGetFrameSize(
+	u_int8_t* pHdr);
+
+u_int16_t MP4AV_AdtsGetHeaderBitSize(
+	u_int8_t* pHdr);
+
+u_int16_t MP4AV_AdtsGetHeaderByteSize(
+	u_int8_t* pHdr);
+
+u_int8_t MP4AV_AdtsGetVersion(
+	u_int8_t* pHdr);
+
+u_int8_t MP4AV_AdtsGetProfile(
+	u_int8_t* pHdr);
+
+u_int8_t MP4AV_AdtsGetSamplingRateIndex(
+	u_int8_t* pHdr);
+
+u_int8_t MP4AV_AdtsFindSamplingRateIndex(
+	u_int32_t samplingRate);
+
+u_int32_t MP4AV_AdtsGetSamplingRate(
+	u_int8_t* pHdr);
+
+u_int8_t MP4AV_AdtsGetChannels(
+	u_int8_t* pHdr);
+
+bool MP4AV_AdtsMakeFrame(
+	u_int8_t* pData,
+	u_int16_t dataLength,
+	bool isMpeg2,
+	u_int8_t profile,
+	u_int32_t samplingFrequency,
+	u_int8_t channels,
+	u_int8_t** ppAdtsData,
+	u_int32_t* pAdtsDataLength);
+
+bool MP4AV_AdtsMakeFrameFromMp4Sample(
+	MP4FileHandle mp4File,
+	MP4TrackId trackId,
+	MP4SampleId sampleId,
+	u_int8_t** ppAdtsData,
+	u_int32_t* pAdtsDataLength);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __MP4AV_ADTS_INCLUDED__ */
--- /dev/null
+++ b/plugins/in_mp4/mp4av_audio.cpp
@@ -1,0 +1,166 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ * 
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ * 
+ * The Original Code is MPEG4IP.
+ * 
+ * The Initial Developer of the Original Code is Cisco Systems Inc.
+ * Portions created by Cisco Systems Inc. are
+ * Copyright (C) Cisco Systems Inc. 2000-2002.  All Rights Reserved.
+ * 
+ * Contributor(s): 
+ *		Dave Mackie		[email protected]
+ */
+
+/* 
+ * Notes:
+ *  - file formatted with tabstops == 4 spaces 
+ */
+
+#include "mp4av_common.h"
+
+extern "C" u_int8_t MP4AV_AudioGetChannels(
+	MP4FileHandle mp4File, 
+	MP4TrackId audioTrackId)
+{
+	u_int8_t audioType = 
+		MP4GetTrackAudioType(mp4File, audioTrackId);
+
+	if (audioType == MP4_INVALID_AUDIO_TYPE) {
+		return 0;
+	}
+
+	if (MP4_IS_MP3_AUDIO_TYPE(audioType)) {
+			return 0;
+	} else if (MP4_IS_AAC_AUDIO_TYPE(audioType)) {
+		u_int8_t* pAacConfig = NULL;
+		u_int32_t aacConfigLength;
+
+		MP4GetTrackESConfiguration(
+			mp4File, 
+			audioTrackId,
+			&pAacConfig,
+			&aacConfigLength);
+
+		if (pAacConfig == NULL || aacConfigLength < 2) {
+			return 0;
+		}
+
+		u_int8_t channels =
+			MP4AV_AacConfigGetChannels(pAacConfig);
+
+		free(pAacConfig);
+
+		return channels;
+
+	} else if (audioType == MP4_PCM16_AUDIO_TYPE) {
+		u_int32_t samplesPerFrame =
+			MP4GetSampleSize(mp4File, audioTrackId, 1) / 2;
+
+		MP4Duration frameDuration =
+			MP4GetSampleDuration(mp4File, audioTrackId, 1);
+
+		if (frameDuration == 0) {
+			return 0;
+		}
+
+		// assumes track time scale == sampling rate
+		return samplesPerFrame / frameDuration;
+	}
+
+	return 0;
+}
+
+extern "C" u_int32_t MP4AV_AudioGetSamplingRate(
+	MP4FileHandle mp4File, 
+	MP4TrackId audioTrackId)
+{
+	u_int8_t audioType = 
+		MP4GetTrackAudioType(mp4File, audioTrackId);
+
+	if (audioType == MP4_INVALID_AUDIO_TYPE) {
+		return 0;
+	}
+
+	if (MP4_IS_MP3_AUDIO_TYPE(audioType)) {
+    	return 0;
+	} else if (MP4_IS_AAC_AUDIO_TYPE(audioType)) {
+		u_int8_t* pAacConfig = NULL;
+		u_int32_t aacConfigLength;
+
+		MP4GetTrackESConfiguration(
+			mp4File, 
+			audioTrackId,
+			&pAacConfig,
+			&aacConfigLength);
+
+		if (pAacConfig == NULL || aacConfigLength < 2) {
+			return 0;
+		}
+
+		u_int32_t samplingRate =
+			MP4AV_AacConfigGetSamplingRate(pAacConfig);
+
+		free(pAacConfig);
+
+		return samplingRate;
+
+	} else if (audioType == MP4_PCM16_AUDIO_TYPE) {
+		return MP4GetTrackTimeScale(mp4File, audioTrackId);
+	}
+
+	return 0;
+}
+
+extern "C" u_int16_t MP4AV_AudioGetSamplingWindow(
+	MP4FileHandle mp4File, 
+	MP4TrackId audioTrackId)
+{
+	u_int8_t audioType = 
+		MP4GetTrackAudioType(mp4File, audioTrackId);
+
+	if (audioType == MP4_INVALID_AUDIO_TYPE) {
+		return 0;
+	}
+
+	if (MP4_IS_MP3_AUDIO_TYPE(audioType)) {
+		return 0;
+	} else if (MP4_IS_AAC_AUDIO_TYPE(audioType)) {
+		u_int8_t* pAacConfig = NULL;
+		u_int32_t aacConfigLength;
+
+		MP4GetTrackESConfiguration(
+			mp4File, 
+			audioTrackId,
+			&pAacConfig,
+			&aacConfigLength);
+
+		if (pAacConfig == NULL || aacConfigLength < 2) {
+			return 0;
+		}
+
+		u_int32_t samplingWindow =
+			MP4AV_AacConfigGetSamplingWindow(pAacConfig);
+
+		free(pAacConfig);
+
+		return samplingWindow;
+
+	} else if (audioType == MP4_PCM16_AUDIO_TYPE) {
+		MP4Duration frameDuration =
+			MP4GetSampleDuration(mp4File, audioTrackId, 1);
+
+		// assumes track time scale == sampling rate
+		// and constant frame size was used
+		return frameDuration;
+	}
+
+	return 0;
+}
--- /dev/null
+++ b/plugins/in_mp4/mp4av_audio.h
@@ -1,0 +1,45 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ * 
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ * 
+ * The Original Code is MPEG4IP.
+ * 
+ * The Initial Developer of the Original Code is Cisco Systems Inc.
+ * Portions created by Cisco Systems Inc. are
+ * Copyright (C) Cisco Systems Inc. 2001-2002.  All Rights Reserved.
+ * 
+ * Contributor(s): 
+ *		Dave Mackie		[email protected]
+ */
+
+#ifndef __MP4AV_AUDIO_INCLUDED__
+#define __MP4AV_AUDIO_INCLUDED__ 
+
+// Audio Track Utitlites
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+u_int8_t MP4AV_AudioGetChannels(
+	MP4FileHandle mp4File, 
+	MP4TrackId audioTrackId);
+
+u_int32_t MP4AV_AudioGetSamplingRate(
+	MP4FileHandle mp4File, 
+	MP4TrackId audioTrackId);
+
+u_int16_t MP4AV_AudioGetSamplingWindow(
+	MP4FileHandle mp4File, 
+	MP4TrackId audioTrackId);
+#ifdef __cplusplus
+}
+#endif
+#endif /* __MP4AV_AUDIO_INCLUDED__ */ 
+
--- /dev/null
+++ b/plugins/in_mp4/mp4av_common.h
@@ -1,0 +1,32 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ * 
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ * 
+ * The Original Code is MPEG4IP.
+ * 
+ * The Initial Developer of the Original Code is Cisco Systems Inc.
+ * Portions created by Cisco Systems Inc. are
+ * Copyright (C) Cisco Systems Inc. 2001-2002.  All Rights Reserved.
+ * 
+ * Contributor(s): 
+ *		Dave Mackie		[email protected]
+ */
+
+#ifndef __MP4AV_COMMON_INCLUDED__
+#define __MP4AV_COMMON_INCLUDED__ 
+
+// the external interface
+#include "mp4av.h"
+
+// the internal interfaces
+#include "mbs.h"
+
+#endif /* __MP4AV_COMMON_INCLUDED__ */ 
+
--- a/plugins/in_mp4/resource.h
+++ b/plugins/in_mp4/resource.h
@@ -17,11 +17,15 @@
 #define IDC_16BITS                      1006
 #define IDC_VSIZE                       1007
 #define IDC_24BITS                      1007
+#define IDC_CONVERT                     1007
 #define IDC_VFPS                        1008
 #define IDC_32BITS                      1008
+#define IDC_CONVERT2                    1008
 #define IDC_CHANNELS                    1009
 #define IDC_24BITS2                     1009
 #define IDC_16BITS_DITHERED             1009
+#define IDC_CONVERT1                    1009
+#define IDC_USERDATA                    1010
 
 // Next default values for new objects
 // 
@@ -29,7 +33,7 @@
 #ifndef APSTUDIO_READONLY_SYMBOLS
 #define _APS_NEXT_RESOURCE_VALUE        103
 #define _APS_NEXT_COMMAND_VALUE         40001
-#define _APS_NEXT_CONTROL_VALUE         1007
+#define _APS_NEXT_CONTROL_VALUE         1011
 #define _APS_NEXT_SYMED_VALUE           101
 #endif
 #endif