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
4e767faa
authored
Jan 09, 2020
by
olly
Committed by
Oliver Woodman
Jan 17, 2020
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Fix extension FLAC decoder to correctly handle non-16-bit depths
PiperOrigin-RevId: 288860159
parent
b35499f8
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
71 additions
and
26 deletions
RELEASENOTES.md
extensions/flac/src/main/java/com/google/android/exoplayer2/ext/flac/FlacDecoder.java
extensions/flac/src/main/java/com/google/android/exoplayer2/ext/flac/LibflacAudioRenderer.java
library/core/src/main/java/com/google/android/exoplayer2/audio/SimpleDecoderAudioRenderer.java
library/core/src/main/java/com/google/android/exoplayer2/util/FlacStreamMetadata.java
library/core/src/test/java/com/google/android/exoplayer2/audio/SimpleDecoderAudioRendererTest.java
RELEASENOTES.md
View file @
4e767faa
...
...
@@ -32,6 +32,10 @@
(
[
#4078
](
https://github.com/google/ExoPlayer/issues/4078
)
).
*
Don't use notification chronometer if playback speed is != 1.0
(
[
#6816
](
https://github.com/google/ExoPlayer/issues/6816
)
).
*
FLAC extension: Fix handling of bit depths other than 16 in
`FLACDecoder`
.
This issue caused FLAC streams with other bit depths to sound like white noise
on earlier releases, but only when embedded in a non-FLAC container such as
Matroska or MP4.
### 2.11.1 (2019-12-20) ###
...
...
@@ -198,7 +202,7 @@
`C.MSG_SET_OUTPUT_BUFFER_RENDERER`
.
*
Use
`VideoDecoderRenderer`
as an implementation of
`VideoDecoderOutputBufferRenderer`
, instead of
`VideoDecoderSurfaceView`
.
*
F
lac
extension: Update to use NDK r20.
*
F
LAC
extension: Update to use NDK r20.
*
Opus extension: Update to use NDK r20.
*
FFmpeg extension:
*
Update to use NDK r20.
...
...
@@ -335,7 +339,7 @@
(
[
#6241
](
https://github.com/google/ExoPlayer/issues/6241
)
).
*
MP3: Use CBR header bitrate, not calculated bitrate. This reverts a change
from 2.9.3 (
[
#6238
](
https://github.com/google/ExoPlayer/issues/6238
)
).
*
F
lac
extension: Parse
`VORBIS_COMMENT`
and
`PICTURE`
metadata
*
F
LAC
extension: Parse
`VORBIS_COMMENT`
and
`PICTURE`
metadata
(
[
#5527
](
https://github.com/google/ExoPlayer/issues/5527
)
).
*
Fix issue where initial seek positions get ignored when playing a preroll ad
(
[
#6201
](
https://github.com/google/ExoPlayer/issues/6201
)
).
...
...
@@ -344,7 +348,7 @@
(
[
#6153
](
https://github.com/google/ExoPlayer/issues/6153
)
).
*
Fix
`DataSchemeDataSource`
re-opening and range requests
(
[
#6192
](
https://github.com/google/ExoPlayer/issues/6192
)
).
*
Fix F
lac
and ALAC playback on some LG devices
*
Fix F
LAC
and ALAC playback on some LG devices
(
[
#5938
](
https://github.com/google/ExoPlayer/issues/5938
)
).
*
Fix issue when calling
`performClick`
on
`PlayerView`
without
`PlayerControlView`
...
...
extensions/flac/src/main/java/com/google/android/exoplayer2/ext/flac/FlacDecoder.java
View file @
4e767faa
...
...
@@ -33,7 +33,7 @@ import java.util.List;
/* package */
final
class
FlacDecoder
extends
SimpleDecoder
<
DecoderInputBuffer
,
SimpleOutputBuffer
,
FlacDecoderException
>
{
private
final
int
maxOutputBufferSize
;
private
final
FlacStreamMetadata
streamMetadata
;
private
final
FlacDecoderJni
decoderJni
;
/**
...
...
@@ -59,7 +59,6 @@ import java.util.List;
}
decoderJni
=
new
FlacDecoderJni
();
decoderJni
.
setData
(
ByteBuffer
.
wrap
(
initializationData
.
get
(
0
)));
FlacStreamMetadata
streamMetadata
;
try
{
streamMetadata
=
decoderJni
.
decodeStreamMetadata
();
}
catch
(
ParserException
e
)
{
...
...
@@ -72,7 +71,6 @@ import java.util.List;
int
initialInputBufferSize
=
maxInputBufferSize
!=
Format
.
NO_VALUE
?
maxInputBufferSize
:
streamMetadata
.
maxFrameSize
;
setInitialInputBufferSize
(
initialInputBufferSize
);
maxOutputBufferSize
=
streamMetadata
.
getMaxDecodedFrameSize
();
}
@Override
...
...
@@ -103,7 +101,8 @@ import java.util.List;
decoderJni
.
flush
();
}
decoderJni
.
setData
(
Util
.
castNonNull
(
inputBuffer
.
data
));
ByteBuffer
outputData
=
outputBuffer
.
init
(
inputBuffer
.
timeUs
,
maxOutputBufferSize
);
ByteBuffer
outputData
=
outputBuffer
.
init
(
inputBuffer
.
timeUs
,
streamMetadata
.
getMaxDecodedFrameSize
());
try
{
decoderJni
.
decodeSample
(
outputData
);
}
catch
(
FlacDecoderJni
.
FlacFrameDecodeException
e
)
{
...
...
@@ -121,4 +120,8 @@ import java.util.List;
decoderJni
.
release
();
}
/** Returns the {@link FlacStreamMetadata} decoded from the initialization data. */
public
FlacStreamMetadata
getStreamMetadata
()
{
return
streamMetadata
;
}
}
extensions/flac/src/main/java/com/google/android/exoplayer2/ext/flac/LibflacAudioRenderer.java
View file @
4e767faa
...
...
@@ -24,15 +24,20 @@ import com.google.android.exoplayer2.audio.AudioRendererEventListener;
import
com.google.android.exoplayer2.audio.SimpleDecoderAudioRenderer
;
import
com.google.android.exoplayer2.drm.DrmSessionManager
;
import
com.google.android.exoplayer2.drm.ExoMediaCrypto
;
import
com.google.android.exoplayer2.util.Assertions
;
import
com.google.android.exoplayer2.util.FlacConstants
;
import
com.google.android.exoplayer2.util.FlacStreamMetadata
;
import
com.google.android.exoplayer2.util.MimeTypes
;
import
com.google.android.exoplayer2.util.Util
;
import
org.checkerframework.checker.nullness.qual.MonotonicNonNull
;
/**
* Decodes and renders audio using the native Flac decoder.
*/
public
class
LibflacAudioRenderer
extends
SimpleDecoderAudioRenderer
{
/** Decodes and renders audio using the native Flac decoder. */
public
final
class
LibflacAudioRenderer
extends
SimpleDecoderAudioRenderer
{
private
static
final
int
NUM_BUFFERS
=
16
;
@MonotonicNonNull
private
FlacStreamMetadata
streamMetadata
;
public
LibflacAudioRenderer
()
{
this
(
/* eventHandler= */
null
,
/* eventListener= */
null
);
}
...
...
@@ -57,7 +62,23 @@ public class LibflacAudioRenderer extends SimpleDecoderAudioRenderer {
if
(!
FlacLibrary
.
isAvailable
()
||
!
MimeTypes
.
AUDIO_FLAC
.
equalsIgnoreCase
(
format
.
sampleMimeType
))
{
return
FORMAT_UNSUPPORTED_TYPE
;
}
else
if
(!
supportsOutput
(
format
.
channelCount
,
C
.
ENCODING_PCM_16BIT
))
{
}
// Compute the PCM encoding that the FLAC decoder will output.
@C
.
PcmEncoding
int
pcmEncoding
;
if
(
format
.
initializationData
.
isEmpty
())
{
// The initialization data might not be set if the format was obtained from a manifest (e.g.
// for DASH playbacks) rather than directly from the media. In this case we assume
// ENCODING_PCM_16BIT. If the actual encoding is different, playback will still succeed as
// long as the AudioSink supports it (which will always be true when using DefaultAudioSink).
pcmEncoding
=
C
.
ENCODING_PCM_16BIT
;
}
else
{
int
streamMetadataOffset
=
FlacConstants
.
STREAM_MARKER_SIZE
+
FlacConstants
.
METADATA_BLOCK_HEADER_SIZE
;
FlacStreamMetadata
streamMetadata
=
new
FlacStreamMetadata
(
format
.
initializationData
.
get
(
0
),
streamMetadataOffset
);
pcmEncoding
=
Util
.
getPcmEncoding
(
streamMetadata
.
bitsPerSample
);
}
if
(!
supportsOutput
(
format
.
channelCount
,
pcmEncoding
))
{
return
FORMAT_UNSUPPORTED_SUBTYPE
;
}
else
if
(!
supportsFormatDrm
(
drmSessionManager
,
format
.
drmInitData
))
{
return
FORMAT_UNSUPPORTED_DRM
;
...
...
@@ -69,8 +90,27 @@ public class LibflacAudioRenderer extends SimpleDecoderAudioRenderer {
@Override
protected
FlacDecoder
createDecoder
(
Format
format
,
@Nullable
ExoMediaCrypto
mediaCrypto
)
throws
FlacDecoderException
{
return
new
FlacDecoder
(
NUM_BUFFERS
,
NUM_BUFFERS
,
format
.
maxInputSize
,
format
.
initializationData
);
FlacDecoder
decoder
=
new
FlacDecoder
(
NUM_BUFFERS
,
NUM_BUFFERS
,
format
.
maxInputSize
,
format
.
initializationData
);
streamMetadata
=
decoder
.
getStreamMetadata
();
return
decoder
;
}
@Override
protected
Format
getOutputFormat
()
{
Assertions
.
checkNotNull
(
streamMetadata
);
return
Format
.
createAudioSampleFormat
(
/* id= */
null
,
MimeTypes
.
AUDIO_RAW
,
/* codecs= */
null
,
/* bitrate= */
Format
.
NO_VALUE
,
/* maxInputSize= */
Format
.
NO_VALUE
,
streamMetadata
.
channels
,
streamMetadata
.
sampleRate
,
Util
.
getPcmEncoding
(
streamMetadata
.
bitsPerSample
),
/* initializationData= */
null
,
/* drmInitData= */
null
,
/* selectionFlags= */
0
,
/* language= */
null
);
}
}
library/core/src/main/java/com/google/android/exoplayer2/audio/SimpleDecoderAudioRenderer.java
View file @
4e767faa
...
...
@@ -351,15 +351,8 @@ public abstract class SimpleDecoderAudioRenderer extends BaseRenderer implements
/**
* Returns the format of audio buffers output by the decoder. Will not be called until the first
* output buffer has been dequeued, so the decoder may use input data to determine the format.
* <p>
* The default implementation returns a 16-bit PCM format with the same channel count and sample
* rate as the input.
*/
protected
Format
getOutputFormat
()
{
return
Format
.
createAudioSampleFormat
(
null
,
MimeTypes
.
AUDIO_RAW
,
null
,
Format
.
NO_VALUE
,
Format
.
NO_VALUE
,
inputFormat
.
channelCount
,
inputFormat
.
sampleRate
,
C
.
ENCODING_PCM_16BIT
,
null
,
null
,
0
,
null
);
}
protected
abstract
Format
getOutputFormat
();
/**
* Returns whether the existing decoder can be kept for a new format.
...
...
library/core/src/main/java/com/google/android/exoplayer2/util/FlacStreamMetadata.java
View file @
4e767faa
...
...
@@ -102,8 +102,9 @@ public final class FlacStreamMetadata {
/**
* Parses binary FLAC stream info metadata.
*
* @param data An array containing binary FLAC stream info block (with or without header).
* @param offset The offset of the stream info block in {@code data} (header excluded).
* @param data An array containing binary FLAC stream info block.
* @param offset The offset of the stream info block in {@code data}, excluding the header (i.e.
* the offset points to the first byte of the minimum block size).
*/
public
FlacStreamMetadata
(
byte
[]
data
,
int
offset
)
{
ParsableBitArray
scratch
=
new
ParsableBitArray
(
data
);
...
...
library/core/src/test/java/com/google/android/exoplayer2/audio/SimpleDecoderAudioRendererTest.java
View file @
4e767faa
...
...
@@ -67,10 +67,14 @@ public class SimpleDecoderAudioRendererTest {
@Override
protected
SimpleDecoder
<
DecoderInputBuffer
,
?
extends
SimpleOutputBuffer
,
?
extends
AudioDecoderException
>
createDecoder
(
Format
format
,
@Nullable
ExoMediaCrypto
mediaCrypto
)
throws
AudioDecoderException
{
createDecoder
(
Format
format
,
@Nullable
ExoMediaCrypto
mediaCrypto
)
{
return
new
FakeDecoder
();
}
@Override
protected
Format
getOutputFormat
()
{
return
FORMAT
;
}
};
}
...
...
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