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 @@
...
@@ -12,6 +12,8 @@
(
[
#6733
](
https://github.com/google/ExoPlayer/issues/6733
)
). Incorrect handling
(
[
#6733
](
https://github.com/google/ExoPlayer/issues/6733
)
). Incorrect handling
could previously cause downloads to be paused when they should have been able
could previously cause downloads to be paused when they should have been able
to proceed.
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) ###
### 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;
...
@@ -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
* 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
{
public
final
class
Ac3Util
{
...
@@ -39,8 +39,8 @@ public final class Ac3Util {
...
@@ -39,8 +39,8 @@ public final class Ac3Util {
public
static
final
class
SyncFrameInfo
{
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},
* AC3 stream types. See also E
.1.3.1.1. One of {@link #STREAM_TYPE_UNDEFINED}, {@link
*
{@link
#STREAM_TYPE_TYPE0}, {@link #STREAM_TYPE_TYPE1} or {@link #STREAM_TYPE_TYPE2}.
* #STREAM_TYPE_TYPE0}, {@link #STREAM_TYPE_TYPE1} or {@link #STREAM_TYPE_TYPE2}.
*/
*/
@Documented
@Documented
@Retention
(
RetentionPolicy
.
SOURCE
)
@Retention
(
RetentionPolicy
.
SOURCE
)
...
@@ -114,9 +114,7 @@ public final class Ac3Util {
...
@@ -114,9 +114,7 @@ public final class Ac3Util {
* The number of new samples per (E-)AC-3 audio block.
* The number of new samples per (E-)AC-3 audio block.
*/
*/
private
static
final
int
AUDIO_SAMPLES_PER_AUDIO_BLOCK
=
256
;
private
static
final
int
AUDIO_SAMPLES_PER_AUDIO_BLOCK
=
256
;
/**
/** Each syncframe has 6 blocks that provide 256 new audio samples. See subsection 4.1. */
* Each syncframe has 6 blocks that provide 256 new audio samples. See ETSI TS 102 366 4.1.
*/
private
static
final
int
AC3_SYNCFRAME_AUDIO_SAMPLE_COUNT
=
6
*
AUDIO_SAMPLES_PER_AUDIO_BLOCK
;
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.
* Number of audio blocks per E-AC-3 syncframe, indexed by numblkscod.
...
@@ -134,20 +132,21 @@ public final class Ac3Util {
...
@@ -134,20 +132,21 @@ public final class Ac3Util {
* Channel counts, indexed by acmod.
* Channel counts, indexed by acmod.
*/
*/
private
static
final
int
[]
CHANNEL_COUNT_BY_ACMOD
=
new
int
[]
{
2
,
1
,
2
,
3
,
3
,
4
,
4
,
5
};
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 table 4.13.) */
* 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
[]
{
private
static
final
int
[]
BITRATE_BY_HALF_FRMSIZECOD
=
new
int
[]
{
32
,
40
,
48
,
56
,
64
,
80
,
96
,
32
,
40
,
48
,
56
,
64
,
80
,
96
,
112
,
128
,
160
,
192
,
224
,
256
,
320
,
384
,
448
,
512
,
576
,
640
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.) */
* 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
[]
{
private
static
final
int
[]
SYNCFRAME_SIZE_WORDS_BY_HALF_FRMSIZECOD_44_1
=
new
int
[]
{
69
,
87
,
104
,
69
,
87
,
104
,
121
,
139
,
174
,
208
,
243
,
278
,
348
,
417
,
487
,
557
,
696
,
835
,
975
,
1114
,
1253
,
121
,
139
,
174
,
208
,
243
,
278
,
348
,
417
,
487
,
557
,
696
,
835
,
975
,
1114
,
1253
,
1393
};
1393
};
/**
/**
* Returns the AC-3 format given {@code data} containing the AC3SpecificBox according to
ETSI TS
* Returns the AC-3 format given {@code data} containing the AC3SpecificBox according to
Annex F.
*
102 366 Annex F.
The reading position of {@code data} will be modified.
* The reading position of {@code data} will be modified.
*
*
* @param data The AC3SpecificBox to parse.
* @param data The AC3SpecificBox to parse.
* @param trackId The track identifier to set on the format.
* @param trackId The track identifier to set on the format.
...
@@ -179,8 +178,8 @@ public final class Ac3Util {
...
@@ -179,8 +178,8 @@ public final class Ac3Util {
}
}
/**
/**
* Returns the E-AC-3 format given {@code data} containing the EC3SpecificBox according to
ETSI TS
* Returns the E-AC-3 format given {@code data} containing the EC3SpecificBox according to
Annex
*
102 366 Annex
F. The reading position of {@code data} will be modified.
* F. The reading position of {@code data} will be modified.
*
*
* @param data The EC3SpecificBox to parse.
* @param data The EC3SpecificBox to parse.
* @param trackId The track identifier to set on the format.
* @param trackId The track identifier to set on the format.
...
@@ -243,9 +242,10 @@ public final class Ac3Util {
...
@@ -243,9 +242,10 @@ public final class Ac3Util {
public
static
SyncFrameInfo
parseAc3SyncframeInfo
(
ParsableBitArray
data
)
{
public
static
SyncFrameInfo
parseAc3SyncframeInfo
(
ParsableBitArray
data
)
{
int
initialPosition
=
data
.
getPosition
();
int
initialPosition
=
data
.
getPosition
();
data
.
skipBits
(
40
);
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
);
data
.
setPosition
(
initialPosition
);
String
mimeType
;
@Nullable
String
mimeType
;
@StreamType
int
streamType
=
SyncFrameInfo
.
STREAM_TYPE_UNDEFINED
;
@StreamType
int
streamType
=
SyncFrameInfo
.
STREAM_TYPE_UNDEFINED
;
int
sampleRate
;
int
sampleRate
;
int
acmod
;
int
acmod
;
...
@@ -254,7 +254,7 @@ public final class Ac3Util {
...
@@ -254,7 +254,7 @@ public final class Ac3Util {
boolean
lfeon
;
boolean
lfeon
;
int
channelCount
;
int
channelCount
;
if
(
isEac3
)
{
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
data
.
skipBits
(
16
);
// syncword
switch
(
data
.
readBits
(
2
))
{
// strmtyp
switch
(
data
.
readBits
(
2
))
{
// strmtyp
case
0
:
case
0
:
...
@@ -472,7 +472,8 @@ public final class Ac3Util {
...
@@ -472,7 +472,8 @@ public final class Ac3Util {
if
(
data
.
length
<
6
)
{
if
(
data
.
length
<
6
)
{
return
C
.
LENGTH_UNSET
;
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
)
{
if
(
isEac3
)
{
int
frmsiz
=
(
data
[
2
]
&
0x07
)
<<
8
;
// Most significant 3 bits.
int
frmsiz
=
(
data
[
2
]
&
0x07
)
<<
8
;
// Most significant 3 bits.
frmsiz
|=
data
[
3
]
&
0xFF
;
// Least significant 8 bits.
frmsiz
|=
data
[
3
]
&
0xFF
;
// Least significant 8 bits.
...
@@ -485,24 +486,22 @@ public final class Ac3Util {
...
@@ -485,24 +486,22 @@ public final class Ac3Util {
}
}
/**
/**
* Returns the number of audio samples in an AC-3 syncframe.
* Reads the number of audio samples represented by the given (E-)AC-3 syncframe. The buffer's
*/
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
* position is not modified.
* position is not modified.
*
*
* @param buffer The {@link ByteBuffer} from which to read the syncframe.
* @param buffer The {@link ByteBuffer} from which to read the syncframe.
* @return The number of audio samples represented by the syncframe.
* @return The number of audio samples represented by the syncframe.
*/
*/
public
static
int
parseEAc3SyncframeAudioSampleCount
(
ByteBuffer
buffer
)
{
public
static
int
parseAc3SyncframeAudioSampleCount
(
ByteBuffer
buffer
)
{
// See ETSI TS 102 366 subsection E.1.2.2.
// Parse the bitstream ID for AC-3 and E-AC-3 (see subsections 4.3, E.1.2 and E.1.3.1.6).
int
fscod
=
(
buffer
.
get
(
buffer
.
position
()
+
4
)
&
0xC0
)
>>
6
;
boolean
isEac3
=
((
buffer
.
get
(
buffer
.
position
()
+
5
)
&
0xF8
)
>>
3
)
>
10
;
return
AUDIO_SAMPLES_PER_AUDIO_BLOCK
*
(
fscod
==
0x03
?
6
if
(
isEac3
)
{
:
BLOCKS_PER_SYNCFRAME_BY_NUMBLKSCOD
[(
buffer
.
get
(
buffer
.
position
()
+
4
)
&
0x30
)
>>
4
]);
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 {
...
@@ -1166,10 +1166,9 @@ public final class DefaultAudioSink implements AudioSink {
case
C
.
ENCODING_DTS_HD
:
case
C
.
ENCODING_DTS_HD
:
return
DtsUtil
.
parseDtsAudioSampleCount
(
buffer
);
return
DtsUtil
.
parseDtsAudioSampleCount
(
buffer
);
case
C
.
ENCODING_AC3
:
case
C
.
ENCODING_AC3
:
return
Ac3Util
.
getAc3SyncframeAudioSampleCount
();
case
C
.
ENCODING_E_AC3
:
case
C
.
ENCODING_E_AC3
:
case
C
.
ENCODING_E_AC3_JOC
:
case
C
.
ENCODING_E_AC3_JOC
:
return
Ac3Util
.
parse
E
Ac3SyncframeAudioSampleCount
(
buffer
);
return
Ac3Util
.
parseAc3SyncframeAudioSampleCount
(
buffer
);
case
C
.
ENCODING_AC4
:
case
C
.
ENCODING_AC4
:
return
Ac4Util
.
parseAc4SyncframeAudioSampleCount
(
buffer
);
return
Ac4Util
.
parseAc4SyncframeAudioSampleCount
(
buffer
);
case
C
.
ENCODING_DOLBY_TRUEHD
:
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