2
* The contents of this file are subject to the Mozilla Public
3
* License Version 1.1 (the "License"); you may not use this file
4
* except in compliance with the License. You may obtain a copy of
5
* the License at http://www.mozilla.org/MPL/
7
* Software distributed under the License is distributed on an "AS
8
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
9
* implied. See the License for the specific language governing
10
* rights and limitations under the License.
12
* The Original Code is MPEG4IP.
14
* The Initial Developer of the Original Code is Cisco Systems Inc.
15
* Portions created by Cisco Systems Inc. are
16
* Copyright (C) Cisco Systems Inc. 2000-2002. All Rights Reserved.
19
* Dave Mackie dmackie@cisco.com
24
* - file formatted with tabstops == 4 spaces
27
#include <mp4av_common.h>
31
* MPEG-2 version 56 bits (byte aligned)
32
* MPEG-4 version 56 bits (byte aligned) - note - changed for 0.99 version
37
* protection_absent 1 bit
39
* sampling_frequency_index 4 bits
41
* channel_configuraton 3 bits
45
* copyright_id_start 1 bit
46
* aac_frame_length 13 bits
47
* adts_buffer_fullness 11 bits
48
* num_raw_data_blocks 2 bits
50
* if (protection_absent == 0)
54
u_int32_t AdtsSamplingRates[NUM_ADTS_SAMPLING_RATES] = {
55
96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
56
16000, 12000, 11025, 8000, 7350, 0, 0, 0
60
* compute ADTS frame size
62
extern "C" u_int16_t MP4AV_AdtsGetFrameSize(u_int8_t* pHdr)
64
/* extract the necessary fields from the header */
67
frameLength = (((u_int16_t)(pHdr[3] & 0x3)) << 11)
68
| (((u_int16_t)pHdr[4]) << 3) | (pHdr[5] >> 5);
74
* Compute length of ADTS header in bits
76
extern "C" u_int16_t MP4AV_AdtsGetHeaderBitSize(u_int8_t* pHdr)
78
u_int8_t hasCrc = !(pHdr[1] & 0x01);
89
extern "C" u_int16_t MP4AV_AdtsGetHeaderByteSize(u_int8_t* pHdr)
91
return (MP4AV_AdtsGetHeaderBitSize(pHdr) + 7) / 8;
94
extern "C" u_int8_t MP4AV_AdtsGetVersion(u_int8_t* pHdr)
96
return (pHdr[1] & 0x08) >> 3;
99
extern "C" u_int8_t MP4AV_AdtsGetProfile(u_int8_t* pHdr)
101
return (pHdr[2] & 0xc0) >> 6;
104
extern "C" u_int8_t MP4AV_AdtsGetSamplingRateIndex(u_int8_t* pHdr)
106
return (pHdr[2] & 0x3c) >> 2;
109
extern "C" u_int8_t MP4AV_AdtsFindSamplingRateIndex(u_int32_t samplingRate)
111
for (u_int8_t i = 0; i < NUM_ADTS_SAMPLING_RATES; i++) {
112
if (samplingRate == AdtsSamplingRates[i]) {
116
return NUM_ADTS_SAMPLING_RATES - 1;
119
extern "C" u_int32_t MP4AV_AdtsGetSamplingRate(u_int8_t* pHdr)
121
return AdtsSamplingRates[MP4AV_AdtsGetSamplingRateIndex(pHdr)];
124
extern "C" u_int8_t MP4AV_AdtsGetChannels(u_int8_t* pHdr)
126
return ((pHdr[2] & 0x1) << 2) | ((pHdr[3] & 0xc0) >> 6);
129
extern "C" bool MP4AV_AdtsMakeFrameFromMp4Sample(
130
MP4FileHandle mp4File,
132
MP4SampleId sampleId,
134
u_int8_t** ppAdtsData,
135
u_int32_t* pAdtsDataLength)
137
static MP4FileHandle lastMp4File = MP4_INVALID_FILE_HANDLE;
138
static MP4TrackId lastMp4TrackId = MP4_INVALID_TRACK_ID;
140
static u_int8_t profile;
141
static u_int32_t samplingFrequency;
142
static u_int8_t channels;
144
if (mp4File != lastMp4File || trackId != lastMp4TrackId) {
146
// changed cached file and track info
148
lastMp4File = mp4File;
149
lastMp4TrackId = trackId;
151
u_int8_t audioType = MP4GetTrackEsdsObjectTypeId(mp4File,
154
if (MP4_IS_MPEG2_AAC_AUDIO_TYPE(audioType)) {
156
profile = audioType - MP4_MPEG2_AAC_MAIN_AUDIO_TYPE;
157
if (force_profile == 4) {
159
// profile remains the same
161
} else if (audioType == MP4_MPEG4_AUDIO_TYPE) {
163
profile = MP4GetTrackAudioMpeg4Type(mp4File, trackId) - 1;
164
if (force_profile == 2) {
165
if (profile > MP4_MPEG4_AAC_SSR_AUDIO_TYPE) {
166
// they can't use these profiles for mpeg2.
167
lastMp4File = MP4_INVALID_FILE_HANDLE;
168
lastMp4TrackId =MP4_INVALID_TRACK_ID;
174
lastMp4File = MP4_INVALID_FILE_HANDLE;
175
lastMp4TrackId = MP4_INVALID_TRACK_ID;
179
u_int8_t* pConfig = NULL;
180
u_int32_t configLength;
182
MP4GetTrackESConfiguration(
188
if (pConfig == NULL || configLength < 2) {
189
lastMp4File = MP4_INVALID_FILE_HANDLE;
190
lastMp4TrackId = MP4_INVALID_TRACK_ID;
194
samplingFrequency = MP4AV_AacConfigGetSamplingRate(pConfig);
196
channels = MP4AV_AacConfigGetChannels(pConfig);
201
u_int8_t* pSample = NULL;
202
u_int32_t sampleSize = 0;
215
rc = MP4AV_AdtsMakeFrame(
230
extern "C" bool MP4AV_AdtsMakeFrame(
232
u_int16_t dataLength,
235
u_int32_t samplingFrequency,
237
u_int8_t** ppAdtsData,
238
u_int32_t* pAdtsDataLength)
240
*pAdtsDataLength = 7 + dataLength; // 56 bits only
242
CMemoryBitstream adts;
245
adts.AllocBytes(*pAdtsDataLength);
246
*ppAdtsData = adts.GetBuffer();
249
adts.PutBits(0xFFF, 12); // syncword
250
adts.PutBits(isMpeg2, 1); // id
251
adts.PutBits(0, 2); // layer
252
adts.PutBits(1, 1); // protection_absent
253
adts.PutBits(profile, 2); // profile
255
MP4AV_AdtsFindSamplingRateIndex(samplingFrequency),
256
4); // sampling_frequency_index
257
adts.PutBits(0, 1); // private
258
adts.PutBits(channels, 3); // channel_configuration
259
adts.PutBits(0, 1); // original
260
adts.PutBits(0, 1); // home
262
adts.PutBits(0, 1); // copyright_id
263
adts.PutBits(0, 1); // copyright_id_start
264
adts.PutBits(*pAdtsDataLength, 13); // aac_frame_length
265
adts.PutBits(0x7FF, 11); // adts_buffer_fullness
266
adts.PutBits(0, 2); // num_raw_data_blocks
268
// copy audio frame data
269
adts.PutBytes(pData, dataLength);