~ubuntu-branches/debian/wheezy/vlc/wheezy

« back to all changes in this revision

Viewing changes to extras/faad2/common/mp4av/adts.cpp

Tags: upstream-0.7.2.final
ImportĀ upstreamĀ versionĀ 0.7.2.final

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
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/
 
6
 * 
 
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.
 
11
 * 
 
12
 * The Original Code is MPEG4IP.
 
13
 * 
 
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.
 
17
 * 
 
18
 * Contributor(s): 
 
19
 *              Dave Mackie             dmackie@cisco.com
 
20
 */
 
21
 
 
22
/* 
 
23
 * Notes:
 
24
 *  - file formatted with tabstops == 4 spaces 
 
25
 */
 
26
 
 
27
#include <mp4av_common.h>
 
28
 
 
29
/*
 
30
 * ADTS Header: 
 
31
 *  MPEG-2 version 56 bits (byte aligned) 
 
32
 *  MPEG-4 version 56 bits (byte aligned) - note - changed for 0.99 version
 
33
 *
 
34
 * syncword                                             12 bits
 
35
 * id                                                   1 bit
 
36
 * layer                                                2 bits
 
37
 * protection_absent                    1 bit
 
38
 * profile                                              2 bits
 
39
 * sampling_frequency_index             4 bits
 
40
 * private                                              1 bit
 
41
 * channel_configuraton                 3 bits
 
42
 * original                                             1 bit
 
43
 * home                                                 1 bit
 
44
 * copyright_id                                 1 bit
 
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
 
49
 *
 
50
 * if (protection_absent == 0)
 
51
 *      crc_check                                       16 bits
 
52
 */
 
53
 
 
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
 
57
};
 
58
 
 
59
/*
 
60
 * compute ADTS frame size
 
61
 */
 
62
extern "C" u_int16_t MP4AV_AdtsGetFrameSize(u_int8_t* pHdr)
 
63
{
 
64
        /* extract the necessary fields from the header */
 
65
        uint16_t frameLength;
 
66
 
 
67
        frameLength = (((u_int16_t)(pHdr[3] & 0x3)) << 11) 
 
68
          | (((u_int16_t)pHdr[4]) << 3) | (pHdr[5] >> 5); 
 
69
 
 
70
        return frameLength;
 
71
}
 
72
 
 
73
/*
 
74
 * Compute length of ADTS header in bits
 
75
 */
 
76
extern "C" u_int16_t MP4AV_AdtsGetHeaderBitSize(u_int8_t* pHdr)
 
77
{
 
78
        u_int8_t hasCrc = !(pHdr[1] & 0x01);
 
79
        u_int16_t hdrSize;
 
80
 
 
81
        hdrSize = 56;
 
82
 
 
83
        if (hasCrc) {
 
84
                hdrSize += 16;
 
85
        }
 
86
        return hdrSize;
 
87
}
 
88
 
 
89
extern "C" u_int16_t MP4AV_AdtsGetHeaderByteSize(u_int8_t* pHdr)
 
90
{
 
91
        return (MP4AV_AdtsGetHeaderBitSize(pHdr) + 7) / 8;
 
92
}
 
93
 
 
94
extern "C" u_int8_t MP4AV_AdtsGetVersion(u_int8_t* pHdr)
 
95
{
 
96
        return (pHdr[1] & 0x08) >> 3;
 
97
}
 
98
 
 
99
extern "C" u_int8_t MP4AV_AdtsGetProfile(u_int8_t* pHdr)
 
100
{
 
101
        return (pHdr[2] & 0xc0) >> 6;
 
102
}
 
103
 
 
104
extern "C" u_int8_t MP4AV_AdtsGetSamplingRateIndex(u_int8_t* pHdr)
 
105
{
 
106
        return (pHdr[2] & 0x3c) >> 2;
 
107
}
 
108
 
 
109
extern "C" u_int8_t MP4AV_AdtsFindSamplingRateIndex(u_int32_t samplingRate)
 
110
{
 
111
        for (u_int8_t i = 0; i < NUM_ADTS_SAMPLING_RATES; i++) {
 
112
                if (samplingRate == AdtsSamplingRates[i]) {
 
113
                        return i;
 
114
                }
 
115
        }
 
116
        return NUM_ADTS_SAMPLING_RATES - 1;
 
117
}
 
118
 
 
119
extern "C" u_int32_t MP4AV_AdtsGetSamplingRate(u_int8_t* pHdr)
 
120
{
 
121
        return AdtsSamplingRates[MP4AV_AdtsGetSamplingRateIndex(pHdr)];
 
122
}
 
123
 
 
124
extern "C" u_int8_t MP4AV_AdtsGetChannels(u_int8_t* pHdr)
 
125
{
 
126
        return ((pHdr[2] & 0x1) << 2) | ((pHdr[3] & 0xc0) >> 6);
 
127
}
 
128
 
 
129
extern "C" bool MP4AV_AdtsMakeFrameFromMp4Sample(
 
130
        MP4FileHandle mp4File,
 
131
        MP4TrackId trackId,
 
132
        MP4SampleId sampleId,
 
133
        int force_profile,
 
134
        u_int8_t** ppAdtsData,
 
135
        u_int32_t* pAdtsDataLength)
 
136
{
 
137
        static MP4FileHandle lastMp4File = MP4_INVALID_FILE_HANDLE;
 
138
        static MP4TrackId lastMp4TrackId = MP4_INVALID_TRACK_ID;
 
139
        static bool isMpeg2;
 
140
        static u_int8_t profile;
 
141
        static u_int32_t samplingFrequency;
 
142
        static u_int8_t channels;
 
143
 
 
144
        if (mp4File != lastMp4File || trackId != lastMp4TrackId) {
 
145
 
 
146
                // changed cached file and track info
 
147
 
 
148
                lastMp4File = mp4File;
 
149
                lastMp4TrackId = trackId;
 
150
 
 
151
                u_int8_t audioType = MP4GetTrackEsdsObjectTypeId(mp4File, 
 
152
                                                                 trackId);
 
153
 
 
154
                if (MP4_IS_MPEG2_AAC_AUDIO_TYPE(audioType)) {
 
155
                        isMpeg2 = true;
 
156
                        profile = audioType - MP4_MPEG2_AAC_MAIN_AUDIO_TYPE;
 
157
                        if (force_profile == 4) {
 
158
                          isMpeg2 = false;
 
159
                          // profile remains the same
 
160
                        }
 
161
                } else if (audioType == MP4_MPEG4_AUDIO_TYPE) {
 
162
                        isMpeg2 = false;
 
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;
 
169
                            return false;
 
170
                          }
 
171
                          isMpeg2 = true;
 
172
                        }
 
173
                } else {
 
174
                        lastMp4File = MP4_INVALID_FILE_HANDLE;
 
175
                        lastMp4TrackId = MP4_INVALID_TRACK_ID;
 
176
                        return false;
 
177
                }
 
178
 
 
179
                u_int8_t* pConfig = NULL;
 
180
                u_int32_t configLength;
 
181
 
 
182
                MP4GetTrackESConfiguration(
 
183
                        mp4File, 
 
184
                        trackId,
 
185
                        &pConfig,
 
186
                        &configLength);
 
187
 
 
188
                if (pConfig == NULL || configLength < 2) {
 
189
                        lastMp4File = MP4_INVALID_FILE_HANDLE;
 
190
                        lastMp4TrackId = MP4_INVALID_TRACK_ID;
 
191
                        return false;
 
192
                }
 
193
 
 
194
                samplingFrequency = MP4AV_AacConfigGetSamplingRate(pConfig);
 
195
 
 
196
                channels = MP4AV_AacConfigGetChannels(pConfig);
 
197
 
 
198
        }
 
199
 
 
200
        bool rc;
 
201
        u_int8_t* pSample = NULL;
 
202
        u_int32_t sampleSize = 0;
 
203
 
 
204
        rc = MP4ReadSample(
 
205
                mp4File,
 
206
                trackId,
 
207
                sampleId,
 
208
                &pSample,
 
209
                &sampleSize);
 
210
 
 
211
        if (!rc) {
 
212
                return false;
 
213
        }
 
214
 
 
215
        rc = MP4AV_AdtsMakeFrame(
 
216
                pSample,
 
217
                sampleSize,
 
218
                isMpeg2,
 
219
                profile,
 
220
                samplingFrequency,
 
221
                channels,
 
222
                ppAdtsData,
 
223
                pAdtsDataLength);
 
224
 
 
225
        free(pSample);
 
226
 
 
227
        return rc;
 
228
}
 
229
 
 
230
extern "C" bool MP4AV_AdtsMakeFrame(
 
231
        u_int8_t* pData,
 
232
        u_int16_t dataLength,
 
233
        bool isMpeg2,
 
234
        u_int8_t profile,
 
235
        u_int32_t samplingFrequency,
 
236
        u_int8_t channels,
 
237
        u_int8_t** ppAdtsData,
 
238
        u_int32_t* pAdtsDataLength)
 
239
{
 
240
        *pAdtsDataLength = 7 + dataLength; // 56 bits only
 
241
 
 
242
        CMemoryBitstream adts;
 
243
 
 
244
        try {
 
245
                adts.AllocBytes(*pAdtsDataLength);
 
246
                *ppAdtsData = adts.GetBuffer();
 
247
 
 
248
                // build adts header
 
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
 
254
                adts.PutBits(
 
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
 
261
 
 
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
 
267
 
 
268
                // copy audio frame data
 
269
                adts.PutBytes(pData, dataLength);
 
270
        }
 
271
        catch (int e) {
 
272
                return false;
 
273
        }
 
274
 
 
275
        return true;
 
276
}
 
277