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