Line data Source code
1 : /* This Source Code Form is subject to the terms of the Mozilla Public
2 : * License, v. 2.0. If a copy of the MPL was not distributed with this
3 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 :
5 : #include "mp4_demuxer/Adts.h"
6 : #include "MediaData.h"
7 : #include "mozilla/Array.h"
8 : #include "mozilla/ArrayUtils.h"
9 : #include "nsAutoPtr.h"
10 :
11 : using namespace mozilla;
12 :
13 : namespace mp4_demuxer
14 : {
15 :
16 : int8_t
17 0 : Adts::GetFrequencyIndex(uint32_t aSamplesPerSecond)
18 : {
19 : static const uint32_t freq_lookup[] = { 96000, 88200, 64000, 48000, 44100,
20 : 32000, 24000, 22050, 16000, 12000,
21 : 11025, 8000, 7350, 0};
22 :
23 0 : int8_t i = 0;
24 0 : while (freq_lookup[i] && aSamplesPerSecond < freq_lookup[i]) {
25 0 : i++;
26 : }
27 :
28 0 : if (!freq_lookup[i]) {
29 0 : return -1;
30 : }
31 :
32 0 : return i;
33 : }
34 :
35 : bool
36 0 : Adts::ConvertSample(uint16_t aChannelCount, int8_t aFrequencyIndex,
37 : int8_t aProfile, MediaRawData* aSample)
38 : {
39 : static const int kADTSHeaderSize = 7;
40 :
41 0 : size_t newSize = aSample->Size() + kADTSHeaderSize;
42 :
43 : // ADTS header uses 13 bits for packet size.
44 0 : if (newSize >= (1 << 13) || aChannelCount > 15 ||
45 0 : aFrequencyIndex < 0 || aProfile < 1 || aProfile > 4) {
46 0 : return false;
47 : }
48 :
49 0 : Array<uint8_t, kADTSHeaderSize> header;
50 0 : header[0] = 0xff;
51 0 : header[1] = 0xf1;
52 0 : header[2] =
53 0 : ((aProfile - 1) << 6) + (aFrequencyIndex << 2) + (aChannelCount >> 2);
54 0 : header[3] = ((aChannelCount & 0x3) << 6) + (newSize >> 11);
55 0 : header[4] = (newSize & 0x7ff) >> 3;
56 0 : header[5] = ((newSize & 7) << 5) + 0x1f;
57 0 : header[6] = 0xfc;
58 :
59 0 : nsAutoPtr<MediaRawDataWriter> writer(aSample->CreateWriter());
60 0 : if (!writer->Prepend(&header[0], ArrayLength(header))) {
61 0 : return false;
62 : }
63 :
64 0 : if (aSample->mCrypto.mValid) {
65 0 : if (aSample->mCrypto.mPlainSizes.Length() == 0) {
66 0 : writer->mCrypto.mPlainSizes.AppendElement(kADTSHeaderSize);
67 0 : writer->mCrypto.mEncryptedSizes.AppendElement(aSample->Size() - kADTSHeaderSize);
68 : } else {
69 0 : writer->mCrypto.mPlainSizes[0] += kADTSHeaderSize;
70 : }
71 : }
72 :
73 0 : return true;
74 : }
75 : }
|