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
7fd0b1d8
authored
Jan 02, 2020
by
andrewlewis
Committed by
Oliver Woodman
Jan 17, 2020
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Fix handling of E-AC-3 streams with AC-3 frames
Issue: #6602 PiperOrigin-RevId: 287816831
parent
1edcc6c4
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
39 additions
and
39 deletions
RELEASENOTES.md
library/core/src/main/java/com/google/android/exoplayer2/audio/Ac3Util.java
library/core/src/main/java/com/google/android/exoplayer2/audio/DefaultAudioSink.java
RELEASENOTES.md
View file @
7fd0b1d8
...
...
@@ -12,6 +12,8 @@
(
[
#6733
](
https://github.com/google/ExoPlayer/issues/6733
)
). Incorrect handling
could previously cause downloads to be paused when they should have been able
to proceed.
*
Fix handling of E-AC-3 streams that contain AC-3 syncframes
(
[
#6602
](
https://github.com/google/ExoPlayer/issues/6602
)
).
### 2.11.1 (2019-12-20) ###
...
...
library/core/src/main/java/com/google/android/exoplayer2/audio/Ac3Util.java
View file @
7fd0b1d8
...
...
@@ -31,7 +31,7 @@ import java.nio.ByteBuffer;
/**
* Utility methods for parsing Dolby TrueHD and (E-)AC-3 syncframes. (E-)AC-3 parsing follows the
* definition in ETSI TS 102 366 V1.
2
.1.
* definition in ETSI TS 102 366 V1.
4
.1.
*/
public
final
class
Ac3Util
{
...
...
@@ -39,8 +39,8 @@ public final class Ac3Util {
public
static
final
class
SyncFrameInfo
{
/**
* AC3 stream types. See also E
TSI TS 102 366 E.1.3.1.1. One of {@link #STREAM_TYPE_UNDEFINED},
*
{@link
#STREAM_TYPE_TYPE0}, {@link #STREAM_TYPE_TYPE1} or {@link #STREAM_TYPE_TYPE2}.
* AC3 stream types. See also E
.1.3.1.1. One of {@link #STREAM_TYPE_UNDEFINED}, {@link
* #STREAM_TYPE_TYPE0}, {@link #STREAM_TYPE_TYPE1} or {@link #STREAM_TYPE_TYPE2}.
*/
@Documented
@Retention
(
RetentionPolicy
.
SOURCE
)
...
...
@@ -114,9 +114,7 @@ public final class Ac3Util {
* The number of new samples per (E-)AC-3 audio block.
*/
private
static
final
int
AUDIO_SAMPLES_PER_AUDIO_BLOCK
=
256
;
/**
* Each syncframe has 6 blocks that provide 256 new audio samples. See ETSI TS 102 366 4.1.
*/
/** Each syncframe has 6 blocks that provide 256 new audio samples. See subsection 4.1. */
private
static
final
int
AC3_SYNCFRAME_AUDIO_SAMPLE_COUNT
=
6
*
AUDIO_SAMPLES_PER_AUDIO_BLOCK
;
/**
* Number of audio blocks per E-AC-3 syncframe, indexed by numblkscod.
...
...
@@ -134,20 +132,21 @@ public final class Ac3Util {
* Channel counts, indexed by acmod.
*/
private
static
final
int
[]
CHANNEL_COUNT_BY_ACMOD
=
new
int
[]
{
2
,
1
,
2
,
3
,
3
,
4
,
4
,
5
};
/**
* Nominal bitrates in kbps, indexed by frmsizecod / 2. (See ETSI TS 102 366 table 4.13.)
*/
private
static
final
int
[]
BITRATE_BY_HALF_FRMSIZECOD
=
new
int
[]
{
32
,
40
,
48
,
56
,
64
,
80
,
96
,
112
,
128
,
160
,
192
,
224
,
256
,
320
,
384
,
448
,
512
,
576
,
640
};
/**
* 16-bit words per syncframe, indexed by frmsizecod / 2. (See ETSI TS 102 366 table 4.13.)
*/
private
static
final
int
[]
SYNCFRAME_SIZE_WORDS_BY_HALF_FRMSIZECOD_44_1
=
new
int
[]
{
69
,
87
,
104
,
121
,
139
,
174
,
208
,
243
,
278
,
348
,
417
,
487
,
557
,
696
,
835
,
975
,
1114
,
1253
,
1393
};
/** Nominal bitrates in kbps, indexed by frmsizecod / 2. (See table 4.13.) */
private
static
final
int
[]
BITRATE_BY_HALF_FRMSIZECOD
=
new
int
[]
{
32
,
40
,
48
,
56
,
64
,
80
,
96
,
112
,
128
,
160
,
192
,
224
,
256
,
320
,
384
,
448
,
512
,
576
,
640
};
/** 16-bit words per syncframe, indexed by frmsizecod / 2. (See table 4.13.) */
private
static
final
int
[]
SYNCFRAME_SIZE_WORDS_BY_HALF_FRMSIZECOD_44_1
=
new
int
[]
{
69
,
87
,
104
,
121
,
139
,
174
,
208
,
243
,
278
,
348
,
417
,
487
,
557
,
696
,
835
,
975
,
1114
,
1253
,
1393
};
/**
* Returns the AC-3 format given {@code data} containing the AC3SpecificBox according to
ETSI TS
*
102 366 Annex F.
The reading position of {@code data} will be modified.
* Returns the AC-3 format given {@code data} containing the AC3SpecificBox according to
Annex F.
* The reading position of {@code data} will be modified.
*
* @param data The AC3SpecificBox to parse.
* @param trackId The track identifier to set on the format.
...
...
@@ -179,8 +178,8 @@ public final class Ac3Util {
}
/**
* Returns the E-AC-3 format given {@code data} containing the EC3SpecificBox according to
ETSI TS
*
102 366 Annex
F. The reading position of {@code data} will be modified.
* Returns the E-AC-3 format given {@code data} containing the EC3SpecificBox according to
Annex
* F. The reading position of {@code data} will be modified.
*
* @param data The EC3SpecificBox to parse.
* @param trackId The track identifier to set on the format.
...
...
@@ -243,9 +242,10 @@ public final class Ac3Util {
public
static
SyncFrameInfo
parseAc3SyncframeInfo
(
ParsableBitArray
data
)
{
int
initialPosition
=
data
.
getPosition
();
data
.
skipBits
(
40
);
boolean
isEac3
=
data
.
readBits
(
5
)
==
16
;
// See bsid in subsection E.1.3.1.6.
// Parse the bitstream ID for AC-3 and E-AC-3 (see subsections 4.3, E.1.2 and E.1.3.1.6).
boolean
isEac3
=
data
.
readBits
(
5
)
>
10
;
data
.
setPosition
(
initialPosition
);
String
mimeType
;
@Nullable
String
mimeType
;
@StreamType
int
streamType
=
SyncFrameInfo
.
STREAM_TYPE_UNDEFINED
;
int
sampleRate
;
int
acmod
;
...
...
@@ -254,7 +254,7 @@ public final class Ac3Util {
boolean
lfeon
;
int
channelCount
;
if
(
isEac3
)
{
// S
yntax from ETSI TS 102 366 V1.2.1 subsections E.1.2.1 and E.1.2
.2.
// S
ubsection E.1
.2.
data
.
skipBits
(
16
);
// syncword
switch
(
data
.
readBits
(
2
))
{
// strmtyp
case
0
:
...
...
@@ -472,7 +472,8 @@ public final class Ac3Util {
if
(
data
.
length
<
6
)
{
return
C
.
LENGTH_UNSET
;
}
boolean
isEac3
=
((
data
[
5
]
&
0xFF
)
>>
3
)
==
16
;
// See bsid in subsection E.1.3.1.6.
// Parse the bitstream ID for AC-3 and E-AC-3 (see subsections 4.3, E.1.2 and E.1.3.1.6).
boolean
isEac3
=
((
data
[
5
]
&
0xF8
)
>>
3
)
>
10
;
if
(
isEac3
)
{
int
frmsiz
=
(
data
[
2
]
&
0x07
)
<<
8
;
// Most significant 3 bits.
frmsiz
|=
data
[
3
]
&
0xFF
;
// Least significant 8 bits.
...
...
@@ -485,24 +486,22 @@ public final class Ac3Util {
}
/**
* Returns the number of audio samples in an AC-3 syncframe.
*/
public
static
int
getAc3SyncframeAudioSampleCount
()
{
return
AC3_SYNCFRAME_AUDIO_SAMPLE_COUNT
;
}
/**
* Reads the number of audio samples represented by the given E-AC-3 syncframe. The buffer's
* Reads the number of audio samples represented by the given (E-)AC-3 syncframe. The buffer's
* position is not modified.
*
* @param buffer The {@link ByteBuffer} from which to read the syncframe.
* @return The number of audio samples represented by the syncframe.
*/
public
static
int
parseEAc3SyncframeAudioSampleCount
(
ByteBuffer
buffer
)
{
// See ETSI TS 102 366 subsection E.1.2.2.
int
fscod
=
(
buffer
.
get
(
buffer
.
position
()
+
4
)
&
0xC0
)
>>
6
;
return
AUDIO_SAMPLES_PER_AUDIO_BLOCK
*
(
fscod
==
0x03
?
6
:
BLOCKS_PER_SYNCFRAME_BY_NUMBLKSCOD
[(
buffer
.
get
(
buffer
.
position
()
+
4
)
&
0x30
)
>>
4
]);
public
static
int
parseAc3SyncframeAudioSampleCount
(
ByteBuffer
buffer
)
{
// Parse the bitstream ID for AC-3 and E-AC-3 (see subsections 4.3, E.1.2 and E.1.3.1.6).
boolean
isEac3
=
((
buffer
.
get
(
buffer
.
position
()
+
5
)
&
0xF8
)
>>
3
)
>
10
;
if
(
isEac3
)
{
int
fscod
=
(
buffer
.
get
(
buffer
.
position
()
+
4
)
&
0xC0
)
>>
6
;
int
numblkscod
=
fscod
==
0x03
?
3
:
(
buffer
.
get
(
buffer
.
position
()
+
4
)
&
0x30
)
>>
4
;
return
BLOCKS_PER_SYNCFRAME_BY_NUMBLKSCOD
[
numblkscod
]
*
AUDIO_SAMPLES_PER_AUDIO_BLOCK
;
}
else
{
return
AC3_SYNCFRAME_AUDIO_SAMPLE_COUNT
;
}
}
/**
...
...
library/core/src/main/java/com/google/android/exoplayer2/audio/DefaultAudioSink.java
View file @
7fd0b1d8
...
...
@@ -1166,10 +1166,9 @@ public final class DefaultAudioSink implements AudioSink {
case
C
.
ENCODING_DTS_HD
:
return
DtsUtil
.
parseDtsAudioSampleCount
(
buffer
);
case
C
.
ENCODING_AC3
:
return
Ac3Util
.
getAc3SyncframeAudioSampleCount
();
case
C
.
ENCODING_E_AC3
:
case
C
.
ENCODING_E_AC3_JOC
:
return
Ac3Util
.
parse
E
Ac3SyncframeAudioSampleCount
(
buffer
);
return
Ac3Util
.
parseAc3SyncframeAudioSampleCount
(
buffer
);
case
C
.
ENCODING_AC4
:
return
Ac4Util
.
parseAc4SyncframeAudioSampleCount
(
buffer
);
case
C
.
ENCODING_DOLBY_TRUEHD
:
...
...
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