ref: 3fc6ad0d7c312a7aea77ad7f0d52dae330a30488
parent: b8dedfd0147dbd2c548a4ecd7da9e3bd2c009190
author: menno <menno>
date: Sat Oct 5 11:21:31 EDT 2002
Now using mpeg4ip mp4av library
--- /dev/null
+++ b/common/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/common/mp4av/adts.cpp
@@ -1,0 +1,273 @@
+/*
+ * 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
+ if (!isMpeg2) {
+ 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(0, 2); // num_raw_data_blocks
+
+ // copy audio frame data
+ adts.PutBytes(pData, dataLength);
+ }
+ catch (int e) {
+ return false;
+ }
+
+ return true;
+}
+
--- /dev/null
+++ b/common/mp4av/audio.cpp
@@ -1,0 +1,212 @@
+/*
+ * 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>
+
+static MP4AV_Mp3Header GetMp3Header(
+ MP4FileHandle mp4File,
+ MP4TrackId audioTrackId)
+{
+ u_int8_t* pMp3Frame = NULL;
+ u_int32_t mp3FrameLength = 0;
+
+ bool rc = MP4ReadSample(
+ mp4File,
+ audioTrackId,
+ 1,
+ &pMp3Frame,
+ &mp3FrameLength);
+
+ if (!rc || mp3FrameLength < 4) {
+ return 0;
+ }
+
+ MP4AV_Mp3Header mp3Hdr =
+ MP4AV_Mp3HeaderFromBytes(pMp3Frame);
+ free(pMp3Frame);
+
+ return mp3Hdr;
+}
+
+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)) {
+ MP4AV_Mp3Header mp3Hdr =
+ GetMp3Header(mp4File, audioTrackId);
+
+ if (mp3Hdr == 0) {
+ return 0;
+ }
+ return MP4AV_Mp3GetChannels(mp3Hdr);
+
+ } 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_LITTLE_ENDIAN_AUDIO_TYPE) ||
+ (audioType == MP4_PCM16_BIG_ENDIAN_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)) {
+ MP4AV_Mp3Header mp3Hdr =
+ GetMp3Header(mp4File, audioTrackId);
+
+ if (mp3Hdr == 0) {
+ return 0;
+ }
+ return MP4AV_Mp3GetHdrSamplingRate(mp3Hdr);
+
+ } 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_LITTLE_ENDIAN_AUDIO_TYPE)||
+ (audioType == MP4_PCM16_BIG_ENDIAN_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)) {
+ MP4AV_Mp3Header mp3Hdr =
+ GetMp3Header(mp4File, audioTrackId);
+
+ return MP4AV_Mp3GetHdrSamplingWindow(mp3Hdr);
+
+ } 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_LITTLE_ENDIAN_AUDIO_TYPE)||
+ (audioType == MP4_PCM16_BIG_ENDIAN_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/common/mp4av/audio_hinters.cpp
@@ -1,0 +1,201 @@
+/*
+ * 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>
+
+bool MP4AV_AudioConsecutiveHinter(
+ MP4FileHandle mp4File,
+ MP4TrackId mediaTrackId,
+ MP4TrackId hintTrackId,
+ MP4Duration sampleDuration,
+ u_int8_t perPacketHeaderSize,
+ u_int8_t perSampleHeaderSize,
+ u_int8_t maxSamplesPerPacket,
+ u_int16_t maxPayloadSize,
+ MP4AV_AudioSampleSizer pSizer,
+ MP4AV_AudioConcatenator pConcatenator,
+ MP4AV_AudioFragmenter pFragmenter)
+{
+ bool rc;
+ u_int32_t numSamples =
+ MP4GetTrackNumberOfSamples(mp4File, mediaTrackId);
+
+ u_int16_t bytesThisHint = perPacketHeaderSize;
+ u_int16_t samplesThisHint = 0;
+ MP4SampleId* pSampleIds =
+ new MP4SampleId[maxSamplesPerPacket];
+
+ for (MP4SampleId sampleId = 1; sampleId <= numSamples; sampleId++) {
+
+ u_int32_t sampleSize =
+ (*pSizer)(mp4File, mediaTrackId, sampleId);
+
+ // sample won't fit in this packet
+ // or we've reached the limit on samples per packet
+ if ((int16_t)(sampleSize + perSampleHeaderSize)
+ > maxPayloadSize - bytesThisHint
+ || samplesThisHint == maxSamplesPerPacket) {
+
+ if (samplesThisHint > 0) {
+ rc = (*pConcatenator)(mp4File, mediaTrackId, hintTrackId,
+ samplesThisHint, pSampleIds,
+ samplesThisHint * sampleDuration,
+ maxPayloadSize);
+
+ if (!rc) {
+ return false;
+ }
+ }
+
+ // start a new hint
+ samplesThisHint = 0;
+ bytesThisHint = perPacketHeaderSize;
+
+ // fall thru
+ }
+
+ // sample is less than remaining payload size
+ if ((int16_t)(sampleSize + perSampleHeaderSize)
+ <= maxPayloadSize - bytesThisHint) {
+
+ // add it to this hint
+ bytesThisHint += (sampleSize + perSampleHeaderSize);
+ pSampleIds[samplesThisHint++] = sampleId;
+
+ } else {
+ // jumbo frame, need to fragment it
+ rc = (*pFragmenter)(mp4File, mediaTrackId, hintTrackId,
+ sampleId, sampleSize, sampleDuration, maxPayloadSize);
+
+ if (!rc) {
+ return false;
+ }
+
+ // start a new hint
+ samplesThisHint = 0;
+ bytesThisHint = perPacketHeaderSize;
+ }
+ }
+
+ delete [] pSampleIds;
+
+ return true;
+}
+
+bool MP4AV_AudioInterleaveHinter(
+ MP4FileHandle mp4File,
+ MP4TrackId mediaTrackId,
+ MP4TrackId hintTrackId,
+ MP4Duration sampleDuration,
+ u_int8_t stride,
+ u_int8_t bundle,
+ u_int16_t maxPayloadSize,
+ MP4AV_AudioConcatenator pConcatenator)
+{
+ bool rc;
+ u_int32_t numSamples =
+ MP4GetTrackNumberOfSamples(mp4File, mediaTrackId);
+
+ MP4SampleId* pSampleIds = new MP4SampleId[bundle];
+
+ for (u_int32_t i = 1; i <= numSamples; i += stride * bundle) {
+ for (u_int32_t j = 0; j < stride; j++) {
+ u_int32_t k;
+ for (k = 0; k < bundle; k++) {
+
+ MP4SampleId sampleId = i + j + (k * stride);
+
+ // out of samples for this bundle
+ if (sampleId > numSamples) {
+ break;
+ }
+
+ // add sample to this hint
+ pSampleIds[k] = sampleId;
+ }
+
+ if (k == 0) {
+ break;
+ }
+
+ // compute hint duration
+ // note this is used to control the RTP timestamps
+ // that are emitted for the packet,
+ // it isn't the actual duration of the samples in the packet
+ MP4Duration hintDuration;
+ if (j + 1 == stride) {
+ // at the end of the track
+ if (i + (stride * bundle) > numSamples) {
+ hintDuration = ((numSamples - i) - j) * sampleDuration;
+ } else {
+ hintDuration = ((stride * bundle) - j) * sampleDuration;
+ }
+ } else {
+ hintDuration = sampleDuration;
+ }
+
+ // write hint
+ rc = (*pConcatenator)(mp4File, mediaTrackId, hintTrackId,
+ k, pSampleIds, hintDuration, maxPayloadSize);
+
+ if (!rc) {
+ return false;
+ }
+ }
+ }
+
+ delete [] pSampleIds;
+
+ return true;
+}
+
+MP4Duration MP4AV_GetAudioSampleDuration(
+ MP4FileHandle mp4File,
+ MP4TrackId mediaTrackId)
+{
+ MP4SampleId sampleId = 1;
+ MP4SampleId numSamples =
+ MP4GetTrackNumberOfSamples(mp4File, mediaTrackId);
+
+ // find first non-zero size sample
+ // we need to search in case an empty audio sample has been added
+ // at the beginning of the track to achieve sync with video
+ for (; sampleId <= numSamples; sampleId++) {
+ if (MP4GetSampleSize(mp4File, mediaTrackId, sampleId) > 0) {
+ break;
+ }
+ }
+ if (sampleId >= numSamples) {
+ return MP4_INVALID_DURATION;
+ }
+
+ // get sample duration
+ return MP4GetSampleDuration(mp4File, mediaTrackId, sampleId);
+
+ // OPTION may want to scan all non-zero sized samples
+ // and check that sample durations are +/-1 the same value
+}
+
--- /dev/null
+++ b/common/mp4av/audio_hinters.h
@@ -1,0 +1,78 @@
+/*
+ * 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 __AUDIO_HINTERS_INCLUDED__
+#define __AUDIO_HINTERS_INCLUDED__
+
+// Generic Audio Hinters
+
+typedef u_int32_t (*MP4AV_AudioSampleSizer)(
+ MP4FileHandle mp4File,
+ MP4TrackId mediaTrackId,
+ MP4SampleId sampleId);
+
+typedef bool (*MP4AV_AudioConcatenator)(
+ MP4FileHandle mp4File,
+ MP4TrackId mediaTrackId,
+ MP4TrackId hintTrackId,
+ u_int8_t samplesThisHint,
+ MP4SampleId* pSampleIds,
+ MP4Duration hintDuration,
+ u_int16_t maxPayloadSize);
+
+typedef bool (*MP4AV_AudioFragmenter)(
+ MP4FileHandle mp4File,
+ MP4TrackId mediaTrackId,
+ MP4TrackId hintTrackId,
+ MP4SampleId sampleId,
+ u_int32_t sampleSize,
+ MP4Duration sampleDuration,
+ u_int16_t maxPayloadSize);
+
+bool MP4AV_AudioConsecutiveHinter(
+ MP4FileHandle mp4File,
+ MP4TrackId mediaTrackId,
+ MP4TrackId hintTrackId,
+ MP4Duration sampleDuration,
+ u_int8_t perPacketHeaderSize,
+ u_int8_t perSampleHeaderSize,
+ u_int8_t maxSamplesPerPacket,
+ u_int16_t maxPayloadSize,
+ MP4AV_AudioSampleSizer pSizer,
+ MP4AV_AudioConcatenator pConcatenator,
+ MP4AV_AudioFragmenter pFragmenter);
+
+bool MP4AV_AudioInterleaveHinter(
+ MP4FileHandle mp4File,
+ MP4TrackId mediaTrackId,
+ MP4TrackId hintTrackId,
+ MP4Duration sampleDuration,
+ u_int8_t stride,
+ u_int8_t bundle,
+ u_int16_t maxPayloadSize,
+ MP4AV_AudioConcatenator pConcatenator);
+
+MP4Duration MP4AV_GetAudioSampleDuration(
+ MP4FileHandle mp4File,
+ MP4TrackId mediaTrackId);
+
+#endif /* __AUDIO_HINTERS_INCLUDED__ */
+
--- /dev/null
+++ b/common/mp4av/l16.cpp
@@ -1,0 +1,167 @@
+/*
+ * 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. 2002. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Bill May [email protected]
+ */
+
+#include <mp4av_common.h>
+
+//#define DEBUG_L16 1
+extern "C" bool L16Hinter (MP4FileHandle mp4file,
+ MP4TrackId trackid,
+ uint16_t maxPayloadSize)
+{
+ uint32_t numSamples;
+ uint8_t audioType;
+ MP4SampleId sampleId;
+ uint32_t sampleSize;
+ MP4Duration duration;
+ char buffer[40];
+ MP4TrackId hintTrackId;
+ uint8_t payload;
+ int chans;
+ uint32_t bytes_this_hint;
+ uint32_t sampleOffset;
+
+#ifdef DEBUG_L16
+ printf("time scale %u\n", MP4GetTrackTimeScale(mp4file, trackid));
+
+ printf("Track fixed sample %llu\n", MP4GetTrackFixedSampleDuration(mp4file, trackid));
+#endif
+
+ numSamples = MP4GetTrackNumberOfSamples(mp4file, trackid);
+
+ if (numSamples == 0) return false;
+
+
+#ifdef DEBUG_L16
+ for (unsigned int ix = 1; ix < MIN(10, numSamples); ix++) {
+ printf("sampleId %d, size %u duration %llu time %llu\n",
+ ix, MP4GetSampleSize(mp4file, trackid, ix),
+ MP4GetSampleDuration(mp4file, trackid, ix),
+ MP4GetSampleTime(mp4file, trackid, ix));
+ }
+#endif
+
+ audioType = MP4GetTrackAudioType(mp4file, trackid);
+
+ if (audioType != MP4_PCM16_BIG_ENDIAN_AUDIO_TYPE) return false;
+
+ sampleId = 1;
+ while ((sampleSize = MP4GetSampleSize(mp4file, trackid, sampleId)) == 0) {
+ if (sampleId >= numSamples) return false;
+ sampleId++;
+ }
+
+ // we have a sampleID with a size. Give me duration, and we know the
+ // number of channels based on the sample size for that duration
+ duration = MP4GetSampleDuration(mp4file, trackid, sampleId);
+
+ sampleSize /= sizeof(uint16_t);
+
+ if ((sampleSize % duration) != 0) {
+#ifdef DEBUG_L16
+ printf("Number of samples not correct - duration %llu sample %d\n",
+ duration, sampleSize);
+#endif
+ return false;
+ }
+
+ chans = sampleSize / duration;
+ snprintf(buffer, sizeof(buffer), "%d", chans);
+
+ hintTrackId = MP4AddHintTrack(mp4file, trackid);
+
+ if (hintTrackId == MP4_INVALID_TRACK_ID) {
+ return false;
+ }
+
+ payload = 0;
+ if (MP4GetTrackTimeScale(mp4file, trackid) == 44100) {
+ if (chans == 1) payload = 11;
+ else if (chans == 2) payload = 10;
+ }
+ MP4SetHintTrackRtpPayload(mp4file, hintTrackId, "L16", &payload, 0,
+ chans == 1 ? NULL : buffer);
+
+ sampleId = 1;
+ sampleSize = MP4GetSampleSize(mp4file, trackid, sampleId);
+ sampleOffset = 0;
+ bytes_this_hint = 0;
+
+ if (maxPayloadSize & 0x1) maxPayloadSize--;
+
+ while (1) {
+ if (bytes_this_hint == 0) {
+#ifdef DEBUG_L16
+ printf("Adding hint/packet\n");
+#endif
+ MP4AddRtpHint(mp4file, hintTrackId);
+ MP4AddRtpPacket(mp4file, hintTrackId, false); // marker bit 0
+ }
+ uint16_t bytes_left_this_packet;
+ bytes_left_this_packet = maxPayloadSize - bytes_this_hint;
+ if (sampleSize >= bytes_left_this_packet) {
+ MP4AddRtpSampleData(mp4file, hintTrackId,
+ sampleId, sampleOffset, bytes_left_this_packet);
+ bytes_this_hint += bytes_left_this_packet;
+ sampleSize -= bytes_left_this_packet;
+ sampleOffset += bytes_left_this_packet;
+#ifdef DEBUG_L16
+ printf("Added sample with %d bytes\n", bytes_left_this_packet);
+#endif
+ } else {
+ MP4AddRtpSampleData(mp4file, hintTrackId,
+ sampleId, sampleOffset, sampleSize);
+ bytes_this_hint += sampleSize;
+#ifdef DEBUG_L16
+ printf("Added sample with %d bytes\n", sampleSize);
+#endif
+ sampleSize = 0;
+ }
+
+ if (bytes_this_hint >= maxPayloadSize) {
+ // Write the hint
+ // duration is 1/2 of the bytes written
+ MP4WriteRtpHint(mp4file, hintTrackId, bytes_this_hint / (2 * chans));
+#ifdef DEBUG_L16
+ printf("Finished packet - bytes %d\n", bytes_this_hint);
+#endif
+ bytes_this_hint = 0;
+ }
+ if (sampleSize == 0) {
+ // next sample
+ sampleId++;
+ if (sampleId > numSamples) {
+ // finish it and exit
+ if (bytes_this_hint != 0) {
+ MP4WriteRtpHint(mp4file, hintTrackId, bytes_this_hint / 2);
+ return true;
+ }
+ }
+ sampleSize = MP4GetSampleSize(mp4file, trackid, sampleId);
+#ifdef DEBUG_L16
+ printf("Next sample %d - size %d\n", sampleId, sampleSize);
+#endif
+ sampleOffset = 0;
+ }
+ }
+
+ return true; // will never reach here
+}
+
--- /dev/null
+++ b/common/mp4av/libmp4av.dsp
@@ -1,0 +1,184 @@
+# Microsoft Developer Studio Project File - Name="libmp4av" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Static Library" 0x0104
+
+CFG=libmp4av - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "libmp4av.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "libmp4av.mak" CFG="libmp4av - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "libmp4av - Win32 Release" (based on "Win32 (x86) Static Library")
+!MESSAGE "libmp4av - Win32 Debug" (based on "Win32 (x86) Static Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "libmp4av - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "libmp4av___Win32_Release"
+# PROP BASE Intermediate_Dir "libmp4av___Win32_Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "MRelease"
+# PROP Intermediate_Dir "MRelease"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /I "..\mp4v2" /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo
+
+!ELSEIF "$(CFG)" == "libmp4av - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "MDebug"
+# PROP Intermediate_Dir "MDebug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "." /I "..\mp4v2" /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /D "_WIN32" /D "_WINDOWS" /YX /FD /GZ /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo
+
+!ENDIF
+
+# Begin Target
+
+# Name "libmp4av - Win32 Release"
+# Name "libmp4av - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\aac.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\adts.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\audio.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\audio_hinters.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\mbs.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\mp3.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\mpeg3.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\mpeg4.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\rfc2250.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\rfc3016.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\rfc3119.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\rfcisma.cpp
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\audio_hinters.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\mbs.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\mp4av.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\mp4av_aac.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\mp4av_adts.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\mp4av_audio.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\mp4av_common.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\mp4av_hinters.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\mp4av_mp3.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\mp4av_mpeg3.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\mp4av_mpeg4.h
+# End Source File
+# End Group
+# End Target
+# End Project
--- /dev/null
+++ b/common/mp4av/libmp4av_st.dsp
@@ -1,0 +1,176 @@
+# Microsoft Developer Studio Project File - Name="libmp4av_st" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Static Library" 0x0104
+
+CFG=libmp4av_st - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "libmp4av_st.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "libmp4av_st.mak" CFG="libmp4av_st - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "libmp4av_st - Win32 Release" (based on "Win32 (x86) Static Library")
+!MESSAGE "libmp4av_st - Win32 Debug" (based on "Win32 (x86) Static Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "libmp4av_st - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /I "..\mp4v2" /I ".\\" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo
+
+!ELSEIF "$(CFG)" == "libmp4av_st - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\mp4v2" /I ".\\" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo
+
+!ENDIF
+
+# Begin Target
+
+# Name "libmp4av_st - Win32 Release"
+# Name "libmp4av_st - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\aac.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\adts.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\audio_hinters.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\l16.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\mbs.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\mp3.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\mpeg3.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\mpeg4.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\rfc2250.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\rfc3016.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\rfc3119.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\rfcisma.cpp
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\audio_hinters.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\mbs.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\mp4av.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\mp4av_aac.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\mp4av_adts.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\mp4av_common.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\mp4av_hinters.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\mp4av_mp3.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\mp4av_mpeg4.h
+# End Source File
+# End Group
+# End Target
+# End Project
--- /dev/null
+++ b/common/mp4av/libmp4av_st.vcproj
@@ -1,0 +1,180 @@
+<?xml version="1.0" encoding = "Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.00"
+ Name="libmp4av_st"
+ ProjectGUID="{8CAC9E26-BAA5-45A4-8721-E3170B3F8F49}"
+ SccProjectName=""
+ SccLocalPath="">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory=".\Release"
+ IntermediateDirectory=".\Release"
+ ConfigurationType="4"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ InlineFunctionExpansion="1"
+ AdditionalIncludeDirectories="..\mp4v2,.\"
+ PreprocessorDefinitions="WIN32,NDEBUG,_LIB"
+ StringPooling="TRUE"
+ RuntimeLibrary="4"
+ EnableFunctionLevelLinking="TRUE"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderFile=".\Release/libmp4av_st.pch"
+ AssemblerListingLocation=".\Release/"
+ ObjectFile=".\Release/"
+ ProgramDataBaseFileName=".\Release/"
+ WarningLevel="3"
+ SuppressStartupBanner="TRUE"
+ CompileAs="0"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile=".\Release\libmp4av_st.lib"
+ SuppressStartupBanner="TRUE"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1033"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory=".\Debug"
+ IntermediateDirectory=".\Debug"
+ ConfigurationType="4"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\mp4v2,.\"
+ PreprocessorDefinitions="WIN32,_DEBUG,_LIB"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="5"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderFile=".\Debug/libmp4av_st.pch"
+ AssemblerListingLocation=".\Debug/"
+ ObjectFile=".\Debug/"
+ ProgramDataBaseFileName=".\Debug/"
+ WarningLevel="3"
+ SuppressStartupBanner="TRUE"
+ DebugInformationFormat="4"
+ CompileAs="0"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile=".\Debug\libmp4av_st.lib"
+ SuppressStartupBanner="TRUE"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="1033"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ </Configuration>
+ </Configurations>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
+ <File
+ RelativePath=".\aac.cpp">
+ </File>
+ <File
+ RelativePath=".\adts.cpp">
+ </File>
+ <File
+ RelativePath=".\audio_hinters.cpp">
+ </File>
+ <File
+ RelativePath=".\l16.cpp">
+ </File>
+ <File
+ RelativePath=".\mbs.cpp">
+ </File>
+ <File
+ RelativePath=".\mp3.cpp">
+ </File>
+ <File
+ RelativePath=".\mpeg3.cpp">
+ </File>
+ <File
+ RelativePath=".\mpeg4.cpp">
+ </File>
+ <File
+ RelativePath=".\rfc2250.cpp">
+ </File>
+ <File
+ RelativePath=".\rfc3016.cpp">
+ </File>
+ <File
+ RelativePath=".\rfc3119.cpp">
+ </File>
+ <File
+ RelativePath=".\rfcisma.cpp">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl">
+ <File
+ RelativePath=".\audio_hinters.h">
+ </File>
+ <File
+ RelativePath=".\mbs.h">
+ </File>
+ <File
+ RelativePath=".\mp4av.h">
+ </File>
+ <File
+ RelativePath=".\mp4av_aac.h">
+ </File>
+ <File
+ RelativePath=".\mp4av_adts.h">
+ </File>
+ <File
+ RelativePath=".\mp4av_common.h">
+ </File>
+ <File
+ RelativePath=".\mp4av_hinters.h">
+ </File>
+ <File
+ RelativePath=".\mp4av_mp3.h">
+ </File>
+ <File
+ RelativePath=".\mp4av_mpeg4.h">
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
--- /dev/null
+++ b/common/mp4av/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/common/mp4av/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/common/mp4av/mp3.cpp
@@ -1,0 +1,350 @@
+/*
+ * 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>
+
+static u_int16_t Mp3BitRates[5][14] = {
+ /* MPEG-1, Layer III */
+ { 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320 },
+ /* MPEG-1, Layer II */
+ { 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384 },
+ /* MPEG-1, Layer I */
+ { 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448 },
+ /* MPEG-2 or 2.5, Layer II or III */
+ { 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160 },
+ /* MPEG-2 or 2.5, Layer I */
+ { 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256 }
+};
+
+static u_int16_t Mp3SampleRates[4][3] = {
+ { 11025, 12000, 8000 }, /* MPEG-2.5 */
+ { 0, 0, 0 },
+ { 22050, 24000, 16000 }, /* MPEG-2 */
+ { 44100, 48000, 32000 } /* MPEG-1 */
+};
+
+extern "C" bool MP4AV_Mp3GetNextFrame(
+ const u_int8_t* pSrc,
+ u_int32_t srcLength,
+ const u_int8_t** ppFrame,
+ u_int32_t* pFrameSize,
+ bool allowLayer4,
+ bool donthack)
+{
+ u_int state = 0;
+ u_int dropped = 0;
+ u_char bytes[4];
+ u_int32_t srcPos = 0;
+
+ while (true) {
+ /* read a byte */
+ if (srcPos >= srcLength) {
+ return false;
+ }
+ u_char b = pSrc[srcPos++];
+
+ if (state == 3) {
+ bytes[state] = b;
+ *ppFrame = pSrc + dropped;
+ u_int32_t header = (bytes[0] << 24) | (bytes[1] << 16)
+ | (bytes[2] << 8) | bytes[3];
+ *pFrameSize = MP4AV_Mp3GetFrameSize(header);
+ return true;
+ }
+ if (state == 2) {
+ if ((b & 0xF0) == 0 || (b & 0xF0) == 0xF0 || (b & 0x0C) == 0x0C) {
+ if (bytes[1] == 0xFF) {
+ state = 1;
+ } else {
+ state = 0;
+ }
+ } else {
+ bytes[state] = b;
+ state = 3;
+ }
+ }
+ if (state == 1) {
+ if ((b & 0xE0) == 0xE0 && (b & 0x18) != 0x08 &&
+ ((b & 0x06) != 0 || allowLayer4)) {
+ bytes[state] = b;
+ state = 2;
+ } else {
+ state = 0;
+ }
+ }
+ if (state == 0) {
+ if (b == 0xFF) {
+ bytes[state] = b;
+ state = 1;
+ } else {
+ if (donthack == FALSE &&
+ (dropped == 0 &&
+ ((b & 0xE0) == 0xE0 &&
+ (b & 0x18) != 0x08 &&
+ ((b & 0x06) != 0 || allowLayer4)))) {
+ /*
+ * HACK have seen files where previous frame
+ * was marked as padded, but the byte was never added
+ * which results in the next frame's leading 0XFF being
+ * eaten. We attempt to repair that situation here.
+ */
+ bytes[0] = 0xFF;
+ bytes[1] = b;
+ state = 2;
+ } else {
+ /* else drop it */
+ dropped++;
+ }
+ }
+ }
+ }
+}
+
+extern "C" MP4AV_Mp3Header MP4AV_Mp3HeaderFromBytes(const u_int8_t* pBytes)
+{
+ return (pBytes[0] << 24) | (pBytes[1] << 16)
+ | (pBytes[2] << 8) | pBytes[3];
+}
+
+// MP3 Header
+// syncword 11 bits
+// version 2 bits
+// layer 2 bits
+// protection 1 bit
+// bitrate_index 4 bits
+// sampling_rate 2 bits
+// padding 1 bit
+// private 1 bit
+// mode 2 bits
+// mode_ext 2 bits
+// copyright 1 bit
+// original 1 bit
+// emphasis 2 bits
+
+extern "C" u_int8_t MP4AV_Mp3GetHdrVersion(MP4AV_Mp3Header hdr)
+{
+ /* extract the necessary field from the MP3 header */
+ return ((hdr >> 19) & 0x3);
+}
+
+extern "C" u_int8_t MP4AV_Mp3GetHdrLayer(MP4AV_Mp3Header hdr)
+{
+ /* extract the necessary field from the MP3 header */
+ return ((hdr >> 17) & 0x3);
+}
+
+extern "C" u_int8_t MP4AV_Mp3GetChannels(MP4AV_Mp3Header hdr)
+{
+ if (((hdr >> 6) & 0x3) == 3) {
+ return 1;
+ }
+ return 2;
+}
+
+extern "C" u_int16_t MP4AV_Mp3GetHdrSamplingRate(MP4AV_Mp3Header hdr)
+{
+ /* extract the necessary fields from the MP3 header */
+ u_int8_t version = MP4AV_Mp3GetHdrVersion(hdr);
+ u_int8_t sampleRateIndex = (hdr >> 10) & 0x3;
+
+ return Mp3SampleRates[version][sampleRateIndex];
+}
+
+extern "C" u_int16_t MP4AV_Mp3GetHdrSamplingWindow(MP4AV_Mp3Header hdr)
+{
+ u_int8_t version = MP4AV_Mp3GetHdrVersion(hdr);
+ u_int8_t layer = MP4AV_Mp3GetHdrLayer(hdr);
+ u_int16_t samplingWindow;
+
+ if (layer == 1) {
+ if (version == 3) {
+ samplingWindow = 1152;
+ } else {
+ samplingWindow = 576;
+ }
+ } else if (layer == 2) {
+ samplingWindow = 1152;
+ } else {
+ samplingWindow = 384;
+ }
+
+ return samplingWindow;
+}
+
+extern "C" u_int16_t MP4AV_Mp3GetSamplingWindow(u_int16_t samplingRate)
+{
+ // assumes MP3 usage
+ if (samplingRate > 24000) {
+ return 1152;
+ }
+ return 576;
+}
+
+extern "C" u_int16_t MP4AV_Mp3GetBitRate (MP4AV_Mp3Header hdr)
+{
+ u_int8_t version = MP4AV_Mp3GetHdrVersion(hdr);
+ u_int8_t layer = MP4AV_Mp3GetHdrLayer(hdr);
+ u_int8_t bitRateIndex1;
+ u_int8_t bitRateIndex2 = (hdr >> 12) & 0xF;
+
+ if (version == 3) {
+ /* MPEG-1 */
+ bitRateIndex1 = layer - 1;
+ } else {
+ /* MPEG-2 or MPEG-2.5 */
+ if (layer == 3) {
+ /* Layer I */
+ bitRateIndex1 = 4;
+ } else {
+ bitRateIndex1 = 3;
+ }
+ }
+ return Mp3BitRates[bitRateIndex1][bitRateIndex2-1];
+}
+/*
+ * compute MP3 frame size
+ */
+extern "C" u_int16_t MP4AV_Mp3GetFrameSize(MP4AV_Mp3Header hdr)
+{
+ /* extract the necessary fields from the MP3 header */
+ u_int8_t version = MP4AV_Mp3GetHdrVersion(hdr);
+ u_int8_t layer = MP4AV_Mp3GetHdrLayer(hdr);
+ u_int8_t bitRateIndex1;
+ u_int8_t bitRateIndex2 = (hdr >> 12) & 0xF;
+ u_int8_t sampleRateIndex = (hdr >> 10) & 0x3;
+ bool isPadded = (hdr >> 9) & 0x1;
+ u_int16_t frameSize = 0;
+
+ if (version == 3) {
+ /* MPEG-1 */
+ bitRateIndex1 = layer - 1;
+ } else {
+ /* MPEG-2 or MPEG-2.5 */
+ if (layer == 3) {
+ /* Layer I */
+ bitRateIndex1 = 4;
+ } else {
+ bitRateIndex1 = 3;
+ }
+ }
+
+ /* compute frame size */
+ frameSize = (144 * 1000 * Mp3BitRates[bitRateIndex1][bitRateIndex2-1])
+ / (Mp3SampleRates[version][sampleRateIndex] << !(version & 1));
+
+ if (isPadded) {
+ if (layer == 3) {
+ /* Layer I */
+ frameSize += 4; /* 4 byte pad is present */
+ } else {
+ frameSize++; /* 1 byte pad is present */
+ }
+ }
+
+ return frameSize;
+}
+
+extern "C" u_int16_t
+MP4AV_Mp3GetAduOffset(const u_int8_t* pFrame, u_int32_t frameSize)
+{
+ if (frameSize < 2) {
+ return 0;
+ }
+
+ u_int8_t version = (pFrame[1] >> 3) & 0x3;
+ u_int8_t layer = (pFrame[1] >> 1) & 0x3;
+ bool isProtected = !(pFrame[1] & 0x1);
+ u_int8_t crcSize = isProtected ? 2 : 0;
+
+ // protect against garbage input
+ if (frameSize < (u_int32_t)(5 + crcSize + (version == 3 ? 1 : 0))) {
+ return 0;
+ }
+ if (layer != 1) {
+ return 0;
+ }
+
+ if (version == 3) {
+ // MPEG-1
+ return (pFrame[4 + crcSize] << 1) | (pFrame[5 + crcSize] >> 7);
+ } else {
+ // MPEG-2 or 2.5
+ return pFrame[4 + crcSize];
+ }
+}
+
+extern "C" u_int8_t MP4AV_Mp3GetCrcSize(MP4AV_Mp3Header hdr)
+{
+ return ((hdr & 0x00010000) ? 0 : 2);
+}
+
+extern "C" u_int8_t MP4AV_Mp3GetSideInfoSize(MP4AV_Mp3Header hdr)
+{
+ u_int8_t version = MP4AV_Mp3GetHdrVersion(hdr);
+ u_int8_t layer = MP4AV_Mp3GetHdrLayer(hdr);
+ u_int8_t mode = (hdr >> 6) & 0x3;
+ u_int8_t channels = (mode == 3 ? 1 : 2);
+
+ // check that this is layer 3
+ if (layer != 1) {
+ return 0;
+ }
+
+ if (version == 3) {
+ // MPEG-1
+ if (channels == 1) {
+ return 17;
+ } else {
+ return 32;
+ }
+ } else {
+ // MPEG-2 or 2.5
+ if (channels == 1) {
+ return 9;
+ } else {
+ return 17;
+ }
+ }
+}
+
+extern "C" u_int8_t MP4AV_Mp3ToMp4AudioType(u_int8_t mpegVersion)
+{
+ u_int8_t audioType = MP4_INVALID_AUDIO_TYPE;
+
+ switch (mpegVersion) {
+ case 3:
+ audioType = MP4_MPEG1_AUDIO_TYPE;
+ break;
+ case 2:
+ case 0:
+ audioType = MP4_MPEG2_AUDIO_TYPE;
+ break;
+ case 1:
+ break;
+ }
+ return audioType;
+}
+
--- /dev/null
+++ b/common/mp4av/mp4av.h
@@ -1,0 +1,46 @@
+/*
+ * 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_mp3.h"
+#include "mp4av_mpeg4.h"
+#include "mp4av_audio.h"
+#include "mp4av_hinters.h"
+#include "mp4av_mpeg3.h"
+
+#undef DEFAULT_PARM
+
+#endif /* __MP4AV_INCLUDED__ */
+
--- /dev/null
+++ b/common/mp4av/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/common/mp4av/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/common/mp4av/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/common/mp4av/mp4av_common.h
@@ -1,0 +1,33 @@
+/*
+ * 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"
+#include "audio_hinters.h"
+
+#endif /* __MP4AV_COMMON_INCLUDED__ */
+
--- /dev/null
+++ b/common/mp4av/mp4av_hinters.h
@@ -1,0 +1,71 @@
+/*
+ * 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_HINTERS_INCLUDED__
+#define __MP4AV_HINTERS_INCLUDED__
+
+#define MP4AV_DFLT_PAYLOAD_SIZE 1460
+
+// Audio Hinters
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+bool MP4AV_Rfc2250Hinter(
+ MP4FileHandle mp4File,
+ MP4TrackId mediaTrackId,
+ bool interleave DEFAULT_PARM(false),
+ u_int16_t maxPayloadSize DEFAULT_PARM(MP4AV_DFLT_PAYLOAD_SIZE));
+
+bool MP4AV_Rfc3119Hinter(
+ MP4FileHandle mp4File,
+ MP4TrackId mediaTrackId,
+ bool interleave DEFAULT_PARM(false),
+ u_int16_t maxPayloadSize DEFAULT_PARM(MP4AV_DFLT_PAYLOAD_SIZE));
+
+bool MP4AV_RfcIsmaHinter(
+ MP4FileHandle mp4File,
+ MP4TrackId mediaTrackId,
+ bool interleave DEFAULT_PARM(false),
+ u_int16_t maxPayloadSize DEFAULT_PARM(MP4AV_DFLT_PAYLOAD_SIZE));
+
+
+// Video Hinters
+
+bool MP4AV_Rfc3016Hinter(
+ MP4FileHandle mp4File,
+ MP4TrackId mediaTrackId,
+ u_int16_t maxPayloadSize DEFAULT_PARM(MP4AV_DFLT_PAYLOAD_SIZE));
+
+bool L16Hinter(MP4FileHandle mp4File,
+ MP4TrackId mediaTrackID,
+ uint16_t maxPayloadSize DEFAULT_PARM(MP4AV_DFLT_PAYLOAD_SIZE));
+
+bool Mpeg12Hinter(MP4FileHandle mp4File,
+ MP4TrackId mediaTrackID,
+ uint16_t maxPayloadSize DEFAULT_PARM(MP4AV_DFLT_PAYLOAD_SIZE));
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MP4AV_HINTERS_INCLUDED__ */
+
--- /dev/null
+++ b/common/mp4av/mp4av_mp3.h
@@ -1,0 +1,68 @@
+/*
+ * 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_MP3_INCLUDED__
+#define __MP4AV_MP3_INCLUDED__
+
+typedef u_int32_t MP4AV_Mp3Header;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+bool MP4AV_Mp3GetNextFrame(
+ const u_int8_t* pSrc,
+ u_int32_t srcLength,
+ const u_int8_t** ppFrame,
+ u_int32_t* pFrameSize,
+ bool allowLayer4 DEFAULT_PARM(false),
+ bool donthack DEFAULT_PARM(false));
+
+MP4AV_Mp3Header MP4AV_Mp3HeaderFromBytes(const u_int8_t* pBytes);
+
+u_int8_t MP4AV_Mp3GetHdrVersion(MP4AV_Mp3Header hdr);
+
+u_int8_t MP4AV_Mp3GetHdrLayer(MP4AV_Mp3Header hdr);
+
+u_int8_t MP4AV_Mp3GetChannels(MP4AV_Mp3Header hdr);
+
+u_int16_t MP4AV_Mp3GetHdrSamplingRate(MP4AV_Mp3Header hdr);
+
+u_int16_t MP4AV_Mp3GetHdrSamplingWindow(MP4AV_Mp3Header hdr);
+
+u_int16_t MP4AV_Mp3GetSamplingWindow(u_int16_t samplingRate);
+
+u_int16_t MP4AV_Mp3GetBitRate(MP4AV_Mp3Header hdr);
+
+u_int16_t MP4AV_Mp3GetFrameSize(MP4AV_Mp3Header hdr);
+
+u_int16_t MP4AV_Mp3GetAduOffset(const u_int8_t* pFrame, u_int32_t frameSize);
+
+u_int8_t MP4AV_Mp3GetCrcSize(MP4AV_Mp3Header hdr);
+
+u_int8_t MP4AV_Mp3GetSideInfoSize(MP4AV_Mp3Header hdr);
+
+u_int8_t MP4AV_Mp3ToMp4AudioType(u_int8_t mpegVersion);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __MP4AV_MP3_INCLUDED__ */
--- /dev/null
+++ b/common/mp4av/mp4av_mpeg3.h
@@ -1,0 +1,40 @@
+/*
+ * 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. 2002. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Bill May ([email protected])
+ */
+#ifndef __MP4AV_MPEG3_H__
+#define __MP4AV_MPEG3_H__ 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ int MP4AV_Mpeg3ParseSeqHdr(uint8_t *pbuffer, uint32_t buflen,
+ int *have_mpeg2,
+ uint32_t *height, uint32_t *width,
+ double *frame_rate, double *bitrate);
+
+ int MP4AV_Mpeg3PictHdrType(uint8_t *pbuffer);
+
+ int MP4AV_Mpeg3FindGopOrPictHdr(uint8_t *pbuffer, uint32_t buflen, int *ftype);
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- /dev/null
+++ b/common/mp4av/mp4av_mpeg4.h
@@ -1,0 +1,97 @@
+/*
+ * 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_MPEG4_INCLUDED__
+#define __MP4AV_MPEG4_INCLUDED__
+
+#define MP4AV_MPEG4_SYNC 0x000001
+#define MP4AV_MPEG4_VOSH_START 0xB0
+#define MP4AV_MPEG4_VOL_START 0x20
+#define MP4AV_MPEG4_GOV_START 0xB3
+#define MP4AV_MPEG4_VO_START 0xB5
+#define MP4AV_MPEG4_VOP_START 0xB6
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+bool MP4AV_Mpeg4ParseVosh(
+ u_int8_t* pVoshBuf,
+ u_int32_t voshSize,
+ u_int8_t* pProfileLevel);
+
+bool MP4AV_Mpeg4CreateVosh(
+ u_int8_t** ppBytes,
+ u_int32_t* pNumBytes,
+ u_int8_t profileLevel);
+
+bool MP4AV_Mpeg4CreateVo(
+ u_int8_t** ppBytes,
+ u_int32_t* pNumBytes,
+ u_int8_t objectId);
+
+bool MP4AV_Mpeg4ParseVol(
+ u_int8_t* pVolBuf,
+ u_int32_t volSize,
+ u_int8_t* pTimeBits,
+ u_int16_t* pTimeTicks,
+ u_int16_t* pFrameDuration,
+ u_int16_t* pFrameWidth,
+ u_int16_t* pFrameHeight);
+
+bool MP4AV_Mpeg4CreateVol(
+ u_int8_t** ppBytes,
+ u_int32_t* pNumBytes,
+ u_int8_t profile,
+ float frameRate,
+ bool shortTime,
+ bool variableRate,
+ u_int16_t width,
+ u_int16_t height,
+ u_int8_t quantType,
+ u_int8_t* pTimeBits DEFAULT_PARM(NULL));
+
+bool MP4AV_Mpeg4ParseGov(
+ u_int8_t* pGovBuf,
+ u_int32_t govSize,
+ u_int8_t* pHours,
+ u_int8_t* pMinutes,
+ u_int8_t* pSeconds);
+
+bool MP4AV_Mpeg4ParseVop(
+ u_int8_t* pVopBuf,
+ u_int32_t vopSize,
+ u_char* pVopType,
+ u_int8_t timeBits,
+ u_int16_t timeTicks,
+ u_int32_t* pVopTimeIncrement);
+
+u_int8_t MP4AV_Mpeg4VideoToSystemsProfileLevel(
+ u_int8_t videoProfileLevel);
+
+u_char MP4AV_Mpeg4GetVopType(
+ u_int8_t* pVopBuf,
+ u_int32_t vopSize);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __MP4AV_MPEG4_INCLUDED__ */
--- /dev/null
+++ b/common/mp4av/mpeg3.cpp
@@ -1,0 +1,450 @@
+/*
+ * 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. 2002. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Bill May ([email protected])
+ */
+
+#include "mpeg4ip.h"
+#include "mp4av.h"
+
+//#define DEBUG_MPEG3_HINT 1
+
+static double mpeg3_frame_rate_table[16] =
+{
+ 0.0, /* Pad */
+ 24000.0/1001.0, /* Official frame rates */
+ 24.0,
+ 25.0,
+ 30000.0/1001.0,
+ 30.0,
+ 50.0,
+ ((60.0*1000.0)/1001.0),
+ 60.0,
+
+ 1, /* Unofficial economy rates */
+ 5,
+ 10,
+ 12,
+ 15,
+ 0,
+ 0,
+};
+#define MPEG3_START_CODE_PREFIX 0x000001
+#define MPEG3_SEQUENCE_START_CODE 0x000001b3
+#define MPEG3_PICTURE_START_CODE 0x00000100
+#define MPEG3_GOP_START_CODE 0x000001b8
+#define MPEG3_EXT_START_CODE 0x000001b5
+#define MPEG3_SLICE_MIN_START 0x00000101
+#define MPEG3_SLICE_MAX_START 0x000001af
+
+#define SEQ_ID 1
+extern "C" int MP4AV_Mpeg3ParseSeqHdr (uint8_t *pbuffer,
+ uint32_t buflen,
+ int *have_mpeg2,
+ uint32_t *height,
+ uint32_t *width,
+ double *frame_rate,
+ double *bitrate)
+{
+ uint32_t framerate_code;
+ uint32_t bitrate_int;
+ uint32_t bitrate_ext;
+#if 1
+ uint32_t scode, ix;
+ int found = -1;
+ *have_mpeg2 = 0;
+ buflen -= 6;
+ bitrate_int = 0;
+ for (ix = 0; ix < buflen; ix++, pbuffer++) {
+ scode = (pbuffer[0] << 24) | (pbuffer[1] << 16) | (pbuffer[2] << 8) |
+ pbuffer[3];
+
+ if (scode == MPEG3_SEQUENCE_START_CODE) {
+ pbuffer += sizeof(uint32_t);
+ *width = (pbuffer[0]);
+ *width <<= 4;
+ *width |= ((pbuffer[1] >> 4) &0xf);
+ *height = (pbuffer[1] & 0xf);
+ *height <<= 8;
+ *height |= pbuffer[2];
+ framerate_code = pbuffer[3] & 0xf;
+ *frame_rate = mpeg3_frame_rate_table[framerate_code];
+ // 18 bits
+ bitrate_int = (pbuffer[4] << 10) |
+ (pbuffer[5] << 2) |
+ ((pbuffer[6] >> 6) & 0x3);
+ *bitrate = bitrate_int;
+ *bitrate *= 400.0;
+ ix += sizeof(uint32_t) + 7;
+ pbuffer += 7;
+ found = 0;
+ } else if (found == 0) {
+ if (scode == MPEG3_EXT_START_CODE) {
+ pbuffer += sizeof(uint32_t);
+ ix += sizeof(uint32_t);
+ switch ((pbuffer[0] >> 4) & 0xf) {
+ case SEQ_ID:
+ *have_mpeg2 = 1;
+ *height = ((pbuffer[1] & 0x1) << 13) |
+ ((pbuffer[2] & 0x80) << 5) |
+ (*height & 0x0fff);
+ *width = (((pbuffer[2] >> 5) & 0x3) << 12) | (*width & 0x0fff);
+ bitrate_ext = (pbuffer[2] & 0x1f) << 7;
+ bitrate_ext |= (pbuffer[3] >> 1) & 0x7f;
+ bitrate_int |= (bitrate_ext << 18);
+ *bitrate = bitrate_int;
+ *bitrate *= 400.0;
+ break;
+ default:
+ break;
+ }
+ pbuffer++;
+ ix++;
+ } else if (scode == MPEG3_PICTURE_START_CODE) {
+ return found;
+ }
+ }
+ }
+ return found;
+
+#else
+ // if you want to do the whole frame
+ int ix;
+ CBitstream bs(pbuffer, buflen);
+
+
+ try {
+
+ while (bs.PeekBits(32) != MPEG3_SEQUENCE_START_CODE) {
+ bs.GetBits(8);
+ }
+
+ bs.GetBits(32); // start code
+
+ *height = bs.GetBits(12);
+ *width = bs.GetBits(12);
+ bs.GetBits(4);
+ framerate_code = bs.GetBits(4);
+ *frame_rate = mpeg3_frame_rate_table[framerate_code];
+
+ bs.GetBits(18); // bitrate
+ bs.GetBits(1); // marker bit
+ bs.GetBits(10); // vbv buffer
+ bs.GetBits(1); // constrained params
+ if (bs.GetBits(1)) { // intra_quantizer_matrix
+ for (ix = 0; ix < 64; ix++) {
+ bs.GetBits(8);
+ }
+ }
+ if (bs.GetBits(1)) { // non_intra_quantizer_matrix
+ for (ix = 0; ix < 64; ix++) {
+ bs.GetBits(8);
+ }
+ }
+ } catch (...) {
+ return false;
+ }
+ return true;
+#endif
+}
+
+extern "C" int MP4AV_Mpeg3PictHdrType (uint8_t *pbuffer)
+{
+ pbuffer += sizeof(uint32_t);
+ return ((pbuffer[1] >> 3) & 0x7);
+}
+
+static int FindNextStart (uint8_t *pbuffer,
+ uint32_t buflen,
+ uint32_t *optr,
+ uint32_t *scode)
+{
+ uint32_t value;
+ uint32_t offset;
+
+ for (offset = 0; offset < buflen; offset++, pbuffer++) {
+ value = (pbuffer[0] << 16) | (pbuffer[1] << 8) | (pbuffer[2] << 0);
+
+ if (value == MPEG3_START_CODE_PREFIX) {
+ *optr = offset;
+ *scode = (value << 8) | pbuffer[3];
+ return 0;
+ }
+ }
+ return -1;
+}
+
+static int FindNextSliceStart (uint8_t *pbuffer,
+ uint32_t startoffset,
+ uint32_t buflen,
+ uint32_t *slice_offset)
+{
+ uint32_t slicestart, code;
+ while (FindNextStart(pbuffer + startoffset,
+ buflen - startoffset,
+ &slicestart,
+ &code) >= 0) {
+#ifdef DEBUG_MPEG3_HINT
+ printf("Code %x at offset %d\n",
+ code, startoffset + slicestart);
+#endif
+ if ((code >= MPEG3_SLICE_MIN_START) &&
+ (code <= MPEG3_SLICE_MAX_START)) {
+ *slice_offset = slicestart + startoffset;
+ return 0;
+ }
+ startoffset += slicestart + 4;
+ }
+ return -1;
+}
+
+extern "C" int MP4AV_Mpeg3FindGopOrPictHdr (uint8_t *pbuffer,
+ uint32_t buflen,
+ int *frame_type)
+{
+ uint32_t value;
+ uint32_t offset;
+ int ftype;
+ for (offset = 0; offset < buflen; offset++, pbuffer++) {
+ value = (pbuffer[0] << 24) | (pbuffer[1] << 16) | (pbuffer[2] << 8) |
+ pbuffer[3];
+
+ if (value == MPEG3_PICTURE_START_CODE) {
+ ftype = MP4AV_Mpeg3PictHdrType(pbuffer);
+ if (frame_type != NULL) *frame_type = ftype;
+ if (ftype == 1) {
+ return 0;
+ } else {
+ return -1;
+ }
+ } else if (value == MPEG3_GOP_START_CODE) {
+ return 1;
+ }
+ }
+ return -1;
+}
+
+extern "C" bool Mpeg12Hinter (MP4FileHandle mp4file,
+ MP4TrackId trackid,
+ uint16_t maxPayloadSize)
+{
+ uint32_t numSamples, maxSampleSize;
+ uint8_t videoType;
+ uint8_t rfc2250[4], rfc2250_2;
+ uint32_t offset;
+ uint32_t scode;
+ int have_seq;
+ bool stop;
+ uint8_t *buffer, *pbuffer;
+ uint8_t *pstart;
+ uint8_t type;
+ uint32_t next_slice, prev_slice;
+ bool slice_at_begin;
+ uint32_t sampleSize;
+ MP4SampleId sid;
+
+ MP4TrackId hintTrackId;
+
+ numSamples = MP4GetTrackNumberOfSamples(mp4file, trackid);
+ maxSampleSize = MP4GetTrackMaxSampleSize(mp4file, trackid);
+
+ if (numSamples == 0) return false;
+
+ videoType = MP4GetTrackVideoType(mp4file, trackid);
+
+ if (videoType != MP4_MPEG1_VIDEO_TYPE &&
+ videoType != MP4_MPEG2_VIDEO_TYPE) {
+ return false;
+ }
+
+ hintTrackId = MP4AddHintTrack(mp4file, trackid);
+ if (hintTrackId == MP4_INVALID_TRACK_ID) {
+ return false;
+ }
+
+ uint8_t payload = 32;
+ MP4SetHintTrackRtpPayload(mp4file, hintTrackId, "MPV", &payload, 0);
+
+
+ buffer = (uint8_t *)malloc(maxSampleSize);
+ if (buffer == NULL) {
+ MP4DeleteTrack(mp4file, hintTrackId);
+ return false;
+ }
+
+ maxPayloadSize -= 24; // this is for the 4 byte header
+
+ for (sid = 1; sid <= numSamples; sid++) {
+ sampleSize = maxSampleSize;
+ MP4Timestamp startTime;
+ MP4Duration duration;
+ MP4Duration renderingOffset;
+ bool isSyncSample;
+
+ bool rc = MP4ReadSample(mp4file, trackid, sid,
+ &buffer, &sampleSize,
+ &startTime, &duration,
+ &renderingOffset, &isSyncSample);
+#ifdef DEBUG_MPEG3_HINT
+ printf("sid %d - sample size %d\n", sid, sampleSize);
+#endif
+ if (rc == false) {
+ MP4DeleteTrack(mp4file, hintTrackId);
+ return false;
+ }
+
+ // need to add rfc2250 header
+ offset = 0;
+ have_seq = 0;
+ pbuffer = buffer;
+ stop = false;
+ do {
+ uint32_t oldoffset;
+ oldoffset = offset;
+ if (FindNextStart(pbuffer + offset,
+ sampleSize - offset,
+ &offset,
+ &scode) < 0) {
+ // didn't find the start code
+#ifdef DEBUG_MPEG3_HINT
+ printf("didn't find start code\n");
+#endif
+ stop = true;
+ } else {
+ offset += oldoffset;
+#ifdef DEBUG_MPEG3_HINT
+ printf("next sscode %x found at %d\n", scode, offset);
+#endif
+ if (scode == MPEG3_SEQUENCE_START_CODE) have_seq = 1;
+ offset += 4; // start with next value
+ }
+ } while (scode != MPEG3_PICTURE_START_CODE && stop == false);
+
+ pstart = pbuffer + offset; // point to inside of picture start
+ type = (pstart[1] >> 3) & 0x7;
+
+ rfc2250[0] = (*pstart >> 6) & 0x3;
+ rfc2250[1] = (pstart[0] << 2) | ((pstart[1] >> 6) & 0x3); // temporal ref
+ rfc2250[2] = type;
+ if (have_seq != 0) {
+ rfc2250[2] |= 0x20;
+ have_seq = 0;
+ }
+ rfc2250_2 = rfc2250[2];
+
+ rfc2250[3] = 0;
+ if (type == 2 || type == 3) {
+ rfc2250[3] = pstart[3] << 5;
+ if ((pstart[4] & 0x80) != 0) rfc2250[3] |= 0x10;
+ if (type == 3) {
+ rfc2250[3] |= (pstart[4] >> 3) & 0xf;
+ }
+ }
+
+ MP4AddRtpVideoHint(mp4file, hintTrackId, type == 3, renderingOffset);
+ // Find the next slice. Then we can add the header if the next
+ // slice will be in the start. This lets us set the S bit in
+ // rfc2250[2]. Then we need to loop to find the next slice that's
+ // not in the buffer size - this should be in the while loop.
+
+ prev_slice = 0;
+ if (FindNextSliceStart(pbuffer, offset, sampleSize, &next_slice) < 0) {
+ slice_at_begin = false;
+ } else {
+ slice_at_begin = true;
+ }
+
+#ifdef DEBUG_MPEG3_HINT
+ printf("starting slice at %d\n", next_slice);
+#endif
+ offset = 0;
+ bool nomoreslices = false;
+ bool found_slice = slice_at_begin;
+ bool onfirst = true;
+
+ while (sampleSize > 0) {
+ bool isLastPacket;
+ uint32_t len_to_write;
+
+ if (sampleSize <= maxPayloadSize) {
+ // leave started_slice alone
+ len_to_write = sampleSize;
+ isLastPacket = true;
+ prev_slice = 0;
+ } else {
+ found_slice = (onfirst == false) && (nomoreslices == false) && (next_slice <= maxPayloadSize);
+ onfirst = false;
+ isLastPacket = false;
+
+ while (nomoreslices == false && next_slice <= maxPayloadSize) {
+ prev_slice = next_slice;
+ if (FindNextSliceStart(pbuffer, next_slice + 4, sampleSize, &next_slice) >= 0) {
+#ifdef DEBUG_MPEG3_HINT
+ printf("prev_slice %u next slice %u %u\n", prev_slice, next_slice,
+ offset + next_slice);
+#endif
+ found_slice = true;
+ } else {
+ // at end
+ nomoreslices = true;
+ }
+ }
+ // prev_slice should have the end value. If it's not 0, we have
+ // the end of the slice.
+ if (found_slice) len_to_write = prev_slice;
+ else len_to_write = MIN(maxPayloadSize, sampleSize);
+ }
+
+ rfc2250[2] = rfc2250_2;
+ if (slice_at_begin) {
+ rfc2250[2] |= 0x10; // set b bit
+ }
+ if (found_slice || isLastPacket) {
+ rfc2250[2] |= 0x08; // set end of slice bit
+ slice_at_begin = true; // for next time
+ } else {
+ slice_at_begin = false;
+ }
+
+#ifdef DEBUG_MPEG3_HINT
+ printf("Adding packet, sid %u prev slice %u len_to_write %u\n",
+ sid, prev_slice, len_to_write);
+ printf("Next slice %u offset %u %x %x %x %x\n\n",
+ next_slice, offset,
+ rfc2250[0], rfc2250[1], rfc2250[2], rfc2250[3]);
+#endif
+
+ // okay - we can now write out this packet.
+ MP4AddRtpPacket(mp4file, hintTrackId, isLastPacket);
+ // add the 4 byte header
+ MP4AddRtpImmediateData(mp4file, hintTrackId, rfc2250, sizeof(rfc2250));
+
+ // add the immediate data
+ MP4AddRtpSampleData(mp4file, hintTrackId, sid, offset, len_to_write);
+ offset += len_to_write;
+ sampleSize -= len_to_write;
+ prev_slice = 0;
+ next_slice -= len_to_write;
+ pbuffer += len_to_write;
+ }
+ MP4WriteRtpHint(mp4file, hintTrackId, duration, type == 1);
+ }
+
+ free(buffer);
+ return true;
+}
--- /dev/null
+++ b/common/mp4av/mpeg4.cpp
@@ -1,0 +1,572 @@
+/*
+ * 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" bool MP4AV_Mpeg4ParseVosh(
+ u_int8_t* pVoshBuf,
+ u_int32_t voshSize,
+ u_int8_t* pProfileLevel)
+{
+ CMemoryBitstream vosh;
+
+ vosh.SetBytes(pVoshBuf, voshSize);
+
+ try {
+ vosh.GetBits(32); // start code
+ *pProfileLevel = vosh.GetBits(8);
+ }
+ catch (int e) {
+ return false;
+ }
+
+ return true;
+}
+
+extern "C" bool MP4AV_Mpeg4CreateVosh(
+ u_int8_t** ppBytes,
+ u_int32_t* pNumBytes,
+ u_int8_t profileLevel)
+{
+ CMemoryBitstream vosh;
+
+ try {
+ if (*ppBytes) {
+ // caller must guarantee buffer against overrun
+ memset((*ppBytes) + (*pNumBytes), 0, 5);
+ vosh.SetBytes(*ppBytes, (*pNumBytes) + 5);
+ vosh.SetBitPosition((*pNumBytes) << 3);
+ } else {
+ vosh.AllocBytes(5);
+ }
+
+ vosh.PutBits(MP4AV_MPEG4_SYNC, 24);
+ vosh.PutBits(MP4AV_MPEG4_VOSH_START, 8);
+ vosh.PutBits(profileLevel, 8);
+
+ *ppBytes = vosh.GetBuffer();
+ *pNumBytes = vosh.GetNumberOfBytes();
+ }
+ catch (int e) {
+ return false;
+ }
+
+ return true;
+}
+
+extern "C" bool MP4AV_Mpeg4CreateVo(
+ u_int8_t** ppBytes,
+ u_int32_t* pNumBytes,
+ u_int8_t objectId)
+{
+ CMemoryBitstream vo;
+
+ try {
+ if (*ppBytes) {
+ // caller must guarantee buffer against overrun
+ memset((*ppBytes) + (*pNumBytes), 0, 9);
+ vo.SetBytes(*ppBytes, *pNumBytes + 9);
+ vo.SetBitPosition((*pNumBytes) << 3);
+ } else {
+ vo.AllocBytes(9);
+ }
+
+ vo.PutBits(MP4AV_MPEG4_SYNC, 24);
+ vo.PutBits(MP4AV_MPEG4_VO_START, 8);
+ vo.PutBits(0x08, 8); // no verid, priority, or signal type
+ vo.PutBits(MP4AV_MPEG4_SYNC, 24);
+ vo.PutBits(objectId - 1, 8);
+
+ *ppBytes = vo.GetBuffer();
+ *pNumBytes = vo.GetNumberOfBytes();
+ }
+ catch (int e) {
+ return false;
+ }
+
+ return true;
+}
+
+extern "C" bool MP4AV_Mpeg4ParseVol(
+ u_int8_t* pVolBuf,
+ u_int32_t volSize,
+ u_int8_t* pTimeBits,
+ u_int16_t* pTimeTicks,
+ u_int16_t* pFrameDuration,
+ u_int16_t* pFrameWidth,
+ u_int16_t* pFrameHeight)
+{
+ CMemoryBitstream vol;
+
+ vol.SetBytes(pVolBuf, volSize);
+
+ try {
+ vol.SkipBits(32); // start code
+
+ vol.SkipBits(1); // random accessible vol
+ vol.SkipBits(8); // object type id
+ u_int8_t verid = 0;
+ if (vol.GetBits(1)) { // is object layer id
+ verid = vol.GetBits(4); // object layer verid
+ vol.SkipBits(3); // object layer priority
+ }
+ if (vol.GetBits(4) == 0xF) { // aspect ratio info
+ vol.SkipBits(8); // par width
+ vol.SkipBits(8); // par height
+ }
+ if (vol.GetBits(1)) { // vol control parameters
+ vol.SkipBits(2); // chroma format
+ vol.SkipBits(1); // low delay
+ if (vol.GetBits(1)) { // vbv parameters
+ vol.SkipBits(15); // first half bit rate
+ vol.SkipBits(1); // marker bit
+ vol.SkipBits(15); // latter half bit rate
+ vol.SkipBits(1); // marker bit
+ vol.SkipBits(15); // first half vbv buffer size
+ vol.SkipBits(1); // marker bit
+ vol.SkipBits(3); // latter half vbv buffer size
+ vol.SkipBits(11); // first half vbv occupancy
+ vol.SkipBits(1); // marker bit
+ vol.SkipBits(15); // latter half vbv occupancy
+ vol.SkipBits(1); // marker bit
+ }
+ }
+ u_int8_t shape = vol.GetBits(2); // object layer shape
+ if (shape == 3 /* GRAYSCALE */ && verid != 1) {
+ vol.SkipBits(4); // object layer shape extension
+ }
+ vol.SkipBits(1); // marker bit
+ *pTimeTicks = vol.GetBits(16); // vop time increment resolution
+
+ u_int8_t i;
+ u_int32_t powerOf2 = 1;
+ for (i = 0; i < 16; i++) {
+ if (*pTimeTicks < powerOf2) {
+ break;
+ }
+ powerOf2 <<= 1;
+ }
+ *pTimeBits = i;
+
+ vol.SkipBits(1); // marker bit
+ if (vol.GetBits(1)) { // fixed vop rate
+ // fixed vop time increment
+ *pFrameDuration = vol.GetBits(*pTimeBits);
+ } else {
+ *pFrameDuration = 0;
+ }
+ if (shape == 0 /* RECTANGULAR */) {
+ vol.SkipBits(1); // marker bit
+ *pFrameWidth = vol.GetBits(13); // object layer width
+ vol.SkipBits(1); // marker bit
+ *pFrameHeight = vol.GetBits(13);// object layer height
+ vol.SkipBits(1); // marker bit
+ } else {
+ *pFrameWidth = 0;
+ *pFrameHeight = 0;
+ }
+ // there's more, but we don't need it
+ }
+ catch (int e) {
+ return false;
+ }
+
+ return true;
+}
+
+extern "C" bool MP4AV_Mpeg4CreateVol(
+ u_int8_t** ppBytes,
+ u_int32_t* pNumBytes,
+ u_int8_t profile,
+ float frameRate,
+ bool shortTime,
+ bool variableRate,
+ u_int16_t width,
+ u_int16_t height,
+ u_int8_t quantType,
+ u_int8_t* pTimeBits)
+{
+ CMemoryBitstream vol;
+
+ try {
+ if (*ppBytes) {
+ // caller must guarantee buffer against overrun
+ memset((*ppBytes) + (*pNumBytes), 0, 20);
+ vol.SetBytes(*ppBytes, *pNumBytes + 20);
+ vol.SetBitPosition((*pNumBytes) << 3);
+ } else {
+ vol.AllocBytes(20);
+ }
+
+ /* VOL - Video Object Layer */
+ vol.PutBits(MP4AV_MPEG4_SYNC, 24);
+ vol.PutBits(MP4AV_MPEG4_VOL_START, 8);
+
+ /* 1 bit - random access = 0 (1 only if every VOP is an I frame) */
+ vol.PutBits(0, 1);
+ /*
+ * 8 bits - type indication
+ * = 1 (simple profile)
+ * = 4 (main profile)
+ */
+ vol.PutBits(profile, 8);
+ /* 1 bit - is object layer id = 1 */
+ vol.PutBits(1, 1);
+ /* 4 bits - visual object layer ver id = 2 */
+ vol.PutBits(2, 4);
+ /* 3 bits - visual object layer priority = 1 */
+ vol.PutBits(1, 3);
+
+ /* 4 bits - aspect ratio info = 1 (square pixels) */
+ vol.PutBits(1, 4);
+ /* 1 bit - VOL control params = 0 */
+ vol.PutBits(0, 1);
+ /* 2 bits - VOL shape = 0 (rectangular) */
+ vol.PutBits(0, 2);
+ /* 1 bit - marker = 1 */
+ vol.PutBits(1, 1);
+
+ u_int16_t ticks;
+ if (shortTime /* && frameRate == (float)((int)frameRate) */) {
+ ticks = (u_int16_t)(frameRate + 0.5);
+ } else {
+ ticks = 30000;
+ }
+ /* 16 bits - VOP time increment resolution */
+ vol.PutBits(ticks, 16);
+ /* 1 bit - marker = 1 */
+ vol.PutBits(1, 1);
+
+ u_int8_t rangeBits = 1;
+ while (ticks > (1 << rangeBits)) {
+ rangeBits++;
+ }
+ if (pTimeBits) {
+ *pTimeBits = rangeBits;
+ }
+
+ /* 1 bit - fixed vop rate = 0 or 1 */
+ if (variableRate) {
+ vol.PutBits(0, 1);
+ } else {
+ vol.PutBits(1, 1);
+
+ u_int16_t frameDuration =
+ (u_int16_t)((float)ticks / frameRate);
+
+ /* 1-16 bits - fixed vop time increment in ticks */
+ vol.PutBits(frameDuration, rangeBits);
+ }
+ /* 1 bit - marker = 1 */
+ vol.PutBits(1, 1);
+ /* 13 bits - VOL width */
+ vol.PutBits(width, 13);
+ /* 1 bit - marker = 1 */
+ vol.PutBits(1, 1);
+ /* 13 bits - VOL height */
+ vol.PutBits(height, 13);
+ /* 1 bit - marker = 1 */
+ vol.PutBits(1, 1);
+ /* 1 bit - interlaced = 0 */
+ vol.PutBits(0, 1);
+
+ /* 1 bit - overlapped block motion compensation disable = 1 */
+ vol.PutBits(1, 1);
+ /* 2 bits - sprite usage = 0 */
+ vol.PutBits(0, 2);
+ /* 1 bit - not 8 bit pixels = 0 */
+ vol.PutBits(0, 1);
+ /* 1 bit - quant type = 0 */
+ vol.PutBits(quantType, 1);
+ if (quantType) {
+ /* 1 bit - load intra quant mat = 0 */
+ vol.PutBits(0, 1);
+ /* 1 bit - load inter quant mat = 0 */
+ vol.PutBits(0, 1);
+ }
+ /* 1 bit - quarter pixel = 0 */
+ vol.PutBits(0, 1);
+ /* 1 bit - complexity estimation disable = 1 */
+ vol.PutBits(1, 1);
+ /* 1 bit - resync marker disable = 1 */
+ vol.PutBits(1, 1);
+ /* 1 bit - data partitioned = 0 */
+ vol.PutBits(0, 1);
+ /* 1 bit - newpred = 0 */
+ vol.PutBits(0, 1);
+ /* 1 bit - reduced resolution vop = 0 */
+ vol.PutBits(0, 1);
+ /* 1 bit - scalability = 0 */
+ vol.PutBits(0, 1);
+
+ /* pad to byte boundary with 0 then as many 1's as needed */
+ vol.PutBits(0, 1);
+ if ((vol.GetBitPosition() & 7) != 0) {
+ vol.PutBits(0xFF, 8 - (vol.GetBitPosition() & 7));
+ }
+
+ *ppBytes = vol.GetBuffer();
+ *pNumBytes = vol.GetBitPosition() >> 3;
+ }
+ catch (int e) {
+ return false;
+ }
+
+ return true;
+}
+
+extern "C" bool MP4AV_Mpeg4ParseGov(
+ u_int8_t* pGovBuf,
+ u_int32_t govSize,
+ u_int8_t* pHours,
+ u_int8_t* pMinutes,
+ u_int8_t* pSeconds)
+{
+ CMemoryBitstream gov;
+
+ gov.SetBytes(pGovBuf, govSize);
+
+ try {
+ gov.SkipBits(32); // start code
+ *pHours = gov.GetBits(5);
+ *pMinutes = gov.GetBits(6);
+ gov.SkipBits(1); // marker bit
+ *pSeconds = gov.GetBits(6);
+ }
+ catch (int e) {
+ return false;
+ }
+
+ return true;
+}
+
+static bool Mpeg4ParseShortHeaderVop(
+ u_int8_t* pVopBuf,
+ u_int32_t vopSize,
+ u_char* pVopType)
+{
+ CMemoryBitstream vop;
+
+ vop.SetBytes(pVopBuf, vopSize);
+
+ try {
+ // skip start code, temporal ref, and into type
+ vop.SkipBits(22 + 8 + 5 + 3);
+ if (vop.GetBits(1) == 0) {
+ *pVopType = 'I';
+ } else {
+ *pVopType = 'P';
+ }
+ }
+ catch (int e) {
+ return false;
+ }
+
+ return true;
+}
+
+extern "C" bool MP4AV_Mpeg4ParseVop(
+ u_int8_t* pVopBuf,
+ u_int32_t vopSize,
+ u_char* pVopType,
+ u_int8_t timeBits,
+ u_int16_t timeTicks,
+ u_int32_t* pVopTimeIncrement)
+{
+ CMemoryBitstream vop;
+
+ vop.SetBytes(pVopBuf, vopSize);
+
+ try {
+ vop.SkipBits(32); // skip start code
+
+ switch (vop.GetBits(2)) {
+ case 0:
+ /* Intra */
+ *pVopType = 'I';
+ break;
+ case 1:
+ /* Predictive */
+ *pVopType = 'P';
+ break;
+ case 2:
+ /* Bidirectional Predictive */
+ *pVopType = 'B';
+ break;
+ case 3:
+ /* Sprite */
+ *pVopType = 'S';
+ break;
+ }
+
+ if (!pVopTimeIncrement) {
+ return true;
+ }
+
+ u_int8_t numSecs = 0;
+ while (vop.GetBits(1) != 0) {
+ numSecs++;
+ }
+ vop.SkipBits(1); // skip marker
+ u_int16_t numTicks = vop.GetBits(timeBits);
+ *pVopTimeIncrement = (numSecs * timeTicks) + numTicks;
+ }
+ catch (int e) {
+ return false;
+ }
+
+ return true;
+}
+
+// Map from ISO IEC 14496-2:2000 Appendix G
+// to ISO IEC 14496-1:2001 8.6.4.2 Table 6
+extern "C" u_int8_t
+MP4AV_Mpeg4VideoToSystemsProfileLevel(u_int8_t videoProfileLevel)
+{
+ switch (videoProfileLevel) {
+ // Simple Profile
+ case 0x01: // L1
+ return 0x03;
+ case 0x02: // L2
+ return 0x02;
+ case 0x03: // L3
+ return 0x01;
+ // Simple Scalable Profile
+ case 0x11: // L1
+ return 0x05;
+ case 0x12: // L2
+ return 0x04;
+ // Core Profile
+ case 0x21: // L1
+ return 0x07;
+ case 0x22: // L2
+ return 0x06;
+ // Main Profile
+ case 0x32: // L2
+ return 0x0A;
+ case 0x33: // L3
+ return 0x09;
+ case 0x34: // L4
+ return 0x08;
+ // N-bit Profile
+ case 0x42: // L2
+ return 0x0B;
+ // Scalable Texture
+ case 0x51: // L1
+ return 0x12;
+ case 0x52: // L2
+ return 0x11;
+ case 0x53: // L3
+ return 0x10;
+ // Simple Face Animation Profile
+ case 0x61: // L1
+ return 0x14;
+ case 0x62: // L2
+ return 0x13;
+ // Simple FBA Profile
+ case 0x63: // L1
+ case 0x64: // L2
+ return 0xFE;
+ // Basic Animated Texture Profile
+ case 0x71: // L1
+ return 0x0F;
+ case 0x72: // L2
+ return 0x0E;
+ // Hybrid Profile
+ case 0x81: // L1
+ return 0x0D;
+ case 0x82: // L2
+ return 0x0C;
+ // Advanced Real Time Simple Profile
+ case 0x91: // L1
+ case 0x92: // L2
+ case 0x93: // L3
+ case 0x94: // L4
+ // Core Scalable Profile
+ case 0xA1: // L1
+ case 0xA2: // L2
+ case 0xA3: // L3
+ // Advanced Coding Efficiency Profle
+ case 0xB1: // L1
+ case 0xB2: // L2
+ case 0xB3: // L3
+ case 0xB4: // L4
+ // Advanced Core Profile
+ case 0xC1: // L1
+ case 0xC2: // L2
+ // Advanced Scalable Texture Profile
+ case 0xD1: // L1
+ case 0xD2: // L2
+ case 0xD3: // L3
+ // from draft amendments
+ // Simple Studio
+ case 0xE1: // L1
+ case 0xE2: // L2
+ case 0xE3: // L3
+ case 0xE4: // L4
+ // Core Studio Profile
+ case 0xE5: // L1
+ case 0xE6: // L2
+ case 0xE7: // L3
+ case 0xE8: // L4
+ // Advanced Simple Profile
+ case 0xF1: // L0
+ case 0xF2: // L1
+ case 0xF3: // L2
+ case 0xF4: // L3
+ case 0xF5: // L4
+ // Fine Granularity Scalable Profile
+ case 0xF6: // L0
+ case 0xF7: // L1
+ case 0xF8: // L2
+ case 0xF9: // L3
+ case 0xFA: // L4
+ default:
+ return 0xFE;
+ }
+}
+
+extern "C" u_char MP4AV_Mpeg4GetVopType(u_int8_t* pVopBuf, u_int32_t vopSize)
+{
+ u_char vopType = 0;
+
+ if (vopSize <= 4) {
+ return vopType;
+ }
+
+ if (pVopBuf[0] == 0 && pVopBuf[1] == 0
+ && (pVopBuf[2] & 0xFC) == 0x08 && (pVopBuf[3] & 0x03) == 0x02) {
+ // H.263, (MPEG-4 short header mode)
+ Mpeg4ParseShortHeaderVop(pVopBuf, vopSize, &vopType);
+
+ } else {
+ // MPEG-4 (normal mode)
+ MP4AV_Mpeg4ParseVop(pVopBuf, vopSize, &vopType, 0, 0, NULL);
+ }
+
+ return vopType;
+}
+
--- /dev/null
+++ b/common/mp4av/rfc2250.cpp
@@ -1,0 +1,165 @@
+/*
+ * 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" bool MP4AV_Rfc2250Hinter(
+ MP4FileHandle mp4File,
+ MP4TrackId mediaTrackId,
+ bool interleave,
+ u_int16_t maxPayloadSize)
+{
+ // RFC 2250 doesn't support interleaving
+ if (interleave) {
+ return false;
+ }
+
+ u_int32_t numSamples =
+ MP4GetTrackNumberOfSamples(mp4File, mediaTrackId);
+
+ if (numSamples == 0) {
+ return false;
+ }
+
+ u_int8_t audioType =
+ MP4GetTrackAudioType(mp4File, mediaTrackId);
+
+ if (!MP4_IS_MP3_AUDIO_TYPE(audioType)) {
+ return false;
+ }
+
+ MP4Duration sampleDuration =
+ MP4AV_GetAudioSampleDuration(mp4File, mediaTrackId);
+
+ if (sampleDuration == MP4_INVALID_DURATION) {
+ return false;
+ }
+
+ MP4TrackId hintTrackId =
+ MP4AddHintTrack(mp4File, mediaTrackId);
+
+ if (hintTrackId == MP4_INVALID_TRACK_ID) {
+ return false;
+ }
+
+ u_int8_t payloadNumber = 0; // use dynamic payload number
+
+ if (MP4GetTrackTimeScale(mp4File, mediaTrackId) == 90000) {
+ payloadNumber = 14;
+ }
+
+ MP4SetHintTrackRtpPayload(mp4File, hintTrackId,
+ "MPA", &payloadNumber, 0);
+
+ u_int16_t bytesThisHint = 0;
+ u_int16_t samplesThisHint = 0;
+
+ MP4AddRtpHint(mp4File, hintTrackId);
+ MP4AddRtpPacket(mp4File, hintTrackId, true);
+
+ for (MP4SampleId sampleId = 1; sampleId <= numSamples; sampleId++) {
+ u_int32_t sampleSize =
+ MP4GetSampleSize(mp4File, mediaTrackId, sampleId);
+
+ if (samplesThisHint > 0) {
+ if (bytesThisHint + sampleSize <= maxPayloadSize) {
+ // add the mp3 frame to current hint
+ MP4AddRtpSampleData(mp4File, hintTrackId,
+ sampleId, 0, sampleSize);
+
+ samplesThisHint++;
+ bytesThisHint += sampleSize;
+ continue;
+ } else {
+ // write out current hint
+ MP4WriteRtpHint(mp4File, hintTrackId,
+ samplesThisHint * sampleDuration);
+
+ // start a new hint
+ samplesThisHint = 0;
+ bytesThisHint = 0;
+
+ MP4AddRtpHint(mp4File, hintTrackId);
+ MP4AddRtpPacket(mp4File, hintTrackId, true);
+
+ // fall thru
+ }
+ }
+
+ if (sampleSize + 4 <= maxPayloadSize) {
+ // add rfc 2250 payload header
+ static u_int32_t zero32 = 0;
+
+ MP4AddRtpImmediateData(mp4File, hintTrackId,
+ (u_int8_t*)&zero32, sizeof(zero32));
+
+ // add the mp3 frame to current hint
+ MP4AddRtpSampleData(mp4File, hintTrackId,
+ sampleId, 0, sampleSize);
+
+ bytesThisHint += (4 + sampleSize);
+ } else {
+ // jumbo frame, need to fragment it
+ u_int16_t sampleOffset = 0;
+
+ while (sampleOffset < sampleSize) {
+ u_int16_t fragLength =
+ MIN(sampleSize - sampleOffset, maxPayloadSize) - 4;
+
+ u_int8_t payloadHeader[4];
+ payloadHeader[0] = payloadHeader[1] = 0;
+ payloadHeader[2] = (sampleOffset >> 8);
+ payloadHeader[3] = sampleOffset & 0xFF;
+
+ MP4AddRtpImmediateData(mp4File, hintTrackId,
+ (u_int8_t*)&payloadHeader, sizeof(payloadHeader));
+
+ MP4AddRtpSampleData(mp4File, hintTrackId,
+ sampleId, sampleOffset, fragLength);
+
+ sampleOffset += fragLength;
+
+ // if we're not at the last fragment
+ if (sampleOffset < sampleSize) {
+ MP4AddRtpPacket(mp4File, hintTrackId, false);
+ }
+ }
+
+ // lie to ourselves so as to force next frame to output
+ // our hint as is, and start a new hint for itself
+ bytesThisHint = maxPayloadSize;
+ }
+
+ samplesThisHint = 1;
+ }
+
+ // write out current (final) hint
+ MP4WriteRtpHint(mp4File, hintTrackId,
+ samplesThisHint * sampleDuration);
+
+ return true;
+}
+
--- /dev/null
+++ b/common/mp4av/rfc3016.cpp
@@ -1,0 +1,167 @@
+/*
+ * 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>
+#include <mp4av_mpeg4.h>
+
+extern "C" bool MP4AV_Rfc3016Hinter(
+ MP4FileHandle mp4File,
+ MP4TrackId mediaTrackId,
+ u_int16_t maxPayloadSize)
+{
+ u_int32_t numSamples = MP4GetTrackNumberOfSamples(mp4File, mediaTrackId);
+ u_int32_t maxSampleSize = MP4GetTrackMaxSampleSize(mp4File, mediaTrackId);
+
+ if (numSamples == 0 || maxSampleSize == 0) {
+ return false;
+ }
+
+ MP4TrackId hintTrackId =
+ MP4AddHintTrack(mp4File, mediaTrackId);
+
+ if (hintTrackId == MP4_INVALID_TRACK_ID) {
+ return false;
+ }
+
+ u_int8_t payloadNumber = 0;
+
+ MP4SetHintTrackRtpPayload(mp4File, hintTrackId,
+ "MP4V-ES", &payloadNumber, 0);
+
+ /* get the mpeg4 video configuration */
+ u_int8_t* pConfig;
+ u_int32_t configSize;
+ u_int8_t systemsProfileLevel = 0xFE;
+
+ MP4GetTrackESConfiguration(mp4File, mediaTrackId, &pConfig, &configSize);
+
+ if (pConfig) {
+ // attempt to get a valid profile-level
+ static u_int8_t voshStartCode[4] = {
+ 0x00, 0x00, 0x01, MP4AV_MPEG4_VOSH_START
+ };
+ if (configSize >= 5 && !memcmp(pConfig, voshStartCode, 4)) {
+ systemsProfileLevel =
+ MP4AV_Mpeg4VideoToSystemsProfileLevel(pConfig[4]);
+ }
+ if (systemsProfileLevel == 0xFE) {
+ u_int8_t iodProfileLevel = MP4GetVideoProfileLevel(mp4File);
+ if (iodProfileLevel > 0 && iodProfileLevel < 0xFE) {
+ systemsProfileLevel = iodProfileLevel;
+ } else {
+ systemsProfileLevel = 1;
+ }
+ }
+
+ /* convert it into ASCII form */
+ char* sConfig = MP4BinaryToBase16(pConfig, configSize);
+ if (sConfig == NULL) {
+ MP4DeleteTrack(mp4File, hintTrackId);
+ return false;
+ }
+
+ /* create the appropriate SDP attribute */
+ char* sdpBuf = (char*)malloc(strlen(sConfig) + 128);
+
+ sprintf(sdpBuf,
+ "a=fmtp:%u profile-level-id=%u; config=%s;\015\012",
+ payloadNumber,
+ systemsProfileLevel,
+ sConfig);
+
+ /* add this to the track's sdp */
+ MP4AppendHintTrackSdp(mp4File, hintTrackId, sdpBuf);
+
+ free(sConfig);
+ free(sdpBuf);
+
+ }
+
+ u_int8_t* pSampleBuffer = (u_int8_t*)malloc(maxSampleSize);
+ if (pSampleBuffer == NULL) {
+ MP4DeleteTrack(mp4File, hintTrackId);
+ return false;
+ }
+
+ for (MP4SampleId sampleId = 1; sampleId <= numSamples; sampleId++) {
+ u_int32_t sampleSize = maxSampleSize;
+ MP4Timestamp startTime;
+ MP4Duration duration;
+ MP4Duration renderingOffset;
+ bool isSyncSample;
+
+ bool rc = MP4ReadSample(
+ mp4File, mediaTrackId, sampleId,
+ &pSampleBuffer, &sampleSize,
+ &startTime, &duration,
+ &renderingOffset, &isSyncSample);
+
+ if (!rc) {
+ MP4DeleteTrack(mp4File, hintTrackId);
+ return false;
+ }
+
+ bool isBFrame =
+ (MP4AV_Mpeg4GetVopType(pSampleBuffer, sampleSize) == 'B');
+
+ MP4AddRtpVideoHint(mp4File, hintTrackId, isBFrame, renderingOffset);
+
+ if (sampleId == 1) {
+ MP4AddRtpESConfigurationPacket(mp4File, hintTrackId);
+ }
+
+ u_int32_t offset = 0;
+ u_int32_t remaining = sampleSize;
+
+ // TBD should scan for resync markers (if enabled in ES config)
+ // and packetize on those boundaries
+
+ while (remaining) {
+ bool isLastPacket = false;
+ u_int32_t length;
+
+ if (remaining <= maxPayloadSize) {
+ length = remaining;
+ isLastPacket = true;
+ } else {
+ length = maxPayloadSize;
+ }
+
+ MP4AddRtpPacket(mp4File, hintTrackId, isLastPacket);
+
+ MP4AddRtpSampleData(mp4File, hintTrackId, sampleId,
+ offset, length);
+
+ offset += length;
+ remaining -= length;
+ }
+
+ MP4WriteRtpHint(mp4File, hintTrackId, duration, isSyncSample);
+ }
+
+ return true;
+}
+
--- /dev/null
+++ b/common/mp4av/rfc3119.cpp
@@ -1,0 +1,526 @@
+/*
+ * 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>
+
+// LATER get these on the stack so library is thread-safe!
+// file globals
+static bool doInterleave;
+static u_int32_t samplesPerPacket;
+static u_int32_t samplesPerGroup;
+static MP4AV_Mp3Header* pFrameHeaders = NULL;
+static u_int16_t* pAduOffsets = NULL;
+
+static bool GetFrameInfo(
+ MP4FileHandle mp4File,
+ MP4TrackId mediaTrackId,
+ MP4AV_Mp3Header** ppFrameHeaders,
+ u_int16_t** ppAduOffsets)
+{
+ // allocate memory to hold the frame info that we need
+ u_int32_t numSamples =
+ MP4GetTrackNumberOfSamples(mp4File, mediaTrackId);
+
+ *ppFrameHeaders =
+ (MP4AV_Mp3Header*)calloc((numSamples + 2), sizeof(u_int32_t));
+ if (*ppFrameHeaders == NULL) {
+ return false;
+ }
+
+ *ppAduOffsets =
+ (u_int16_t*)calloc((numSamples + 2), sizeof(u_int16_t));
+ if (*ppAduOffsets == NULL) {
+ free(*ppFrameHeaders);
+ return false;
+ }
+
+ // for each sample
+ for (MP4SampleId sampleId = 1; sampleId <= numSamples; sampleId++) {
+ u_int8_t* pSample = NULL;
+ u_int32_t sampleSize = 0;
+
+ // read it
+ MP4ReadSample(
+ mp4File,
+ mediaTrackId,
+ sampleId,
+ &pSample,
+ &sampleSize);
+
+ // extract the MP3 frame header
+ MP4AV_Mp3Header mp3hdr =
+ MP4AV_Mp3HeaderFromBytes(pSample);
+
+ // store what we need
+ (*ppFrameHeaders)[sampleId] = mp3hdr;
+
+ (*ppAduOffsets)[sampleId] =
+ MP4AV_Mp3GetAduOffset(pSample, sampleSize);
+
+ free(pSample);
+ }
+
+ return true;
+}
+
+static u_int16_t GetFrameHeaderSize(MP4SampleId sampleId)
+{
+ return 4 + MP4AV_Mp3GetCrcSize(pFrameHeaders[sampleId])
+ + MP4AV_Mp3GetSideInfoSize(pFrameHeaders[sampleId]);
+}
+
+static u_int16_t GetFrameDataSize(
+ MP4FileHandle mp4File,
+ MP4TrackId mediaTrackId,
+ MP4SampleId sampleId)
+{
+ return MP4GetSampleSize(mp4File, mediaTrackId, sampleId)
+ - GetFrameHeaderSize(sampleId);
+}
+
+u_int32_t MP4AV_Rfc3119GetAduSize(
+ MP4FileHandle mp4File,
+ MP4TrackId mediaTrackId,
+ MP4SampleId sampleId)
+{
+ u_int32_t sampleSize = MP4GetSampleSize(mp4File, mediaTrackId, sampleId);
+
+ return pAduOffsets[sampleId] + sampleSize - pAduOffsets[sampleId + 1];
+}
+
+static u_int16_t GetMaxAduSize(
+ MP4FileHandle mp4File,
+ MP4TrackId mediaTrackId)
+{
+ u_int32_t numSamples =
+ MP4GetTrackNumberOfSamples(mp4File, mediaTrackId);
+
+ u_int16_t maxAduSize = 0;
+
+ for (MP4SampleId sampleId = 1; sampleId <= numSamples; sampleId++) {
+ u_int16_t aduSize =
+ MP4AV_Rfc3119GetAduSize(mp4File, mediaTrackId, sampleId);
+
+ if (aduSize > maxAduSize) {
+ maxAduSize = aduSize;
+ }
+ }
+
+ return maxAduSize;
+}
+
+static u_int16_t GetAduDataSize(
+ MP4FileHandle mp4File,
+ MP4TrackId mediaTrackId,
+ MP4SampleId sampleId)
+{
+ return MP4AV_Rfc3119GetAduSize(mp4File, mediaTrackId, sampleId)
+ - GetFrameHeaderSize(sampleId);
+}
+
+static void AddFrameHeader(
+ MP4FileHandle mp4File,
+ MP4TrackId mediaTrackId,
+ MP4TrackId hintTrackId,
+ MP4SampleId sampleId)
+{
+ // when interleaving we replace the 11 bit mp3 frame sync
+ if (doInterleave) {
+ // compute interleave index and interleave cycle from sampleId
+ u_int8_t interleaveIndex =
+ (sampleId - 1) % samplesPerGroup;
+ u_int8_t interleaveCycle =
+ ((sampleId - 1) / samplesPerGroup) & 0x7;
+
+ u_int8_t interleaveHeader[4];
+ interleaveHeader[0] =
+ interleaveIndex;
+ interleaveHeader[1] =
+ (interleaveCycle << 5) | ((pFrameHeaders[sampleId] >> 16) & 0x1F);
+ interleaveHeader[2] =
+ (pFrameHeaders[sampleId] >> 8) & 0xFF;
+ interleaveHeader[3] =
+ pFrameHeaders[sampleId] & 0xFF;
+
+ MP4AddRtpImmediateData(mp4File, hintTrackId,
+ interleaveHeader, 4);
+
+ // add crc and side info from current mp3 frame
+ MP4AddRtpSampleData(mp4File, hintTrackId,
+ sampleId, 4, GetFrameHeaderSize(sampleId) - 4);
+ } else {
+ // add mp3 header, crc, and side info from current mp3 frame
+ MP4AddRtpSampleData(mp4File, hintTrackId,
+ sampleId, 0, GetFrameHeaderSize(sampleId));
+ }
+}
+
+static void CollectAduDataBlocks(
+ MP4FileHandle mp4File,
+ MP4TrackId mediaTrackId,
+ MP4TrackId hintTrackId,
+ MP4SampleId sampleId,
+ u_int8_t* pNumBlocks,
+ u_int32_t** ppOffsets,
+ u_int32_t** ppSizes)
+{
+ // go back from sampleId until
+ // accumulated data bytes can fill sample's ADU
+ MP4SampleId sid = sampleId;
+ u_int8_t numBlocks = 1;
+ u_int32_t prevDataBytes = 0;
+ const u_int8_t maxBlocks = 8;
+
+ *ppOffsets = new u_int32_t[maxBlocks];
+ *ppSizes = new u_int32_t[maxBlocks];
+
+ (*ppOffsets)[0] = GetFrameHeaderSize(sampleId);
+ (*ppSizes)[0] = GetFrameDataSize(mp4File, mediaTrackId, sid);
+
+ while (true) {
+ if (prevDataBytes >= pAduOffsets[sampleId]) {
+ u_int32_t adjust =
+ prevDataBytes - pAduOffsets[sampleId];
+
+ (*ppOffsets)[numBlocks-1] += adjust;
+ (*ppSizes)[numBlocks-1] -= adjust;
+
+ break;
+ }
+
+ sid--;
+ numBlocks++;
+
+ if (sid == 0 || numBlocks > maxBlocks) {
+ throw EIO; // media bitstream error
+ }
+
+ (*ppOffsets)[numBlocks-1] = GetFrameHeaderSize(sid);
+ (*ppSizes)[numBlocks-1] = GetFrameDataSize(mp4File, mediaTrackId, sid);
+ prevDataBytes += (*ppSizes)[numBlocks-1];
+ }
+
+ *pNumBlocks = numBlocks;
+}
+
+bool MP4AV_Rfc3119Concatenator(
+ MP4FileHandle mp4File,
+ MP4TrackId mediaTrackId,
+ MP4TrackId hintTrackId,
+ u_int8_t samplesThisHint,
+ MP4SampleId* pSampleIds,
+ MP4Duration hintDuration,
+ u_int16_t maxPayloadSize)
+{
+ // handle degenerate case
+ if (samplesThisHint == 0) {
+ return true;
+ }
+
+ // construct the new hint
+ MP4AddRtpHint(mp4File, hintTrackId);
+ MP4AddRtpPacket(mp4File, hintTrackId, false);
+
+ // rfc 3119 per adu payload header
+ u_int8_t payloadHeader[2];
+
+ // for each given sample
+ for (u_int8_t i = 0; i < samplesThisHint; i++) {
+ MP4SampleId sampleId = pSampleIds[i];
+
+ u_int16_t aduSize =
+ MP4AV_Rfc3119GetAduSize(mp4File, mediaTrackId, sampleId);
+
+ // add the per ADU payload header
+ payloadHeader[0] = 0x40 | ((aduSize >> 8) & 0x3F);
+ payloadHeader[1] = aduSize & 0xFF;
+
+ MP4AddRtpImmediateData(mp4File, hintTrackId,
+ (u_int8_t*)&payloadHeader, sizeof(payloadHeader));
+ // add the mp3 frame header and side info
+ AddFrameHeader(mp4File, mediaTrackId, hintTrackId, sampleId);
+
+ // collect the info on the adu main data fragments
+ u_int8_t numDataBlocks;
+ u_int32_t* pDataOffsets;
+ u_int32_t* pDataSizes;
+
+ CollectAduDataBlocks(mp4File, mediaTrackId, hintTrackId, sampleId,
+ &numDataBlocks, &pDataOffsets, &pDataSizes);
+
+ // collect the needed blocks of data
+ u_int16_t dataSize = 0;
+ u_int16_t aduDataSize =
+ GetAduDataSize(mp4File, mediaTrackId, sampleId);
+
+ for (int8_t i = numDataBlocks - 1;
+ i >= 0 && dataSize < aduDataSize; i--) {
+ u_int32_t blockSize = pDataSizes[i];
+
+ if ((u_int32_t)(aduDataSize - dataSize) < blockSize) {
+ blockSize = (u_int32_t)(aduDataSize - dataSize);
+ }
+
+ MP4AddRtpSampleData(mp4File, hintTrackId,
+ sampleId - i, pDataOffsets[i], blockSize);
+
+ dataSize += blockSize;
+ }
+
+ delete [] pDataOffsets;
+ delete [] pDataSizes;
+ }
+
+ // write the hint
+ MP4WriteRtpHint(mp4File, hintTrackId, hintDuration);
+
+ return true;
+}
+
+bool MP4AV_Rfc3119Fragmenter(
+ MP4FileHandle mp4File,
+ MP4TrackId mediaTrackId,
+ MP4TrackId hintTrackId,
+ MP4SampleId sampleId,
+ u_int32_t aduSize,
+ MP4Duration sampleDuration,
+ u_int16_t maxPayloadSize)
+{
+ MP4AddRtpHint(mp4File, hintTrackId);
+ MP4AddRtpPacket(mp4File, hintTrackId, false);
+
+ // rfc 3119 payload header
+ u_int8_t payloadHeader[2];
+
+ u_int16_t payloadSize =
+ sizeof(payloadHeader) + GetFrameHeaderSize(sampleId);
+
+ // guard against ridiculous payload sizes
+ if (payloadSize > maxPayloadSize) {
+ return false;
+ }
+
+ // add the per ADU fragment payload header
+ payloadHeader[0] = 0x40 | ((aduSize >> 8) & 0x3F);
+ payloadHeader[1] = aduSize & 0xFF;
+
+ MP4AddRtpImmediateData(mp4File, hintTrackId,
+ (u_int8_t*)&payloadHeader, sizeof(payloadHeader));
+
+ payloadHeader[0] |= 0x80; // mark future packets as continuations
+
+ // add the mp3 frame header and side info
+ AddFrameHeader(mp4File, mediaTrackId, hintTrackId, sampleId);
+
+ // collect the info on the adu main data fragments
+ u_int8_t numDataBlocks;
+ u_int32_t* pDataOffsets;
+ u_int32_t* pDataSizes;
+
+ CollectAduDataBlocks(mp4File, mediaTrackId, hintTrackId, sampleId,
+ &numDataBlocks, &pDataOffsets, &pDataSizes);
+
+ u_int16_t dataSize = 0;
+ u_int16_t aduDataSize =
+ GetAduDataSize(mp4File, mediaTrackId, sampleId);
+
+ // for each data block
+ for (int8_t i = numDataBlocks - 1; i >= 0 && dataSize < aduDataSize; i--) {
+ u_int32_t blockSize = pDataSizes[i];
+ u_int32_t blockOffset = pDataOffsets[i];
+
+ // we may not need all of a block
+ if ((u_int32_t)(aduDataSize - dataSize) < blockSize) {
+ blockSize = (u_int32_t)(aduDataSize - dataSize);
+ }
+
+ dataSize += blockSize;
+
+ // while data left in this block
+ while (blockSize > 0) {
+ u_int16_t payloadRemaining = maxPayloadSize - payloadSize;
+
+ if (blockSize < payloadRemaining) {
+ // the entire block fits in this packet
+ MP4AddRtpSampleData(mp4File, hintTrackId,
+ sampleId - i, blockOffset, blockSize);
+
+ payloadSize += blockSize;
+ blockSize = 0;
+
+ } else {
+ // the block fills this packet
+ MP4AddRtpSampleData(mp4File, hintTrackId,
+ sampleId - i, blockOffset, payloadRemaining);
+
+ blockOffset += payloadRemaining;
+ blockSize -= payloadRemaining;
+
+ // start a new RTP packet
+ MP4AddRtpPacket(mp4File, hintTrackId, false);
+
+ // add the fragment payload header
+ MP4AddRtpImmediateData(mp4File, hintTrackId,
+ (u_int8_t*)&payloadHeader, sizeof(payloadHeader));
+
+ payloadSize = sizeof(payloadHeader);
+ }
+ }
+ }
+
+ // write the hint
+ MP4WriteRtpHint(mp4File, hintTrackId, sampleDuration);
+
+ // cleanup
+ delete [] pDataOffsets;
+ delete [] pDataSizes;
+
+ return true;
+}
+
+extern "C" bool MP4AV_Rfc3119Hinter(
+ MP4FileHandle mp4File,
+ MP4TrackId mediaTrackId,
+ bool interleave,
+ u_int16_t maxPayloadSize)
+{
+ int rc;
+
+ u_int32_t numSamples =
+ MP4GetTrackNumberOfSamples(mp4File, mediaTrackId);
+
+ if (numSamples == 0) {
+ return false;
+ }
+
+ u_int8_t audioType =
+ MP4GetTrackAudioType(mp4File, mediaTrackId);
+
+ if (!MP4_IS_MP3_AUDIO_TYPE(audioType)) {
+ return false;
+ }
+
+ MP4Duration sampleDuration =
+ MP4AV_GetAudioSampleDuration(mp4File, mediaTrackId);
+
+ if (sampleDuration == MP4_INVALID_DURATION) {
+ return false;
+ }
+
+ // choose 500 ms max latency
+ MP4Duration maxLatency =
+ MP4GetTrackTimeScale(mp4File, mediaTrackId) / 2;
+ if (maxLatency == 0) {
+ return false;
+ }
+
+ MP4TrackId hintTrackId =
+ MP4AddHintTrack(mp4File, mediaTrackId);
+
+ if (hintTrackId == MP4_INVALID_TRACK_ID) {
+ return false;
+ }
+
+ doInterleave = interleave;
+
+ u_int8_t payloadNumber = 0;
+
+ MP4SetHintTrackRtpPayload(mp4File, hintTrackId,
+ "mpa-robust", &payloadNumber, 0);
+
+ // load mp3 frame information into memory
+ rc = GetFrameInfo(
+ mp4File,
+ mediaTrackId,
+ &pFrameHeaders,
+ &pAduOffsets);
+
+ if (!rc) {
+ MP4DeleteTrack(mp4File, hintTrackId);
+ return false;
+ }
+
+ if (doInterleave) {
+ u_int32_t maxAduSize =
+ GetMaxAduSize(mp4File, mediaTrackId);
+
+ // compute how many maximum size samples would fit in a packet
+ samplesPerPacket =
+ maxPayloadSize / (maxAduSize + 2);
+
+ // can't interleave if this number is 0 or 1
+ if (samplesPerPacket < 2) {
+ doInterleave = false;
+ }
+ }
+
+ if (doInterleave) {
+ // initial estimate of samplesPerGroup
+ samplesPerGroup = maxLatency / sampleDuration;
+ // use that to compute an integral stride
+ u_int8_t stride = samplesPerGroup / samplesPerPacket;
+ // and then recompute samples per group to deal with rounding
+ samplesPerGroup = stride * samplesPerPacket;
+
+ rc = MP4AV_AudioInterleaveHinter(
+ mp4File,
+ mediaTrackId,
+ hintTrackId,
+ sampleDuration,
+ samplesPerGroup / samplesPerPacket, // stride
+ samplesPerPacket, // bundle
+ maxPayloadSize,
+ MP4AV_Rfc3119Concatenator);
+
+ } else {
+ rc = MP4AV_AudioConsecutiveHinter(
+ mp4File,
+ mediaTrackId,
+ hintTrackId,
+ sampleDuration,
+ 0, // perPacketHeaderSize
+ 2, // perSampleHeaderSize
+ maxLatency / sampleDuration, // maxSamplesPerPacket
+ maxPayloadSize,
+ MP4AV_Rfc3119GetAduSize,
+ MP4AV_Rfc3119Concatenator,
+ MP4AV_Rfc3119Fragmenter);
+ }
+
+ // cleanup
+ free(pFrameHeaders);
+ pFrameHeaders = NULL;
+ free(pAduOffsets);
+ pAduOffsets = NULL;
+
+ if (!rc) {
+ MP4DeleteTrack(mp4File, hintTrackId);
+ return false;
+ }
+
+ return true;
+}
+
--- /dev/null
+++ b/common/mp4av/rfcisma.cpp
@@ -1,0 +1,349 @@
+/*
+ * 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>
+
+bool MP4AV_RfcIsmaConcatenator(
+ MP4FileHandle mp4File,
+ MP4TrackId mediaTrackId,
+ MP4TrackId hintTrackId,
+ u_int8_t samplesThisHint,
+ MP4SampleId* pSampleIds,
+ MP4Duration hintDuration,
+ u_int16_t maxPayloadSize)
+{
+ // handle degenerate case
+ if (samplesThisHint == 0) {
+ return true;
+ }
+
+ u_int8_t auPayloadHdrSize;
+
+ // LATER would be more efficient if this were a parameter
+ u_int8_t mpeg4AudioType =
+ MP4GetTrackAudioMpeg4Type(mp4File, mediaTrackId);
+
+ if (mpeg4AudioType == MP4_MPEG4_CELP_AUDIO_TYPE) {
+ auPayloadHdrSize = 1;
+ } else {
+ auPayloadHdrSize = 2;
+ }
+
+ // construct the new hint
+ MP4AddRtpHint(mp4File, hintTrackId);
+ MP4AddRtpPacket(mp4File, hintTrackId, true);
+
+ u_int8_t payloadHeader[2];
+
+ u_int16_t numHdrBits = samplesThisHint * auPayloadHdrSize * 8;
+ payloadHeader[0] = numHdrBits >> 8;
+ payloadHeader[1] = numHdrBits & 0xFF;
+
+ MP4AddRtpImmediateData(mp4File, hintTrackId,
+ (u_int8_t*)&payloadHeader, sizeof(payloadHeader));
+
+ u_int8_t i;
+
+ // first the headers
+ for (i = 0; i < samplesThisHint; i++) {
+ MP4SampleId sampleId = pSampleIds[i];
+
+ u_int32_t sampleSize =
+ MP4GetSampleSize(mp4File, mediaTrackId, sampleId);
+
+ if (auPayloadHdrSize == 1) {
+ // AU payload header is 6 bits of size
+ // follow by 2 bits of the difference between sampleId's - 1
+ payloadHeader[0] = sampleSize << 2;
+
+ } else { // auPayloadHdrSize == 2
+ // AU payload header is 13 bits of size
+ // follow by 3 bits of the difference between sampleId's - 1
+ payloadHeader[0] = sampleSize >> 5;
+ payloadHeader[1] = (sampleSize & 0x1F) << 3;
+ }
+
+ if (i > 0) {
+ payloadHeader[auPayloadHdrSize - 1]
+ |= ((sampleId - pSampleIds[i-1]) - 1);
+ }
+
+ MP4AddRtpImmediateData(mp4File, hintTrackId,
+ (u_int8_t*)&payloadHeader, auPayloadHdrSize);
+ }
+
+ // then the samples
+ for (i = 0; i < samplesThisHint; i++) {
+ MP4SampleId sampleId = pSampleIds[i];
+
+ u_int32_t sampleSize =
+ MP4GetSampleSize(mp4File, mediaTrackId, sampleId);
+
+ MP4AddRtpSampleData(mp4File, hintTrackId, sampleId, 0, sampleSize);
+ }
+
+ // write the hint
+ MP4WriteRtpHint(mp4File, hintTrackId, hintDuration);
+
+ return true;
+}
+
+bool MP4AV_RfcIsmaFragmenter(
+ MP4FileHandle mp4File,
+ MP4TrackId mediaTrackId,
+ MP4TrackId hintTrackId,
+ MP4SampleId sampleId,
+ u_int32_t sampleSize,
+ MP4Duration sampleDuration,
+ u_int16_t maxPayloadSize)
+{
+ MP4AddRtpHint(mp4File, hintTrackId);
+
+ MP4AddRtpPacket(mp4File, hintTrackId, false);
+
+ // Note: CELP is never fragmented
+ // so we assume the two byte AAC-hbr payload header
+ u_int8_t payloadHeader[4];
+ payloadHeader[0] = 0;
+ payloadHeader[1] = 16;
+ payloadHeader[2] = sampleSize >> 5;
+ payloadHeader[3] = (sampleSize & 0x1F) << 3;
+
+ MP4AddRtpImmediateData(mp4File, hintTrackId,
+ (u_int8_t*)&payloadHeader, sizeof(payloadHeader));
+
+ u_int16_t sampleOffset = 0;
+ u_int16_t fragLength = maxPayloadSize - 4;
+
+ do {
+ MP4AddRtpSampleData(mp4File, hintTrackId,
+ sampleId, sampleOffset, fragLength);
+
+ sampleOffset += fragLength;
+
+ if (sampleSize - sampleOffset > maxPayloadSize) {
+ fragLength = maxPayloadSize;
+ MP4AddRtpPacket(mp4File, hintTrackId, false);
+ } else {
+ fragLength = sampleSize - sampleOffset;
+ if (fragLength) {
+ MP4AddRtpPacket(mp4File, hintTrackId, true);
+ }
+ }
+ } while (sampleOffset < sampleSize);
+
+ MP4WriteRtpHint(mp4File, hintTrackId, sampleDuration);
+
+ return true;
+}
+
+extern "C" bool MP4AV_RfcIsmaHinter(
+ MP4FileHandle mp4File,
+ MP4TrackId mediaTrackId,
+ bool interleave,
+ u_int16_t maxPayloadSize)
+{
+ // gather information, and check for validity
+
+ u_int32_t numSamples =
+ MP4GetTrackNumberOfSamples(mp4File, mediaTrackId);
+
+ if (numSamples == 0) {
+ return false;
+ }
+
+ u_int32_t timeScale =
+ MP4GetTrackTimeScale(mp4File, mediaTrackId);
+
+ if (timeScale == 0) {
+ return false;
+ }
+
+ u_int8_t audioType =
+ MP4GetTrackAudioType(mp4File, mediaTrackId);
+
+ if (audioType != MP4_MPEG4_AUDIO_TYPE
+ && !MP4_IS_AAC_AUDIO_TYPE(audioType)) {
+ return false;
+ }
+
+ u_int8_t mpeg4AudioType =
+ MP4GetTrackAudioMpeg4Type(mp4File, mediaTrackId);
+
+ if (audioType == MP4_MPEG4_AUDIO_TYPE) {
+ // check that track contains either MPEG-4 AAC or CELP
+ if (!MP4_IS_MPEG4_AAC_AUDIO_TYPE(mpeg4AudioType)
+ && mpeg4AudioType != MP4_MPEG4_CELP_AUDIO_TYPE) {
+ return false;
+ }
+ }
+
+ MP4Duration sampleDuration =
+ MP4AV_GetAudioSampleDuration(mp4File, mediaTrackId);
+
+ if (sampleDuration == MP4_INVALID_DURATION) {
+ return false;
+ }
+
+ /* get the ES configuration */
+ u_int8_t* pConfig = NULL;
+ u_int32_t configSize;
+ uint8_t channels;
+
+ MP4GetTrackESConfiguration(mp4File, mediaTrackId, &pConfig, &configSize);
+
+ if (!pConfig) {
+ return false;
+ }
+
+ channels = MP4AV_AacConfigGetChannels(pConfig);
+
+ /* convert ES Config into ASCII form */
+ char* sConfig =
+ MP4BinaryToBase16(pConfig, configSize);
+
+ free(pConfig);
+
+ if (!sConfig) {
+ return false;
+ }
+
+ /* create the appropriate SDP attribute */
+ char* sdpBuf =
+ (char*)malloc(strlen(sConfig) + 256);
+
+ if (!sdpBuf) {
+ free(sConfig);
+ return false;
+ }
+
+
+ // now add the hint track
+ MP4TrackId hintTrackId =
+ MP4AddHintTrack(mp4File, mediaTrackId);
+
+ if (hintTrackId == MP4_INVALID_TRACK_ID) {
+ free(sConfig);
+ free(sdpBuf);
+ return false;
+ }
+
+ u_int8_t payloadNumber = 0;
+ char buffer[10];
+ if (channels != 1) {
+ snprintf(buffer, sizeof(buffer), "%u", channels);
+ }
+ MP4SetHintTrackRtpPayload(mp4File, hintTrackId,
+ "mpeg4-generic", &payloadNumber, 0,
+ channels != 1 ? buffer : NULL);
+
+ MP4Duration maxLatency;
+
+ if (mpeg4AudioType == MP4_MPEG4_CELP_AUDIO_TYPE) {
+ sprintf(sdpBuf,
+ "a=fmtp:%u "
+ "streamtype=5; profile-level-id=15; mode=CELP-vbr; config=%s; "
+ "SizeLength=6; IndexLength=2; IndexDeltaLength=2; Profile=0;"
+ "\015\012",
+ payloadNumber,
+ sConfig);
+
+ // 200 ms max latency for ISMA profile 1
+ maxLatency = timeScale / 5;
+
+ } else { // AAC
+ sprintf(sdpBuf,
+ "a=fmtp:%u "
+ "streamtype=5; profile-level-id=15; mode=AAC-hbr; config=%s; "
+ "SizeLength=13; IndexLength=3; IndexDeltaLength=3; Profile=1;"
+ "\015\012",
+ payloadNumber,
+ sConfig);
+
+ // 500 ms max latency for ISMA profile 1
+ maxLatency = timeScale / 2;
+ }
+
+ /* add this to the track's sdp */
+ MP4AppendHintTrackSdp(mp4File, hintTrackId, sdpBuf);
+
+ free(sConfig);
+ free(sdpBuf);
+
+ u_int32_t samplesPerPacket = 0;
+
+ if (interleave) {
+ u_int32_t maxSampleSize =
+ MP4GetTrackMaxSampleSize(mp4File, mediaTrackId);
+
+ // compute how many maximum size samples would fit in a packet
+ samplesPerPacket =
+ (maxPayloadSize - 2) / (maxSampleSize + 2);
+
+ // can't interleave if this number is 0 or 1
+ if (samplesPerPacket < 2) {
+ interleave = false;
+ }
+ }
+
+ bool rc;
+
+ if (interleave) {
+ u_int32_t samplesPerGroup = maxLatency / sampleDuration;
+
+ rc = MP4AV_AudioInterleaveHinter(
+ mp4File,
+ mediaTrackId,
+ hintTrackId,
+ sampleDuration,
+ samplesPerGroup / samplesPerPacket, // stride
+ samplesPerPacket, // bundle
+ maxPayloadSize,
+ MP4AV_RfcIsmaConcatenator);
+
+ } else {
+ rc = MP4AV_AudioConsecutiveHinter(
+ mp4File,
+ mediaTrackId,
+ hintTrackId,
+ sampleDuration,
+ 2, // perPacketHeaderSize
+ 2, // perSampleHeaderSize
+ maxLatency / sampleDuration, // maxSamplesPerPacket
+ maxPayloadSize,
+ MP4GetSampleSize,
+ MP4AV_RfcIsmaConcatenator,
+ MP4AV_RfcIsmaFragmenter);
+ }
+
+ if (!rc) {
+ MP4DeleteTrack(mp4File, hintTrackId);
+ return false;
+ }
+
+ return true;
+}
+
--- a/plugins/in_mp4/aac2mp4.c
+++ /dev/null
@@ -1,80 +1,0 @@
-/*
-** 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.2 2002/09/03 21:22:53 menno Exp $
-**/
-
-#include <mpeg4ip.h>
-#include <mp4.h>
-#include "mp4av.h"
-
-#include "aac2mp4.h"
-
-int covert_aac_to_mp4(char *inputFileName, char *mp4FileName)
-{
- int Mp4TimeScale = 90000;
- int allMpeg4Streams = 0;
- MP4FileHandle mp4File;
- FILE* inFile;
- char *type;
- MP4TrackId createdTrackId = MP4_INVALID_TRACK_ID;
-
- 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.cpp
@@ -1,0 +1,313 @@
+/*
+** 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.cpp,v 1.1 2002/10/05 15:20:20 menno Exp $
+**/
+
+#include <mpeg4ip.h>
+#include <mp4.h>
+#include <mp4av.h>
+
+#include "aac2mp4.h"
+
+int covert_aac_to_mp4(char *inputFileName, char *mp4FileName)
+{
+ int Mp4TimeScale = 90000;
+ int allMpeg4Streams = 0;
+ MP4FileHandle mp4File;
+ FILE* inFile;
+ const char *type;
+ MP4TrackId createdTrackId = MP4_INVALID_TRACK_ID;
+
+ 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;
+}
+
+#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/aactrack.cpp
+++ /dev/null
@@ -1,265 +1,0 @@
-/*
- * 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.dsp
+++ b/plugins/in_mp4/in_mp4.dsp
@@ -43,7 +43,7 @@
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
-# ADD CPP /nologo /W3 /GX /O2 /I "..\..\include" /I "..\..\common\mp4v2" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /I "..\..\include" /I "..\..\common\mp4v2" /I "..\..\common\mp4av" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x413 /d "NDEBUG"
@@ -69,7 +69,7 @@
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c
-# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\..\include" /I "..\..\common\mp4v2" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\..\include" /I "..\..\common\mp4v2" /I "..\..\common\mp4av" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x413 /d "_DEBUG"
@@ -92,7 +92,7 @@
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
-SOURCE=.\aac2mp4.c
+SOURCE=.\aac2mp4.cpp
# End Source File
# Begin Source File
@@ -100,31 +100,11 @@
# End Source File
# Begin Source File
-SOURCE=.\aactrack.cpp
-# End Source File
-# Begin Source File
-
SOURCE=.\config.c
# End Source File
# Begin Source File
SOURCE=.\in_mp4.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\mbs.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\mp4av_aac.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\mp4av_adts.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\mp4av_audio.cpp
# End Source File
# Begin Source File
--- a/plugins/in_mp4/in_mp4.dsw
+++ b/plugins/in_mp4/in_mp4.dsw
@@ -33,6 +33,18 @@
###############################################################################
+Project: "libmp4av_st"=..\..\common\mp4av\libmp4av_st.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
Project: "libmp4v2_st"=..\..\common\mp4v2\libmp4v2_st60.dsp - Package Owner=<4>
Package=<5>
--- a/plugins/in_mp4/in_mp4.sln
+++ b/plugins/in_mp4/in_mp4.sln
@@ -5,6 +5,8 @@
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libmp4v2_st", "..\..\common\mp4v2\libmp4v2_st60.vcproj", "{2398BB2F-FFF9-490B-B4CC-863F2D21AE46}"
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libmp4av_st", "..\..\common\mp4av\libmp4av_st.vcproj", "{8CAC9E26-BAA5-45A4-8721-E3170B3F8F49}"
+EndProject
Global
GlobalSection(SolutionConfiguration) = preSolution
ConfigName.0 = Debug
@@ -11,8 +13,9 @@
ConfigName.1 = Release
EndGlobalSection
GlobalSection(ProjectDependencies) = postSolution
- {2D8F479D-A591-4502-9456-398425D5F834}.0 = {2398BB2F-FFF9-490B-B4CC-863F2D21AE46}
- {2D8F479D-A591-4502-9456-398425D5F834}.1 = {82CAD808-21AF-40A6-92EC-AE01AA67B413}
+ {2D8F479D-A591-4502-9456-398425D5F834}.0 = {82CAD808-21AF-40A6-92EC-AE01AA67B413}
+ {2D8F479D-A591-4502-9456-398425D5F834}.1 = {8CAC9E26-BAA5-45A4-8721-E3170B3F8F49}
+ {2D8F479D-A591-4502-9456-398425D5F834}.2 = {2398BB2F-FFF9-490B-B4CC-863F2D21AE46}
EndGlobalSection
GlobalSection(ProjectConfiguration) = postSolution
{2D8F479D-A591-4502-9456-398425D5F834}.Debug.ActiveCfg = Debug|Win32
@@ -27,6 +30,10 @@
{2398BB2F-FFF9-490B-B4CC-863F2D21AE46}.Debug.Build.0 = Debug|Win32
{2398BB2F-FFF9-490B-B4CC-863F2D21AE46}.Release.ActiveCfg = Release|Win32
{2398BB2F-FFF9-490B-B4CC-863F2D21AE46}.Release.Build.0 = Release|Win32
+ {8CAC9E26-BAA5-45A4-8721-E3170B3F8F49}.Debug.ActiveCfg = Debug|Win32
+ {8CAC9E26-BAA5-45A4-8721-E3170B3F8F49}.Debug.Build.0 = Debug|Win32
+ {8CAC9E26-BAA5-45A4-8721-E3170B3F8F49}.Release.ActiveCfg = Release|Win32
+ {8CAC9E26-BAA5-45A4-8721-E3170B3F8F49}.Release.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection
--- a/plugins/in_mp4/in_mp4.vcproj
+++ b/plugins/in_mp4/in_mp4.vcproj
@@ -20,7 +20,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories="..\..\include,..\..\common\mp4v2"
+ AdditionalIncludeDirectories="..\..\include,..\..\common\mp4v2,..\..\common\mp4av"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
@@ -82,7 +82,7 @@
EnableIntrinsicFunctions="TRUE"
FavorSizeOrSpeed="1"
OptimizeForProcessor="2"
- AdditionalIncludeDirectories="..\..\include,..\..\common\mp4v2"
+ AdditionalIncludeDirectories="..\..\include,..\..\common\mp4v2,..\..\common\mp4av"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
StringPooling="TRUE"
RuntimeLibrary="4"
@@ -135,31 +135,16 @@
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
<File
- RelativePath="aac2mp4.c">
+ RelativePath="aac2mp4.cpp">
</File>
<File
RelativePath="aacinfo.c">
</File>
<File
- RelativePath="aactrack.cpp">
- </File>
- <File
RelativePath=".\config.c">
</File>
<File
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">
--- a/plugins/in_mp4/mbs.cpp
+++ /dev/null
@@ -1,93 +1,0 @@
-/*
- * 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;
-}
-
--- a/plugins/in_mp4/mp4av.h
+++ /dev/null
@@ -1,42 +1,0 @@
-/*
- * 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__ */
-
--- a/plugins/in_mp4/mp4av_aac.cpp
+++ /dev/null
@@ -1,133 +1,0 @@
-/*
- * 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;
-}
-
--- a/plugins/in_mp4/mp4av_aac.h
+++ /dev/null
@@ -1,61 +1,0 @@
-/*
- * 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__ */
--- a/plugins/in_mp4/mp4av_adts.cpp
+++ /dev/null
@@ -1,271 +1,0 @@
-/*
- * 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;
-}
-
--- a/plugins/in_mp4/mp4av_adts.h
+++ /dev/null
@@ -1,86 +1,0 @@
-/*
- * 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__ */
--- a/plugins/in_mp4/mp4av_audio.cpp
+++ /dev/null
@@ -1,166 +1,0 @@
-/*
- * 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;
-}
--- a/plugins/in_mp4/mp4av_audio.h
+++ /dev/null
@@ -1,45 +1,0 @@
-/*
- * 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__ */
-
--- a/plugins/in_mp4/mp4av_common.h
+++ /dev/null
@@ -1,32 +1,0 @@
-/*
- * 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__ */
-