Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
SDK
/
exoplayer
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
1ca9a061
authored
Feb 28, 2020
by
andrewlewis
Committed by
Oliver Woodman
Feb 28, 2020
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Split AAC utils out of CodecSpecificDataUtil
PiperOrigin-RevId: 297823929
parent
ffdc5805
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
356 additions
and
330 deletions
library/common/src/main/java/com/google/android/exoplayer2/audio/AacUtil.java
library/common/src/main/java/com/google/android/exoplayer2/util/CodecSpecificDataUtil.java
library/core/src/main/java/com/google/android/exoplayer2/audio/DefaultAudioSink.java
library/extractor/src/main/java/com/google/android/exoplayer2/extractor/flv/AudioTagPayloadReader.java
library/extractor/src/main/java/com/google/android/exoplayer2/extractor/mp4/AtomParsers.java
library/extractor/src/main/java/com/google/android/exoplayer2/extractor/ts/AdtsReader.java
library/extractor/src/main/java/com/google/android/exoplayer2/extractor/ts/LatmReader.java
library/smoothstreaming/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/manifest/SsManifestParser.java
library/common/src/main/java/com/google/android/exoplayer2/audio/AacUtil.java
0 → 100644
View file @
1ca9a061
/*
* Copyright 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
com
.
google
.
android
.
exoplayer2
.
audio
;
import
com.google.android.exoplayer2.C
;
import
com.google.android.exoplayer2.ParserException
;
import
com.google.android.exoplayer2.util.Assertions
;
import
com.google.android.exoplayer2.util.Log
;
import
com.google.android.exoplayer2.util.ParsableBitArray
;
/** Utility methods for handling AAC audio streams. */
public
final
class
AacUtil
{
private
static
final
String
TAG
=
"AacUtil"
;
/** Holds sample format information for AAC audio. */
public
static
final
class
Config
{
/** The sample rate in Hertz. */
public
final
int
sampleRateHz
;
/** The number of channels. */
public
final
int
channelCount
;
/** The RFC 6381 codecs string. */
public
final
String
codecs
;
private
Config
(
int
sampleRateHz
,
int
channelCount
,
String
codecs
)
{
this
.
sampleRateHz
=
sampleRateHz
;
this
.
channelCount
=
channelCount
;
this
.
codecs
=
codecs
;
}
}
// Audio sample count constants assume the frameLengthFlag in the access unit is 0.
/**
* Number of raw audio samples that are produced per channel when decoding an AAC LC access unit.
*/
public
static
final
int
AAC_LC_AUDIO_SAMPLE_COUNT
=
1024
;
/**
* Number of raw audio samples that are produced per channel when decoding an AAC XHE access unit.
*/
public
static
final
int
AAC_XHE_AUDIO_SAMPLE_COUNT
=
AAC_LC_AUDIO_SAMPLE_COUNT
;
/**
* Number of raw audio samples that are produced per channel when decoding an AAC HE access unit.
*/
public
static
final
int
AAC_HE_AUDIO_SAMPLE_COUNT
=
2048
;
/**
* Number of raw audio samples that are produced per channel when decoding an AAC LD access unit.
*/
public
static
final
int
AAC_LD_AUDIO_SAMPLE_COUNT
=
512
;
private
static
final
int
AUDIO_SPECIFIC_CONFIG_FREQUENCY_INDEX_ARBITRARY
=
0xF
;
private
static
final
int
[]
AUDIO_SPECIFIC_CONFIG_SAMPLING_RATE_TABLE
=
new
int
[]
{
96000
,
88200
,
64000
,
48000
,
44100
,
32000
,
24000
,
22050
,
16000
,
12000
,
11025
,
8000
,
7350
};
private
static
final
int
AUDIO_SPECIFIC_CONFIG_CHANNEL_CONFIGURATION_INVALID
=
-
1
;
/**
* In the channel configurations below, <A> indicates a single channel element; (A, B)
* indicates a channel pair element; and [A] indicates a low-frequency effects element. The
* speaker mapping short forms used are:
*
* <ul>
* <li>FC: front center
* <li>BC: back center
* <li>FL/FR: front left/right
* <li>FCL/FCR: front center left/right
* <li>FTL/FTR: front top left/right
* <li>SL/SR: back surround left/right
* <li>BL/BR: back left/right
* <li>LFE: low frequency effects
* </ul>
*/
private
static
final
int
[]
AUDIO_SPECIFIC_CONFIG_CHANNEL_COUNT_TABLE
=
new
int
[]
{
0
,
1
,
/* mono: <FC> */
2
,
/* stereo: (FL, FR) */
3
,
/* 3.0: <FC>, (FL, FR) */
4
,
/* 4.0: <FC>, (FL, FR), <BC> */
5
,
/* 5.0 back: <FC>, (FL, FR), (SL, SR) */
6
,
/* 5.1 back: <FC>, (FL, FR), (SL, SR), <BC>, [LFE] */
8
,
/* 7.1 wide back: <FC>, (FCL, FCR), (FL, FR), (SL, SR), [LFE] */
AUDIO_SPECIFIC_CONFIG_CHANNEL_CONFIGURATION_INVALID
,
AUDIO_SPECIFIC_CONFIG_CHANNEL_CONFIGURATION_INVALID
,
AUDIO_SPECIFIC_CONFIG_CHANNEL_CONFIGURATION_INVALID
,
7
,
/* 6.1: <FC>, (FL, FR), (SL, SR), <RC>, [LFE] */
8
,
/* 7.1: <FC>, (FL, FR), (SL, SR), (BL, BR), [LFE] */
AUDIO_SPECIFIC_CONFIG_CHANNEL_CONFIGURATION_INVALID
,
8
,
/* 7.1 top: <FC>, (FL, FR), (SL, SR), [LFE], (FTL, FTR) */
AUDIO_SPECIFIC_CONFIG_CHANNEL_CONFIGURATION_INVALID
};
/**
* Prefix for the RFC 6381 codecs string for AAC formats. To form a full codecs string, suffix the
* decimal AudioObjectType.
*/
private
static
final
String
CODECS_STRING_PREFIX
=
"mp4a.40."
;
// Advanced Audio Coding Low-Complexity profile.
private
static
final
int
AUDIO_OBJECT_TYPE_AAC_LC
=
2
;
// Spectral Band Replication.
private
static
final
int
AUDIO_OBJECT_TYPE_AAC_SBR
=
5
;
// Error Resilient Bit-Sliced Arithmetic Coding.
private
static
final
int
AUDIO_OBJECT_TYPE_AAC_ER_BSAC
=
22
;
// Enhanced low delay.
private
static
final
int
AUDIO_OBJECT_TYPE_AAC_ELD
=
23
;
// Parametric Stereo.
private
static
final
int
AUDIO_OBJECT_TYPE_AAC_PS
=
29
;
// Escape code for extended audio object types.
private
static
final
int
AUDIO_OBJECT_TYPE_ESCAPE
=
31
;
// Extended high efficiency.
private
static
final
int
AUDIO_OBJECT_TYPE_AAC_XHE
=
42
;
/**
* Parses an AAC AudioSpecificConfig, as defined in ISO 14496-3 1.6.2.1
*
* @param audioSpecificConfig A byte array containing the AudioSpecificConfig to parse.
* @return The parsed configuration.
* @throws ParserException If the AudioSpecificConfig cannot be parsed as it's not supported.
*/
public
static
Config
parseAudioSpecificConfig
(
byte
[]
audioSpecificConfig
)
throws
ParserException
{
return
parseAudioSpecificConfig
(
new
ParsableBitArray
(
audioSpecificConfig
),
/* forceReadToEnd= */
false
);
}
/**
* Parses an AAC AudioSpecificConfig, as defined in ISO 14496-3 1.6.2.1
*
* @param bitArray A {@link ParsableBitArray} containing the AudioSpecificConfig to parse. The
* position is advanced to the end of the AudioSpecificConfig.
* @param forceReadToEnd Whether the entire AudioSpecificConfig should be read. Required for
* knowing the length of the configuration payload.
* @return The parsed configuration.
* @throws ParserException If the AudioSpecificConfig cannot be parsed as it's not supported.
*/
public
static
Config
parseAudioSpecificConfig
(
ParsableBitArray
bitArray
,
boolean
forceReadToEnd
)
throws
ParserException
{
int
audioObjectType
=
getAudioObjectType
(
bitArray
);
int
sampleRateHz
=
getSamplingFrequency
(
bitArray
);
int
channelConfiguration
=
bitArray
.
readBits
(
4
);
String
codecs
=
CODECS_STRING_PREFIX
+
audioObjectType
;
if
(
audioObjectType
==
AUDIO_OBJECT_TYPE_AAC_SBR
||
audioObjectType
==
AUDIO_OBJECT_TYPE_AAC_PS
)
{
// For an AAC bitstream using spectral band replication (SBR) or parametric stereo (PS) with
// explicit signaling, we return the extension sampling frequency as the sample rate of the
// content; this is identical to the sample rate of the decoded output but may differ from
// the sample rate set above.
// Use the extensionSamplingFrequencyIndex.
sampleRateHz
=
getSamplingFrequency
(
bitArray
);
audioObjectType
=
getAudioObjectType
(
bitArray
);
if
(
audioObjectType
==
AUDIO_OBJECT_TYPE_AAC_ER_BSAC
)
{
// Use the extensionChannelConfiguration.
channelConfiguration
=
bitArray
.
readBits
(
4
);
}
}
if
(
forceReadToEnd
)
{
switch
(
audioObjectType
)
{
case
1
:
case
2
:
case
3
:
case
4
:
case
6
:
case
7
:
case
17
:
case
19
:
case
20
:
case
21
:
case
22
:
case
23
:
parseGaSpecificConfig
(
bitArray
,
audioObjectType
,
channelConfiguration
);
break
;
default
:
throw
new
ParserException
(
"Unsupported audio object type: "
+
audioObjectType
);
}
switch
(
audioObjectType
)
{
case
17
:
case
19
:
case
20
:
case
21
:
case
22
:
case
23
:
int
epConfig
=
bitArray
.
readBits
(
2
);
if
(
epConfig
==
2
||
epConfig
==
3
)
{
throw
new
ParserException
(
"Unsupported epConfig: "
+
epConfig
);
}
break
;
default
:
break
;
}
}
// For supported containers, bits_to_decode() is always 0.
int
channelCount
=
AUDIO_SPECIFIC_CONFIG_CHANNEL_COUNT_TABLE
[
channelConfiguration
];
Assertions
.
checkArgument
(
channelCount
!=
AUDIO_SPECIFIC_CONFIG_CHANNEL_CONFIGURATION_INVALID
);
return
new
Config
(
sampleRateHz
,
channelCount
,
codecs
);
}
/**
* Builds a simple AAC LC AudioSpecificConfig, as defined in ISO 14496-3 1.6.2.1
*
* @param sampleRate The sample rate in Hz.
* @param channelCount The channel count.
* @return The AudioSpecificConfig.
*/
public
static
byte
[]
buildAacLcAudioSpecificConfig
(
int
sampleRate
,
int
channelCount
)
{
int
sampleRateIndex
=
C
.
INDEX_UNSET
;
for
(
int
i
=
0
;
i
<
AUDIO_SPECIFIC_CONFIG_SAMPLING_RATE_TABLE
.
length
;
++
i
)
{
if
(
sampleRate
==
AUDIO_SPECIFIC_CONFIG_SAMPLING_RATE_TABLE
[
i
])
{
sampleRateIndex
=
i
;
}
}
int
channelConfig
=
C
.
INDEX_UNSET
;
for
(
int
i
=
0
;
i
<
AUDIO_SPECIFIC_CONFIG_CHANNEL_COUNT_TABLE
.
length
;
++
i
)
{
if
(
channelCount
==
AUDIO_SPECIFIC_CONFIG_CHANNEL_COUNT_TABLE
[
i
])
{
channelConfig
=
i
;
}
}
if
(
sampleRate
==
C
.
INDEX_UNSET
||
channelConfig
==
C
.
INDEX_UNSET
)
{
throw
new
IllegalArgumentException
(
"Invalid sample rate or number of channels: "
+
sampleRate
+
", "
+
channelCount
);
}
return
buildAudioSpecificConfig
(
AUDIO_OBJECT_TYPE_AAC_LC
,
sampleRateIndex
,
channelConfig
);
}
/**
* Builds a simple AudioSpecificConfig, as defined in ISO 14496-3 1.6.2.1
*
* @param audioObjectType The audio object type.
* @param sampleRateIndex The sample rate index.
* @param channelConfig The channel configuration.
* @return The AudioSpecificConfig.
*/
public
static
byte
[]
buildAudioSpecificConfig
(
int
audioObjectType
,
int
sampleRateIndex
,
int
channelConfig
)
{
byte
[]
specificConfig
=
new
byte
[
2
];
specificConfig
[
0
]
=
(
byte
)
(((
audioObjectType
<<
3
)
&
0xF8
)
|
((
sampleRateIndex
>>
1
)
&
0x07
));
specificConfig
[
1
]
=
(
byte
)
(((
sampleRateIndex
<<
7
)
&
0x80
)
|
((
channelConfig
<<
3
)
&
0x78
));
return
specificConfig
;
}
/** Returns the encoding for a given AAC audio object type. */
@C
.
Encoding
public
static
int
getEncodingForAudioObjectType
(
int
audioObjectType
)
{
switch
(
audioObjectType
)
{
case
AUDIO_OBJECT_TYPE_AAC_LC:
return
C
.
ENCODING_AAC_LC
;
case
AUDIO_OBJECT_TYPE_AAC_SBR:
return
C
.
ENCODING_AAC_HE_V1
;
case
AUDIO_OBJECT_TYPE_AAC_PS:
return
C
.
ENCODING_AAC_HE_V2
;
case
AUDIO_OBJECT_TYPE_AAC_XHE:
return
C
.
ENCODING_AAC_XHE
;
case
AUDIO_OBJECT_TYPE_AAC_ELD:
return
C
.
ENCODING_AAC_ELD
;
default
:
return
C
.
ENCODING_INVALID
;
}
}
/**
* Returns the AAC audio object type as specified in 14496-3 (2005) Table 1.14.
*
* @param bitArray The bit array containing the audio specific configuration.
* @return The audio object type.
*/
private
static
int
getAudioObjectType
(
ParsableBitArray
bitArray
)
{
int
audioObjectType
=
bitArray
.
readBits
(
5
);
if
(
audioObjectType
==
AUDIO_OBJECT_TYPE_ESCAPE
)
{
audioObjectType
=
32
+
bitArray
.
readBits
(
6
);
}
return
audioObjectType
;
}
/**
* Returns the AAC sampling frequency (or extension sampling frequency) as specified in 14496-3
* (2005) Table 1.13.
*
* @param bitArray The bit array containing the audio specific configuration.
* @return The sampling frequency.
*/
private
static
int
getSamplingFrequency
(
ParsableBitArray
bitArray
)
{
int
samplingFrequency
;
int
frequencyIndex
=
bitArray
.
readBits
(
4
);
if
(
frequencyIndex
==
AUDIO_SPECIFIC_CONFIG_FREQUENCY_INDEX_ARBITRARY
)
{
samplingFrequency
=
bitArray
.
readBits
(
24
);
}
else
{
Assertions
.
checkArgument
(
frequencyIndex
<
13
);
samplingFrequency
=
AUDIO_SPECIFIC_CONFIG_SAMPLING_RATE_TABLE
[
frequencyIndex
];
}
return
samplingFrequency
;
}
private
static
void
parseGaSpecificConfig
(
ParsableBitArray
bitArray
,
int
audioObjectType
,
int
channelConfiguration
)
{
boolean
frameLengthFlag
=
bitArray
.
readBit
();
if
(
frameLengthFlag
)
{
Log
.
w
(
TAG
,
"Unexpected frameLengthFlag = 1"
);
}
boolean
dependsOnCoreDecoder
=
bitArray
.
readBit
();
if
(
dependsOnCoreDecoder
)
{
bitArray
.
skipBits
(
14
);
// coreCoderDelay.
}
boolean
extensionFlag
=
bitArray
.
readBit
();
if
(
channelConfiguration
==
0
)
{
throw
new
UnsupportedOperationException
();
// TODO: Implement programConfigElement();
}
if
(
audioObjectType
==
6
||
audioObjectType
==
20
)
{
bitArray
.
skipBits
(
3
);
// layerNr.
}
if
(
extensionFlag
)
{
if
(
audioObjectType
==
22
)
{
bitArray
.
skipBits
(
16
);
// numOfSubFrame (5), layer_length(11).
}
if
(
audioObjectType
==
17
||
audioObjectType
==
19
||
audioObjectType
==
20
||
audioObjectType
==
23
)
{
// aacSectionDataResilienceFlag, aacScalefactorDataResilienceFlag,
// aacSpectralDataResilienceFlag.
bitArray
.
skipBits
(
3
);
}
bitArray
.
skipBits
(
1
);
// extensionFlag3.
}
}
private
AacUtil
()
{}
}
library/common/src/main/java/com/google/android/exoplayer2/util/CodecSpecificDataUtil.java
View file @
1ca9a061
...
...
@@ -18,7 +18,6 @@ package com.google.android.exoplayer2.util;
import
android.util.Pair
;
import
androidx.annotation.Nullable
;
import
com.google.android.exoplayer2.C
;
import
com.google.android.exoplayer2.ParserException
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.List
;
...
...
@@ -26,253 +25,8 @@ import java.util.List;
/** Provides utilities for handling various types of codec-specific data. */
public
final
class
CodecSpecificDataUtil
{
private
static
final
String
TAG
=
"CodecSpecificDataUtil"
;
/** Holds sample format information for AAC audio. */
public
static
final
class
AacConfig
{
/** The sample rate in Hertz. */
public
final
int
sampleRateHz
;
/** The number of channels. */
public
final
int
channelCount
;
/** The RFC 6381 codecs string. */
public
final
String
codecs
;
private
AacConfig
(
int
sampleRateHz
,
int
channelCount
,
String
codecs
)
{
this
.
sampleRateHz
=
sampleRateHz
;
this
.
channelCount
=
channelCount
;
this
.
codecs
=
codecs
;
}
}
// AAC audio sample count constants assume the frameLengthFlag in the access unit is 0.
/**
* Number of raw audio samples that are produced per channel when decoding an AAC LC access unit.
*/
public
static
final
int
AAC_LC_AUDIO_SAMPLE_COUNT
=
1024
;
/**
* Number of raw audio samples that are produced per channel when decoding an AAC XHE access unit.
*/
public
static
final
int
AAC_XHE_AUDIO_SAMPLE_COUNT
=
AAC_LC_AUDIO_SAMPLE_COUNT
;
/**
* Number of raw audio samples that are produced per channel when decoding an AAC HE access unit.
*/
public
static
final
int
AAC_HE_AUDIO_SAMPLE_COUNT
=
2048
;
/**
* Number of raw audio samples that are produced per channel when decoding an AAC LD access unit.
*/
public
static
final
int
AAC_LD_AUDIO_SAMPLE_COUNT
=
512
;
private
static
final
byte
[]
NAL_START_CODE
=
new
byte
[]
{
0
,
0
,
0
,
1
};
private
static
final
int
AUDIO_SPECIFIC_CONFIG_FREQUENCY_INDEX_ARBITRARY
=
0xF
;
private
static
final
int
[]
AUDIO_SPECIFIC_CONFIG_SAMPLING_RATE_TABLE
=
new
int
[]
{
96000
,
88200
,
64000
,
48000
,
44100
,
32000
,
24000
,
22050
,
16000
,
12000
,
11025
,
8000
,
7350
};
private
static
final
int
AUDIO_SPECIFIC_CONFIG_CHANNEL_CONFIGURATION_INVALID
=
-
1
;
/**
* In the channel configurations below, <A> indicates a single channel element; (A, B) indicates a
* channel pair element; and [A] indicates a low-frequency effects element.
* The speaker mapping short forms used are:
* - FC: front center
* - BC: back center
* - FL/FR: front left/right
* - FCL/FCR: front center left/right
* - FTL/FTR: front top left/right
* - SL/SR: back surround left/right
* - BL/BR: back left/right
* - LFE: low frequency effects
*/
private
static
final
int
[]
AUDIO_SPECIFIC_CONFIG_CHANNEL_COUNT_TABLE
=
new
int
[]
{
0
,
1
,
/* mono: <FC> */
2
,
/* stereo: (FL, FR) */
3
,
/* 3.0: <FC>, (FL, FR) */
4
,
/* 4.0: <FC>, (FL, FR), <BC> */
5
,
/* 5.0 back: <FC>, (FL, FR), (SL, SR) */
6
,
/* 5.1 back: <FC>, (FL, FR), (SL, SR), <BC>, [LFE] */
8
,
/* 7.1 wide back: <FC>, (FCL, FCR), (FL, FR), (SL, SR), [LFE] */
AUDIO_SPECIFIC_CONFIG_CHANNEL_CONFIGURATION_INVALID
,
AUDIO_SPECIFIC_CONFIG_CHANNEL_CONFIGURATION_INVALID
,
AUDIO_SPECIFIC_CONFIG_CHANNEL_CONFIGURATION_INVALID
,
7
,
/* 6.1: <FC>, (FL, FR), (SL, SR), <RC>, [LFE] */
8
,
/* 7.1: <FC>, (FL, FR), (SL, SR), (BL, BR), [LFE] */
AUDIO_SPECIFIC_CONFIG_CHANNEL_CONFIGURATION_INVALID
,
8
,
/* 7.1 top: <FC>, (FL, FR), (SL, SR), [LFE], (FTL, FTR) */
AUDIO_SPECIFIC_CONFIG_CHANNEL_CONFIGURATION_INVALID
};
/**
* Prefix for the RFC 6381 codecs string for AAC formats. To form a full codecs string, suffix the
* decimal AudioObjectType.
*/
private
static
final
String
AAC_CODECS_STRING_PREFIX
=
"mp4a.40."
;
// Advanced Audio Coding Low-Complexity profile.
private
static
final
int
AUDIO_OBJECT_TYPE_AAC_LC
=
2
;
// Spectral Band Replication.
private
static
final
int
AUDIO_OBJECT_TYPE_AAC_SBR
=
5
;
// Error Resilient Bit-Sliced Arithmetic Coding.
private
static
final
int
AUDIO_OBJECT_TYPE_AAC_ER_BSAC
=
22
;
// Enhanced low delay.
private
static
final
int
AUDIO_OBJECT_TYPE_AAC_ELD
=
23
;
// Parametric Stereo.
private
static
final
int
AUDIO_OBJECT_TYPE_AAC_PS
=
29
;
// Escape code for extended audio object types.
private
static
final
int
AUDIO_OBJECT_TYPE_ESCAPE
=
31
;
// Extended high efficiency.
private
static
final
int
AUDIO_OBJECT_TYPE_AAC_XHE
=
42
;
private
CodecSpecificDataUtil
()
{}
/**
* Parses an AAC AudioSpecificConfig, as defined in ISO 14496-3 1.6.2.1
*
* @param audioSpecificConfig A byte array containing the AudioSpecificConfig to parse.
* @return The parsed configuration.
* @throws ParserException If the AudioSpecificConfig cannot be parsed as it's not supported.
*/
public
static
AacConfig
parseAacAudioSpecificConfig
(
byte
[]
audioSpecificConfig
)
throws
ParserException
{
return
parseAacAudioSpecificConfig
(
new
ParsableBitArray
(
audioSpecificConfig
),
/* forceReadToEnd= */
false
);
}
/**
* Parses an AAC AudioSpecificConfig, as defined in ISO 14496-3 1.6.2.1
*
* @param bitArray A {@link ParsableBitArray} containing the AudioSpecificConfig to parse. The
* position is advanced to the end of the AudioSpecificConfig.
* @param forceReadToEnd Whether the entire AudioSpecificConfig should be read. Required for
* knowing the length of the configuration payload.
* @return The parsed configuration.
* @throws ParserException If the AudioSpecificConfig cannot be parsed as it's not supported.
*/
public
static
AacConfig
parseAacAudioSpecificConfig
(
ParsableBitArray
bitArray
,
boolean
forceReadToEnd
)
throws
ParserException
{
int
audioObjectType
=
getAacAudioObjectType
(
bitArray
);
int
sampleRateHz
=
getAacSamplingFrequency
(
bitArray
);
int
channelConfiguration
=
bitArray
.
readBits
(
4
);
String
codecs
=
AAC_CODECS_STRING_PREFIX
+
audioObjectType
;
if
(
audioObjectType
==
AUDIO_OBJECT_TYPE_AAC_SBR
||
audioObjectType
==
AUDIO_OBJECT_TYPE_AAC_PS
)
{
// For an AAC bitstream using spectral band replication (SBR) or parametric stereo (PS) with
// explicit signaling, we return the extension sampling frequency as the sample rate of the
// content; this is identical to the sample rate of the decoded output but may differ from
// the sample rate set above.
// Use the extensionSamplingFrequencyIndex.
sampleRateHz
=
getAacSamplingFrequency
(
bitArray
);
audioObjectType
=
getAacAudioObjectType
(
bitArray
);
if
(
audioObjectType
==
AUDIO_OBJECT_TYPE_AAC_ER_BSAC
)
{
// Use the extensionChannelConfiguration.
channelConfiguration
=
bitArray
.
readBits
(
4
);
}
}
if
(
forceReadToEnd
)
{
switch
(
audioObjectType
)
{
case
1
:
case
2
:
case
3
:
case
4
:
case
6
:
case
7
:
case
17
:
case
19
:
case
20
:
case
21
:
case
22
:
case
23
:
parseGaSpecificConfig
(
bitArray
,
audioObjectType
,
channelConfiguration
);
break
;
default
:
throw
new
ParserException
(
"Unsupported audio object type: "
+
audioObjectType
);
}
switch
(
audioObjectType
)
{
case
17
:
case
19
:
case
20
:
case
21
:
case
22
:
case
23
:
int
epConfig
=
bitArray
.
readBits
(
2
);
if
(
epConfig
==
2
||
epConfig
==
3
)
{
throw
new
ParserException
(
"Unsupported epConfig: "
+
epConfig
);
}
break
;
}
}
// For supported containers, bits_to_decode() is always 0.
int
channelCount
=
AUDIO_SPECIFIC_CONFIG_CHANNEL_COUNT_TABLE
[
channelConfiguration
];
Assertions
.
checkArgument
(
channelCount
!=
AUDIO_SPECIFIC_CONFIG_CHANNEL_CONFIGURATION_INVALID
);
return
new
AacConfig
(
sampleRateHz
,
channelCount
,
codecs
);
}
/**
* Builds a simple HE-AAC LC AudioSpecificConfig, as defined in ISO 14496-3 1.6.2.1
*
* @param sampleRate The sample rate in Hz.
* @param channelCount The channel count.
* @return The AudioSpecificConfig.
*/
public
static
byte
[]
buildAacLcAudioSpecificConfig
(
int
sampleRate
,
int
channelCount
)
{
int
sampleRateIndex
=
C
.
INDEX_UNSET
;
for
(
int
i
=
0
;
i
<
AUDIO_SPECIFIC_CONFIG_SAMPLING_RATE_TABLE
.
length
;
++
i
)
{
if
(
sampleRate
==
AUDIO_SPECIFIC_CONFIG_SAMPLING_RATE_TABLE
[
i
])
{
sampleRateIndex
=
i
;
}
}
int
channelConfig
=
C
.
INDEX_UNSET
;
for
(
int
i
=
0
;
i
<
AUDIO_SPECIFIC_CONFIG_CHANNEL_COUNT_TABLE
.
length
;
++
i
)
{
if
(
channelCount
==
AUDIO_SPECIFIC_CONFIG_CHANNEL_COUNT_TABLE
[
i
])
{
channelConfig
=
i
;
}
}
if
(
sampleRate
==
C
.
INDEX_UNSET
||
channelConfig
==
C
.
INDEX_UNSET
)
{
throw
new
IllegalArgumentException
(
"Invalid sample rate or number of channels: "
+
sampleRate
+
", "
+
channelCount
);
}
return
buildAacAudioSpecificConfig
(
AUDIO_OBJECT_TYPE_AAC_LC
,
sampleRateIndex
,
channelConfig
);
}
/**
* Builds a simple AudioSpecificConfig, as defined in ISO 14496-3 1.6.2.1
*
* @param audioObjectType The audio object type.
* @param sampleRateIndex The sample rate index.
* @param channelConfig The channel configuration.
* @return The AudioSpecificConfig.
*/
public
static
byte
[]
buildAacAudioSpecificConfig
(
int
audioObjectType
,
int
sampleRateIndex
,
int
channelConfig
)
{
byte
[]
specificConfig
=
new
byte
[
2
];
specificConfig
[
0
]
=
(
byte
)
(((
audioObjectType
<<
3
)
&
0xF8
)
|
((
sampleRateIndex
>>
1
)
&
0x07
));
specificConfig
[
1
]
=
(
byte
)
(((
sampleRateIndex
<<
7
)
&
0x80
)
|
((
channelConfig
<<
3
)
&
0x78
));
return
specificConfig
;
}
/** Returns the encoding for a given AAC audio object type. */
@C
.
Encoding
public
static
int
getEncodingForAacAudioObjectType
(
int
audioObjectType
)
{
switch
(
audioObjectType
)
{
case
AUDIO_OBJECT_TYPE_AAC_LC:
return
C
.
ENCODING_AAC_LC
;
case
AUDIO_OBJECT_TYPE_AAC_SBR:
return
C
.
ENCODING_AAC_HE_V1
;
case
AUDIO_OBJECT_TYPE_AAC_PS:
return
C
.
ENCODING_AAC_HE_V2
;
case
AUDIO_OBJECT_TYPE_AAC_XHE:
return
C
.
ENCODING_AAC_XHE
;
case
AUDIO_OBJECT_TYPE_AAC_ELD:
return
C
.
ENCODING_AAC_ELD
;
default
:
return
C
.
ENCODING_INVALID
;
}
}
/**
* Parses an ALAC AudioSpecificConfig (i.e. an <a
* href="https://github.com/macosforge/alac/blob/master/ALACMagicCookieDescription.txt">ALACSpecificConfig</a>).
...
...
@@ -414,67 +168,5 @@ public final class CodecSpecificDataUtil {
return
true
;
}
/**
* Returns the AAC audio object type as specified in 14496-3 (2005) Table 1.14.
*
* @param bitArray The bit array containing the audio specific configuration.
* @return The audio object type.
*/
private
static
int
getAacAudioObjectType
(
ParsableBitArray
bitArray
)
{
int
audioObjectType
=
bitArray
.
readBits
(
5
);
if
(
audioObjectType
==
AUDIO_OBJECT_TYPE_ESCAPE
)
{
audioObjectType
=
32
+
bitArray
.
readBits
(
6
);
}
return
audioObjectType
;
}
/**
* Returns the AAC sampling frequency (or extension sampling frequency) as specified in 14496-3
* (2005) Table 1.13.
*
* @param bitArray The bit array containing the audio specific configuration.
* @return The sampling frequency.
*/
private
static
int
getAacSamplingFrequency
(
ParsableBitArray
bitArray
)
{
int
samplingFrequency
;
int
frequencyIndex
=
bitArray
.
readBits
(
4
);
if
(
frequencyIndex
==
AUDIO_SPECIFIC_CONFIG_FREQUENCY_INDEX_ARBITRARY
)
{
samplingFrequency
=
bitArray
.
readBits
(
24
);
}
else
{
Assertions
.
checkArgument
(
frequencyIndex
<
13
);
samplingFrequency
=
AUDIO_SPECIFIC_CONFIG_SAMPLING_RATE_TABLE
[
frequencyIndex
];
}
return
samplingFrequency
;
}
private
static
void
parseGaSpecificConfig
(
ParsableBitArray
bitArray
,
int
audioObjectType
,
int
channelConfiguration
)
{
boolean
frameLengthFlag
=
bitArray
.
readBit
();
if
(
frameLengthFlag
)
{
Log
.
w
(
TAG
,
"Unexpected AAC frameLengthFlag = 1"
);
}
boolean
dependsOnCoreDecoder
=
bitArray
.
readBit
();
if
(
dependsOnCoreDecoder
)
{
bitArray
.
skipBits
(
14
);
// coreCoderDelay.
}
boolean
extensionFlag
=
bitArray
.
readBit
();
if
(
channelConfiguration
==
0
)
{
throw
new
UnsupportedOperationException
();
// TODO: Implement programConfigElement();
}
if
(
audioObjectType
==
6
||
audioObjectType
==
20
)
{
bitArray
.
skipBits
(
3
);
// layerNr.
}
if
(
extensionFlag
)
{
if
(
audioObjectType
==
22
)
{
bitArray
.
skipBits
(
16
);
// numOfSubFrame (5), layer_length(11).
}
if
(
audioObjectType
==
17
||
audioObjectType
==
19
||
audioObjectType
==
20
||
audioObjectType
==
23
)
{
// aacSectionDataResilienceFlag, aacScalefactorDataResilienceFlag,
// aacSpectralDataResilienceFlag.
bitArray
.
skipBits
(
3
);
}
bitArray
.
skipBits
(
1
);
// extensionFlag3.
}
}
private
CodecSpecificDataUtil
()
{}
}
library/core/src/main/java/com/google/android/exoplayer2/audio/DefaultAudioSink.java
View file @
1ca9a061
...
...
@@ -28,7 +28,6 @@ import com.google.android.exoplayer2.Format;
import
com.google.android.exoplayer2.PlaybackParameters
;
import
com.google.android.exoplayer2.audio.AudioProcessor.UnhandledAudioFormatException
;
import
com.google.android.exoplayer2.util.Assertions
;
import
com.google.android.exoplayer2.util.CodecSpecificDataUtil
;
import
com.google.android.exoplayer2.util.Log
;
import
com.google.android.exoplayer2.util.Util
;
import
java.nio.ByteBuffer
;
...
...
@@ -1258,14 +1257,14 @@ public final class DefaultAudioSink implements AudioSink {
case
C
.
ENCODING_MP3
:
return
MpegAudioUtil
.
parseMpegAudioFrameSampleCount
(
buffer
.
get
(
buffer
.
position
()));
case
C
.
ENCODING_AAC_LC
:
return
CodecSpecificData
Util
.
AAC_LC_AUDIO_SAMPLE_COUNT
;
return
Aac
Util
.
AAC_LC_AUDIO_SAMPLE_COUNT
;
case
C
.
ENCODING_AAC_HE_V1
:
case
C
.
ENCODING_AAC_HE_V2
:
return
CodecSpecificData
Util
.
AAC_HE_AUDIO_SAMPLE_COUNT
;
return
Aac
Util
.
AAC_HE_AUDIO_SAMPLE_COUNT
;
case
C
.
ENCODING_AAC_XHE
:
return
CodecSpecificData
Util
.
AAC_XHE_AUDIO_SAMPLE_COUNT
;
return
Aac
Util
.
AAC_XHE_AUDIO_SAMPLE_COUNT
;
case
C
.
ENCODING_AAC_ELD
:
return
CodecSpecificData
Util
.
AAC_LD_AUDIO_SAMPLE_COUNT
;
return
Aac
Util
.
AAC_LD_AUDIO_SAMPLE_COUNT
;
case
C
.
ENCODING_DTS
:
case
C
.
ENCODING_DTS_HD
:
return
DtsUtil
.
parseDtsAudioSampleCount
(
buffer
);
...
...
library/extractor/src/main/java/com/google/android/exoplayer2/extractor/flv/AudioTagPayloadReader.java
View file @
1ca9a061
...
...
@@ -18,9 +18,8 @@ package com.google.android.exoplayer2.extractor.flv;
import
com.google.android.exoplayer2.C
;
import
com.google.android.exoplayer2.Format
;
import
com.google.android.exoplayer2.ParserException
;
import
com.google.android.exoplayer2.audio.AacUtil
;
import
com.google.android.exoplayer2.extractor.TrackOutput
;
import
com.google.android.exoplayer2.util.CodecSpecificDataUtil
;
import
com.google.android.exoplayer2.util.CodecSpecificDataUtil.AacConfig
;
import
com.google.android.exoplayer2.util.MimeTypes
;
import
com.google.android.exoplayer2.util.ParsableByteArray
;
import
java.util.Collections
;
...
...
@@ -109,8 +108,7 @@ import java.util.Collections;
// Parse the sequence header.
byte
[]
audioSpecificConfig
=
new
byte
[
data
.
bytesLeft
()];
data
.
readBytes
(
audioSpecificConfig
,
0
,
audioSpecificConfig
.
length
);
AacConfig
aacConfig
=
CodecSpecificDataUtil
.
parseAacAudioSpecificConfig
(
audioSpecificConfig
);
AacUtil
.
Config
aacConfig
=
AacUtil
.
parseAudioSpecificConfig
(
audioSpecificConfig
);
Format
format
=
new
Format
.
Builder
()
.
setSampleMimeType
(
MimeTypes
.
AUDIO_AAC
)
...
...
library/extractor/src/main/java/com/google/android/exoplayer2/extractor/mp4/AtomParsers.java
View file @
1ca9a061
...
...
@@ -22,6 +22,7 @@ import androidx.annotation.Nullable;
import
com.google.android.exoplayer2.C
;
import
com.google.android.exoplayer2.Format
;
import
com.google.android.exoplayer2.ParserException
;
import
com.google.android.exoplayer2.audio.AacUtil
;
import
com.google.android.exoplayer2.audio.Ac3Util
;
import
com.google.android.exoplayer2.audio.Ac4Util
;
import
com.google.android.exoplayer2.drm.DrmInitData
;
...
...
@@ -29,7 +30,6 @@ import com.google.android.exoplayer2.extractor.GaplessInfoHolder;
import
com.google.android.exoplayer2.metadata.Metadata
;
import
com.google.android.exoplayer2.util.Assertions
;
import
com.google.android.exoplayer2.util.CodecSpecificDataUtil
;
import
com.google.android.exoplayer2.util.CodecSpecificDataUtil.AacConfig
;
import
com.google.android.exoplayer2.util.Log
;
import
com.google.android.exoplayer2.util.MimeTypes
;
import
com.google.android.exoplayer2.util.ParsableByteArray
;
...
...
@@ -1184,8 +1184,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
if
(
MimeTypes
.
AUDIO_AAC
.
equals
(
mimeType
)
&&
initializationData
!=
null
)
{
// Update sampleRate and channelCount from the AudioSpecificConfig initialization data,
// which is more reliable. See [Internal: b/10903778].
AacConfig
aacConfig
=
CodecSpecificDataUtil
.
parseAacAudioSpecificConfig
(
initializationData
);
AacUtil
.
Config
aacConfig
=
AacUtil
.
parseAudioSpecificConfig
(
initializationData
);
sampleRate
=
aacConfig
.
sampleRateHz
;
channelCount
=
aacConfig
.
channelCount
;
codecs
=
aacConfig
.
codecs
;
...
...
library/extractor/src/main/java/com/google/android/exoplayer2/extractor/ts/AdtsReader.java
View file @
1ca9a061
...
...
@@ -19,13 +19,12 @@ import androidx.annotation.Nullable;
import
com.google.android.exoplayer2.C
;
import
com.google.android.exoplayer2.Format
;
import
com.google.android.exoplayer2.ParserException
;
import
com.google.android.exoplayer2.audio.AacUtil
;
import
com.google.android.exoplayer2.extractor.DummyTrackOutput
;
import
com.google.android.exoplayer2.extractor.ExtractorOutput
;
import
com.google.android.exoplayer2.extractor.TrackOutput
;
import
com.google.android.exoplayer2.extractor.ts.TsPayloadReader.TrackIdGenerator
;
import
com.google.android.exoplayer2.util.Assertions
;
import
com.google.android.exoplayer2.util.CodecSpecificDataUtil
;
import
com.google.android.exoplayer2.util.CodecSpecificDataUtil.AacConfig
;
import
com.google.android.exoplayer2.util.Log
;
import
com.google.android.exoplayer2.util.MimeTypes
;
import
com.google.android.exoplayer2.util.ParsableBitArray
;
...
...
@@ -467,9 +466,9 @@ public final class AdtsReader implements ElementaryStreamReader {
int
channelConfig
=
adtsScratch
.
readBits
(
3
);
byte
[]
audioSpecificConfig
=
CodecSpecificDataUtil
.
buildAac
AudioSpecificConfig
(
AacUtil
.
build
AudioSpecificConfig
(
audioObjectType
,
firstFrameSampleRateIndex
,
channelConfig
);
Aac
Config
aacConfig
=
CodecSpecificDataUtil
.
parseAac
AudioSpecificConfig
(
audioSpecificConfig
);
Aac
Util
.
Config
aacConfig
=
AacUtil
.
parse
AudioSpecificConfig
(
audioSpecificConfig
);
Format
format
=
new
Format
.
Builder
()
.
setId
(
formatId
)
...
...
library/extractor/src/main/java/com/google/android/exoplayer2/extractor/ts/LatmReader.java
View file @
1ca9a061
...
...
@@ -19,12 +19,11 @@ import androidx.annotation.Nullable;
import
com.google.android.exoplayer2.C
;
import
com.google.android.exoplayer2.Format
;
import
com.google.android.exoplayer2.ParserException
;
import
com.google.android.exoplayer2.audio.AacUtil
;
import
com.google.android.exoplayer2.extractor.ExtractorOutput
;
import
com.google.android.exoplayer2.extractor.TrackOutput
;
import
com.google.android.exoplayer2.extractor.ts.TsPayloadReader.TrackIdGenerator
;
import
com.google.android.exoplayer2.util.Assertions
;
import
com.google.android.exoplayer2.util.CodecSpecificDataUtil
;
import
com.google.android.exoplayer2.util.CodecSpecificDataUtil.AacConfig
;
import
com.google.android.exoplayer2.util.MimeTypes
;
import
com.google.android.exoplayer2.util.ParsableBitArray
;
import
com.google.android.exoplayer2.util.ParsableByteArray
;
...
...
@@ -273,8 +272,7 @@ public final class LatmReader implements ElementaryStreamReader {
private
int
parseAudioSpecificConfig
(
ParsableBitArray
data
)
throws
ParserException
{
int
bitsLeft
=
data
.
bitsLeft
();
AacConfig
config
=
CodecSpecificDataUtil
.
parseAacAudioSpecificConfig
(
data
,
/* forceReadToEnd= */
true
);
AacUtil
.
Config
config
=
AacUtil
.
parseAudioSpecificConfig
(
data
,
/* forceReadToEnd= */
true
);
sampleRateHz
=
config
.
sampleRateHz
;
channelCount
=
config
.
channelCount
;
return
bitsLeft
-
data
.
bitsLeft
();
...
...
library/smoothstreaming/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/manifest/SsManifestParser.java
View file @
1ca9a061
...
...
@@ -23,6 +23,7 @@ import androidx.annotation.Nullable;
import
com.google.android.exoplayer2.C
;
import
com.google.android.exoplayer2.Format
;
import
com.google.android.exoplayer2.ParserException
;
import
com.google.android.exoplayer2.audio.AacUtil
;
import
com.google.android.exoplayer2.drm.DrmInitData
;
import
com.google.android.exoplayer2.drm.DrmInitData.SchemeData
;
import
com.google.android.exoplayer2.extractor.mp4.PsshAtomUtil
;
...
...
@@ -687,7 +688,7 @@ public class SsManifestParser implements ParsingLoadable.Parser<SsManifest> {
if
(
codecSpecificData
.
isEmpty
()
&&
MimeTypes
.
AUDIO_AAC
.
equals
(
sampleMimeType
))
{
codecSpecificData
=
Collections
.
singletonList
(
CodecSpecificData
Util
.
buildAacLcAudioSpecificConfig
(
sampleRate
,
channelCount
));
Aac
Util
.
buildAacLcAudioSpecificConfig
(
sampleRate
,
channelCount
));
}
formatBuilder
.
setContainerMimeType
(
MimeTypes
.
AUDIO_MP4
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment