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