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
19144c4c
authored
Jan 28, 2019
by
olly
Committed by
Oliver Woodman
Jan 29, 2019
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Allow to disable libyuv dependency on LIBVPX
Goal: reduce binary size. PiperOrigin-RevId: 231198579
parent
866835ea
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
47 additions
and
155 deletions
RELEASENOTES.md
extensions/vp9/README.md
extensions/vp9/src/androidTest/java/com/google/android/exoplayer2/ext/vp9/VpxPlaybackTest.java
extensions/vp9/src/main/java/com/google/android/exoplayer2/ext/vp9/LibvpxVideoRenderer.java
extensions/vp9/src/main/java/com/google/android/exoplayer2/ext/vp9/VpxDecoder.java
extensions/vp9/src/main/java/com/google/android/exoplayer2/ext/vp9/VpxOutputBuffer.java
extensions/vp9/src/main/jni/Android.mk
extensions/vp9/src/main/jni/vpx_jni.cc
library/core/proguard-rules.txt
library/core/src/main/java/com/google/android/exoplayer2/DefaultRenderersFactory.java
RELEASENOTES.md
View file @
19144c4c
...
@@ -41,6 +41,9 @@
...
@@ -41,6 +41,9 @@
*
Add
`Handler`
parameter to
`ConcatenatingMediaSource`
methods which take a
*
Add
`Handler`
parameter to
`ConcatenatingMediaSource`
methods which take a
callback
`Runnable`
.
callback
`Runnable`
.
*
Remove
`player`
and
`isTopLevelSource`
parameters from
`MediaSource.prepare`
.
*
Remove
`player`
and
`isTopLevelSource`
parameters from
`MediaSource.prepare`
.
*
VP9 extension: Remove RGB output mode and libyuv dependency, and switch to
surface YUV output as the default. Remove constructor parameters
`scaleToFit`
and
`useSurfaceYuvOutput`
.
*
Change signature of
`PlayerNotificationManager.NotificationListener`
to better
*
Change signature of
`PlayerNotificationManager.NotificationListener`
to better
fit service requirements. Remove ability to set a custom stop action.
fit service requirements. Remove ability to set a custom stop action.
...
...
extensions/vp9/README.md
View file @
19144c4c
...
@@ -34,26 +34,6 @@ VP9_EXT_PATH="${EXOPLAYER_ROOT}/extensions/vp9/src/main"
...
@@ -34,26 +34,6 @@ VP9_EXT_PATH="${EXOPLAYER_ROOT}/extensions/vp9/src/main"
NDK_PATH="<path to Android NDK>"
NDK_PATH="<path to Android NDK>"
```
```
*
Fetch libvpx and libyuv:
```
cd "${VP9_EXT_PATH}/jni" && \
git clone https://chromium.googlesource.com/webm/libvpx libvpx && \
git clone https://chromium.googlesource.com/libyuv/libyuv libyuv
```
*
Checkout the appropriate branches of libvpx and libyuv (the scripts and
makefiles bundled in this repo are known to work only at these versions of the
libraries - we will update this periodically as newer versions of
libvpx/libyuv are released):
```
cd "${VP9_EXT_PATH}/jni/libvpx" && \
git checkout tags/v1.7.0 -b v1.7.0 && \
cd "${VP9_EXT_PATH}/jni/libyuv" && \
git checkout 996a2bbd
```
*
Run a script that generates necessary configuration files for libvpx:
*
Run a script that generates necessary configuration files for libvpx:
```
```
...
@@ -78,10 +58,6 @@ ${NDK_PATH}/ndk-build APP_ABI=all -j4
...
@@ -78,10 +58,6 @@ ${NDK_PATH}/ndk-build APP_ABI=all -j4
*
Android config scripts should be re-generated by running
*
Android config scripts should be re-generated by running
`generate_libvpx_android_configs.sh`
`generate_libvpx_android_configs.sh`
*
Clean and re-build the project.
*
Clean and re-build the project.
*
If you want to use your own version of libvpx or libyuv, place it in
`${VP9_EXT_PATH}/jni/libvpx`
or
`${VP9_EXT_PATH}/jni/libyuv`
respectively. But
please note that
`generate_libvpx_android_configs.sh`
and the makefiles need
to be modified to work with arbitrary versions of libvpx and libyuv.
## Using the extension ##
## Using the extension ##
...
...
extensions/vp9/src/androidTest/java/com/google/android/exoplayer2/ext/vp9/VpxPlaybackTest.java
View file @
19144c4c
...
@@ -114,7 +114,7 @@ public class VpxPlaybackTest {
...
@@ -114,7 +114,7 @@ public class VpxPlaybackTest {
@Override
@Override
public
void
run
()
{
public
void
run
()
{
Looper
.
prepare
();
Looper
.
prepare
();
LibvpxVideoRenderer
videoRenderer
=
new
LibvpxVideoRenderer
(
true
,
0
);
LibvpxVideoRenderer
videoRenderer
=
new
LibvpxVideoRenderer
(
0
);
DefaultTrackSelector
trackSelector
=
new
DefaultTrackSelector
();
DefaultTrackSelector
trackSelector
=
new
DefaultTrackSelector
();
player
=
ExoPlayerFactory
.
newInstance
(
context
,
new
Renderer
[]
{
videoRenderer
},
trackSelector
);
player
=
ExoPlayerFactory
.
newInstance
(
context
,
new
Renderer
[]
{
videoRenderer
},
trackSelector
);
player
.
addListener
(
this
);
player
.
addListener
(
this
);
...
...
extensions/vp9/src/main/java/com/google/android/exoplayer2/ext/vp9/LibvpxVideoRenderer.java
View file @
19144c4c
...
@@ -15,8 +15,6 @@
...
@@ -15,8 +15,6 @@
*/
*/
package
com
.
google
.
android
.
exoplayer2
.
ext
.
vp9
;
package
com
.
google
.
android
.
exoplayer2
.
ext
.
vp9
;
import
android.graphics.Bitmap
;
import
android.graphics.Canvas
;
import
android.os.Handler
;
import
android.os.Handler
;
import
android.os.Looper
;
import
android.os.Looper
;
import
android.os.SystemClock
;
import
android.os.SystemClock
;
...
@@ -109,7 +107,6 @@ public class LibvpxVideoRenderer extends BaseRenderer {
...
@@ -109,7 +107,6 @@ public class LibvpxVideoRenderer extends BaseRenderer {
/** The default input buffer size. */
/** The default input buffer size. */
private
static
final
int
DEFAULT_INPUT_BUFFER_SIZE
=
768
*
1024
;
// Value based on cs/SoftVpx.cpp.
private
static
final
int
DEFAULT_INPUT_BUFFER_SIZE
=
768
*
1024
;
// Value based on cs/SoftVpx.cpp.
private
final
boolean
scaleToFit
;
private
final
boolean
disableLoopFilter
;
private
final
boolean
disableLoopFilter
;
private
final
long
allowedJoiningTimeMs
;
private
final
long
allowedJoiningTimeMs
;
private
final
int
maxDroppedFramesToNotify
;
private
final
int
maxDroppedFramesToNotify
;
...
@@ -119,7 +116,6 @@ public class LibvpxVideoRenderer extends BaseRenderer {
...
@@ -119,7 +116,6 @@ public class LibvpxVideoRenderer extends BaseRenderer {
private
final
TimedValueQueue
<
Format
>
formatQueue
;
private
final
TimedValueQueue
<
Format
>
formatQueue
;
private
final
DecoderInputBuffer
flagsOnlyBuffer
;
private
final
DecoderInputBuffer
flagsOnlyBuffer
;
private
final
DrmSessionManager
<
ExoMediaCrypto
>
drmSessionManager
;
private
final
DrmSessionManager
<
ExoMediaCrypto
>
drmSessionManager
;
private
final
boolean
useSurfaceYuvOutput
;
private
Format
format
;
private
Format
format
;
private
Format
pendingFormat
;
private
Format
pendingFormat
;
...
@@ -133,7 +129,6 @@ public class LibvpxVideoRenderer extends BaseRenderer {
...
@@ -133,7 +129,6 @@ public class LibvpxVideoRenderer extends BaseRenderer {
private
@ReinitializationState
int
decoderReinitializationState
;
private
@ReinitializationState
int
decoderReinitializationState
;
private
boolean
decoderReceivedBuffers
;
private
boolean
decoderReceivedBuffers
;
private
Bitmap
bitmap
;
private
boolean
renderedFirstFrame
;
private
boolean
renderedFirstFrame
;
private
long
initialPositionUs
;
private
long
initialPositionUs
;
private
long
joiningDeadlineMs
;
private
long
joiningDeadlineMs
;
...
@@ -158,16 +153,14 @@ public class LibvpxVideoRenderer extends BaseRenderer {
...
@@ -158,16 +153,14 @@ public class LibvpxVideoRenderer extends BaseRenderer {
protected
DecoderCounters
decoderCounters
;
protected
DecoderCounters
decoderCounters
;
/**
/**
* @param scaleToFit Whether video frames should be scaled to fit when rendering.
* @param allowedJoiningTimeMs The maximum duration in milliseconds for which this video renderer
* @param allowedJoiningTimeMs The maximum duration in milliseconds for which this video renderer
* can attempt to seamlessly join an ongoing playback.
* can attempt to seamlessly join an ongoing playback.
*/
*/
public
LibvpxVideoRenderer
(
boolean
scaleToFit
,
long
allowedJoiningTimeMs
)
{
public
LibvpxVideoRenderer
(
long
allowedJoiningTimeMs
)
{
this
(
scaleToFit
,
allowedJoiningTimeMs
,
null
,
null
,
0
);
this
(
allowedJoiningTimeMs
,
null
,
null
,
0
);
}
}
/**
/**
* @param scaleToFit Whether video frames should be scaled to fit when rendering.
* @param allowedJoiningTimeMs The maximum duration in milliseconds for which this video renderer
* @param allowedJoiningTimeMs The maximum duration in milliseconds for which this video renderer
* can attempt to seamlessly join an ongoing playback.
* can attempt to seamlessly join an ongoing playback.
* @param eventHandler A handler to use when delivering events to {@code eventListener}. May be
* @param eventHandler A handler to use when delivering events to {@code eventListener}. May be
...
@@ -176,23 +169,22 @@ public class LibvpxVideoRenderer extends BaseRenderer {
...
@@ -176,23 +169,22 @@ public class LibvpxVideoRenderer extends BaseRenderer {
* @param maxDroppedFramesToNotify The maximum number of frames that can be dropped between
* @param maxDroppedFramesToNotify The maximum number of frames that can be dropped between
* invocations of {@link VideoRendererEventListener#onDroppedFrames(int, long)}.
* invocations of {@link VideoRendererEventListener#onDroppedFrames(int, long)}.
*/
*/
public
LibvpxVideoRenderer
(
boolean
scaleToFit
,
long
allowedJoiningTimeMs
,
public
LibvpxVideoRenderer
(
Handler
eventHandler
,
VideoRendererEventListener
eventListener
,
long
allowedJoiningTimeMs
,
Handler
eventHandler
,
VideoRendererEventListener
eventListener
,
int
maxDroppedFramesToNotify
)
{
int
maxDroppedFramesToNotify
)
{
this
(
this
(
scaleToFit
,
allowedJoiningTimeMs
,
allowedJoiningTimeMs
,
eventHandler
,
eventHandler
,
eventListener
,
eventListener
,
maxDroppedFramesToNotify
,
maxDroppedFramesToNotify
,
/* drmSessionManager= */
null
,
/* drmSessionManager= */
null
,
/* playClearSamplesWithoutKeys= */
false
,
/* playClearSamplesWithoutKeys= */
false
,
/* disableLoopFilter= */
false
,
/* disableLoopFilter= */
false
);
/* useSurfaceYuvOutput= */
false
);
}
}
/**
/**
* @param scaleToFit Whether video frames should be scaled to fit when rendering.
* @param allowedJoiningTimeMs The maximum duration in milliseconds for which this video renderer
* @param allowedJoiningTimeMs The maximum duration in milliseconds for which this video renderer
* can attempt to seamlessly join an ongoing playback.
* can attempt to seamlessly join an ongoing playback.
* @param eventHandler A handler to use when delivering events to {@code eventListener}. May be
* @param eventHandler A handler to use when delivering events to {@code eventListener}. May be
...
@@ -208,26 +200,21 @@ public class LibvpxVideoRenderer extends BaseRenderer {
...
@@ -208,26 +200,21 @@ public class LibvpxVideoRenderer extends BaseRenderer {
* permitted to play clear regions of encrypted media files before {@code drmSessionManager}
* permitted to play clear regions of encrypted media files before {@code drmSessionManager}
* has obtained the keys necessary to decrypt encrypted regions of the media.
* has obtained the keys necessary to decrypt encrypted regions of the media.
* @param disableLoopFilter Disable the libvpx in-loop smoothing filter.
* @param disableLoopFilter Disable the libvpx in-loop smoothing filter.
* @param useSurfaceYuvOutput Directly output YUV to the Surface via ANativeWindow.
*/
*/
public
LibvpxVideoRenderer
(
public
LibvpxVideoRenderer
(
boolean
scaleToFit
,
long
allowedJoiningTimeMs
,
long
allowedJoiningTimeMs
,
Handler
eventHandler
,
Handler
eventHandler
,
VideoRendererEventListener
eventListener
,
VideoRendererEventListener
eventListener
,
int
maxDroppedFramesToNotify
,
int
maxDroppedFramesToNotify
,
DrmSessionManager
<
ExoMediaCrypto
>
drmSessionManager
,
DrmSessionManager
<
ExoMediaCrypto
>
drmSessionManager
,
boolean
playClearSamplesWithoutKeys
,
boolean
playClearSamplesWithoutKeys
,
boolean
disableLoopFilter
,
boolean
disableLoopFilter
)
{
boolean
useSurfaceYuvOutput
)
{
super
(
C
.
TRACK_TYPE_VIDEO
);
super
(
C
.
TRACK_TYPE_VIDEO
);
this
.
scaleToFit
=
scaleToFit
;
this
.
disableLoopFilter
=
disableLoopFilter
;
this
.
disableLoopFilter
=
disableLoopFilter
;
this
.
allowedJoiningTimeMs
=
allowedJoiningTimeMs
;
this
.
allowedJoiningTimeMs
=
allowedJoiningTimeMs
;
this
.
maxDroppedFramesToNotify
=
maxDroppedFramesToNotify
;
this
.
maxDroppedFramesToNotify
=
maxDroppedFramesToNotify
;
this
.
drmSessionManager
=
drmSessionManager
;
this
.
drmSessionManager
=
drmSessionManager
;
this
.
playClearSamplesWithoutKeys
=
playClearSamplesWithoutKeys
;
this
.
playClearSamplesWithoutKeys
=
playClearSamplesWithoutKeys
;
this
.
useSurfaceYuvOutput
=
useSurfaceYuvOutput
;
joiningDeadlineMs
=
C
.
TIME_UNSET
;
joiningDeadlineMs
=
C
.
TIME_UNSET
;
clearReportedVideoSize
();
clearReportedVideoSize
();
formatHolder
=
new
FormatHolder
();
formatHolder
=
new
FormatHolder
();
...
@@ -586,18 +573,14 @@ public class LibvpxVideoRenderer extends BaseRenderer {
...
@@ -586,18 +573,14 @@ public class LibvpxVideoRenderer extends BaseRenderer {
*/
*/
protected
void
renderOutputBuffer
(
VpxOutputBuffer
outputBuffer
)
throws
VpxDecoderException
{
protected
void
renderOutputBuffer
(
VpxOutputBuffer
outputBuffer
)
throws
VpxDecoderException
{
int
bufferMode
=
outputBuffer
.
mode
;
int
bufferMode
=
outputBuffer
.
mode
;
boolean
renderRgb
=
bufferMode
==
VpxDecoder
.
OUTPUT_MODE_RGB
&&
surface
!=
null
;
boolean
renderSurface
=
bufferMode
==
VpxDecoder
.
OUTPUT_MODE_SURFACE_YUV
&&
surface
!=
null
;
boolean
renderSurface
=
bufferMode
==
VpxDecoder
.
OUTPUT_MODE_SURFACE_YUV
&&
surface
!=
null
;
boolean
renderYuv
=
bufferMode
==
VpxDecoder
.
OUTPUT_MODE_YUV
&&
outputBufferRenderer
!=
null
;
boolean
renderYuv
=
bufferMode
==
VpxDecoder
.
OUTPUT_MODE_YUV
&&
outputBufferRenderer
!=
null
;
lastRenderTimeUs
=
SystemClock
.
elapsedRealtime
()
*
1000
;
lastRenderTimeUs
=
SystemClock
.
elapsedRealtime
()
*
1000
;
if
(!
render
Rgb
&&
!
render
Yuv
&&
!
renderSurface
)
{
if
(!
renderYuv
&&
!
renderSurface
)
{
dropOutputBuffer
(
outputBuffer
);
dropOutputBuffer
(
outputBuffer
);
}
else
{
}
else
{
maybeNotifyVideoSizeChanged
(
outputBuffer
.
width
,
outputBuffer
.
height
);
maybeNotifyVideoSizeChanged
(
outputBuffer
.
width
,
outputBuffer
.
height
);
if
(
renderRgb
)
{
if
(
renderYuv
)
{
renderRgbFrame
(
outputBuffer
,
scaleToFit
);
outputBuffer
.
release
();
}
else
if
(
renderYuv
)
{
outputBufferRenderer
.
setOutputBuffer
(
outputBuffer
);
outputBufferRenderer
.
setOutputBuffer
(
outputBuffer
);
// The renderer will release the buffer.
// The renderer will release the buffer.
}
else
{
// renderSurface
}
else
{
// renderSurface
...
@@ -675,8 +658,7 @@ public class LibvpxVideoRenderer extends BaseRenderer {
...
@@ -675,8 +658,7 @@ public class LibvpxVideoRenderer extends BaseRenderer {
this
.
surface
=
surface
;
this
.
surface
=
surface
;
this
.
outputBufferRenderer
=
outputBufferRenderer
;
this
.
outputBufferRenderer
=
outputBufferRenderer
;
if
(
surface
!=
null
)
{
if
(
surface
!=
null
)
{
outputMode
=
outputMode
=
VpxDecoder
.
OUTPUT_MODE_SURFACE_YUV
;
useSurfaceYuvOutput
?
VpxDecoder
.
OUTPUT_MODE_SURFACE_YUV
:
VpxDecoder
.
OUTPUT_MODE_RGB
;
}
else
{
}
else
{
outputMode
=
outputMode
=
outputBufferRenderer
!=
null
?
VpxDecoder
.
OUTPUT_MODE_YUV
:
VpxDecoder
.
OUTPUT_MODE_NONE
;
outputBufferRenderer
!=
null
?
VpxDecoder
.
OUTPUT_MODE_YUV
:
VpxDecoder
.
OUTPUT_MODE_NONE
;
...
@@ -739,8 +721,7 @@ public class LibvpxVideoRenderer extends BaseRenderer {
...
@@ -739,8 +721,7 @@ public class LibvpxVideoRenderer extends BaseRenderer {
NUM_OUTPUT_BUFFERS
,
NUM_OUTPUT_BUFFERS
,
initialInputBufferSize
,
initialInputBufferSize
,
mediaCrypto
,
mediaCrypto
,
disableLoopFilter
,
disableLoopFilter
);
useSurfaceYuvOutput
);
decoder
.
setOutputMode
(
outputMode
);
decoder
.
setOutputMode
(
outputMode
);
TraceUtil
.
endSection
();
TraceUtil
.
endSection
();
long
decoderInitializedTimestamp
=
SystemClock
.
elapsedRealtime
();
long
decoderInitializedTimestamp
=
SystemClock
.
elapsedRealtime
();
...
@@ -940,23 +921,6 @@ public class LibvpxVideoRenderer extends BaseRenderer {
...
@@ -940,23 +921,6 @@ public class LibvpxVideoRenderer extends BaseRenderer {
return
drmSessionState
!=
DrmSession
.
STATE_OPENED_WITH_KEYS
;
return
drmSessionState
!=
DrmSession
.
STATE_OPENED_WITH_KEYS
;
}
}
private
void
renderRgbFrame
(
VpxOutputBuffer
outputBuffer
,
boolean
scale
)
{
if
(
bitmap
==
null
||
bitmap
.
getWidth
()
!=
outputBuffer
.
width
||
bitmap
.
getHeight
()
!=
outputBuffer
.
height
)
{
bitmap
=
Bitmap
.
createBitmap
(
outputBuffer
.
width
,
outputBuffer
.
height
,
Bitmap
.
Config
.
RGB_565
);
}
bitmap
.
copyPixelsFromBuffer
(
outputBuffer
.
data
);
Canvas
canvas
=
surface
.
lockCanvas
(
null
);
if
(
scale
)
{
canvas
.
scale
(
((
float
)
canvas
.
getWidth
())
/
outputBuffer
.
width
,
((
float
)
canvas
.
getHeight
())
/
outputBuffer
.
height
);
}
canvas
.
drawBitmap
(
bitmap
,
0
,
0
,
null
);
surface
.
unlockCanvasAndPost
(
canvas
);
}
private
void
setJoiningDeadlineMs
()
{
private
void
setJoiningDeadlineMs
()
{
joiningDeadlineMs
=
allowedJoiningTimeMs
>
0
joiningDeadlineMs
=
allowedJoiningTimeMs
>
0
?
(
SystemClock
.
elapsedRealtime
()
+
allowedJoiningTimeMs
)
:
C
.
TIME_UNSET
;
?
(
SystemClock
.
elapsedRealtime
()
+
allowedJoiningTimeMs
)
:
C
.
TIME_UNSET
;
...
...
extensions/vp9/src/main/java/com/google/android/exoplayer2/ext/vp9/VpxDecoder.java
View file @
19144c4c
...
@@ -31,8 +31,7 @@ import java.nio.ByteBuffer;
...
@@ -31,8 +31,7 @@ import java.nio.ByteBuffer;
public
static
final
int
OUTPUT_MODE_NONE
=
-
1
;
public
static
final
int
OUTPUT_MODE_NONE
=
-
1
;
public
static
final
int
OUTPUT_MODE_YUV
=
0
;
public
static
final
int
OUTPUT_MODE_YUV
=
0
;
public
static
final
int
OUTPUT_MODE_RGB
=
1
;
public
static
final
int
OUTPUT_MODE_SURFACE_YUV
=
1
;
public
static
final
int
OUTPUT_MODE_SURFACE_YUV
=
2
;
private
static
final
int
NO_ERROR
=
0
;
private
static
final
int
NO_ERROR
=
0
;
private
static
final
int
DECODE_ERROR
=
1
;
private
static
final
int
DECODE_ERROR
=
1
;
...
@@ -52,7 +51,6 @@ import java.nio.ByteBuffer;
...
@@ -52,7 +51,6 @@ import java.nio.ByteBuffer;
* @param exoMediaCrypto The {@link ExoMediaCrypto} object required for decoding encrypted
* @param exoMediaCrypto The {@link ExoMediaCrypto} object required for decoding encrypted
* content. Maybe null and can be ignored if decoder does not handle encrypted content.
* content. Maybe null and can be ignored if decoder does not handle encrypted content.
* @param disableLoopFilter Disable the libvpx in-loop smoothing filter.
* @param disableLoopFilter Disable the libvpx in-loop smoothing filter.
* @param enableSurfaceYuvOutputMode Whether OUTPUT_MODE_SURFACE_YUV is allowed.
* @throws VpxDecoderException Thrown if an exception occurs when initializing the decoder.
* @throws VpxDecoderException Thrown if an exception occurs when initializing the decoder.
*/
*/
public
VpxDecoder
(
public
VpxDecoder
(
...
@@ -60,8 +58,7 @@ import java.nio.ByteBuffer;
...
@@ -60,8 +58,7 @@ import java.nio.ByteBuffer;
int
numOutputBuffers
,
int
numOutputBuffers
,
int
initialInputBufferSize
,
int
initialInputBufferSize
,
ExoMediaCrypto
exoMediaCrypto
,
ExoMediaCrypto
exoMediaCrypto
,
boolean
disableLoopFilter
,
boolean
disableLoopFilter
)
boolean
enableSurfaceYuvOutputMode
)
throws
VpxDecoderException
{
throws
VpxDecoderException
{
super
(
new
VpxInputBuffer
[
numInputBuffers
],
new
VpxOutputBuffer
[
numOutputBuffers
]);
super
(
new
VpxInputBuffer
[
numInputBuffers
],
new
VpxOutputBuffer
[
numOutputBuffers
]);
if
(!
VpxLibrary
.
isAvailable
())
{
if
(!
VpxLibrary
.
isAvailable
())
{
...
@@ -71,7 +68,7 @@ import java.nio.ByteBuffer;
...
@@ -71,7 +68,7 @@ import java.nio.ByteBuffer;
if
(
exoMediaCrypto
!=
null
&&
!
VpxLibrary
.
vpxIsSecureDecodeSupported
())
{
if
(
exoMediaCrypto
!=
null
&&
!
VpxLibrary
.
vpxIsSecureDecodeSupported
())
{
throw
new
VpxDecoderException
(
"Vpx decoder does not support secure decode."
);
throw
new
VpxDecoderException
(
"Vpx decoder does not support secure decode."
);
}
}
vpxDecContext
=
vpxInit
(
disableLoopFilter
,
enableSurfaceYuvOutputMod
e
);
vpxDecContext
=
vpxInit
(
disableLoopFilter
,
tru
e
);
if
(
vpxDecContext
==
0
)
{
if
(
vpxDecContext
==
0
)
{
throw
new
VpxDecoderException
(
"Failed to initialize decoder"
);
throw
new
VpxDecoderException
(
"Failed to initialize decoder"
);
}
}
...
@@ -86,8 +83,8 @@ import java.nio.ByteBuffer;
...
@@ -86,8 +83,8 @@ import java.nio.ByteBuffer;
/**
/**
* Sets the output mode for frames rendered by the decoder.
* Sets the output mode for frames rendered by the decoder.
*
*
* @param outputMode The output mode. One of {@link #OUTPUT_MODE_NONE}
, {@link #OUTPUT_MODE_RGB}
* @param outputMode The output mode. One of {@link #OUTPUT_MODE_NONE}
and {@link
*
and {@link
#OUTPUT_MODE_YUV}.
* #OUTPUT_MODE_YUV}.
*/
*/
public
void
setOutputMode
(
int
outputMode
)
{
public
void
setOutputMode
(
int
outputMode
)
{
this
.
outputMode
=
outputMode
;
this
.
outputMode
=
outputMode
;
...
...
extensions/vp9/src/main/java/com/google/android/exoplayer2/ext/vp9/VpxOutputBuffer.java
View file @
19144c4c
...
@@ -60,8 +60,8 @@ public final class VpxOutputBuffer extends OutputBuffer {
...
@@ -60,8 +60,8 @@ public final class VpxOutputBuffer extends OutputBuffer {
* Initializes the buffer.
* Initializes the buffer.
*
*
* @param timeUs The presentation timestamp for the buffer, in microseconds.
* @param timeUs The presentation timestamp for the buffer, in microseconds.
* @param mode The output mode. One of {@link VpxDecoder#OUTPUT_MODE_NONE}
,
* @param mode The output mode. One of {@link VpxDecoder#OUTPUT_MODE_NONE}
and {@link
*
{@link VpxDecoder#OUTPUT_MODE_RGB} and {@link
VpxDecoder#OUTPUT_MODE_YUV}.
* VpxDecoder#OUTPUT_MODE_YUV}.
*/
*/
public
void
init
(
long
timeUs
,
int
mode
)
{
public
void
init
(
long
timeUs
,
int
mode
)
{
this
.
timeUs
=
timeUs
;
this
.
timeUs
=
timeUs
;
...
@@ -69,27 +69,11 @@ public final class VpxOutputBuffer extends OutputBuffer {
...
@@ -69,27 +69,11 @@ public final class VpxOutputBuffer extends OutputBuffer {
}
}
/**
/**
* Resizes the buffer based on the given dimensions. Called via JNI after decoding completes.
* @return Whether the buffer was resized successfully.
*/
public
boolean
initForRgbFrame
(
int
width
,
int
height
)
{
this
.
width
=
width
;
this
.
height
=
height
;
this
.
yuvPlanes
=
null
;
if
(!
isSafeToMultiply
(
width
,
height
)
||
!
isSafeToMultiply
(
width
*
height
,
2
))
{
return
false
;
}
int
minimumRgbSize
=
width
*
height
*
2
;
initData
(
minimumRgbSize
);
return
true
;
}
/**
* Resizes the buffer based on the given stride. Called via JNI after decoding completes.
* Resizes the buffer based on the given stride. Called via JNI after decoding completes.
*
* @return Whether the buffer was resized successfully.
* @return Whether the buffer was resized successfully.
*/
*/
public
boolean
initForYuvFrame
(
int
width
,
int
height
,
int
yStride
,
int
uvStride
,
public
boolean
initForYuvFrame
(
int
width
,
int
height
,
int
yStride
,
int
uvStride
,
int
colorspace
)
{
int
colorspace
)
{
this
.
width
=
width
;
this
.
width
=
width
;
this
.
height
=
height
;
this
.
height
=
height
;
this
.
colorspace
=
colorspace
;
this
.
colorspace
=
colorspace
;
...
...
extensions/vp9/src/main/jni/Android.mk
View file @
19144c4c
...
@@ -17,12 +17,6 @@
...
@@ -17,12 +17,6 @@
WORKING_DIR := $(call my-dir)
WORKING_DIR := $(call my-dir)
include $(CLEAR_VARS)
include $(CLEAR_VARS)
LIBVPX_ROOT := $(WORKING_DIR)/libvpx
LIBVPX_ROOT := $(WORKING_DIR)/libvpx
LIBYUV_ROOT := $(WORKING_DIR)/libyuv
# build libyuv_static.a
LOCAL_PATH := $(WORKING_DIR)
LIBYUV_DISABLE_JPEG := "yes"
include $(LIBYUV_ROOT)/Android.mk
# build libvpx.so
# build libvpx.so
LOCAL_PATH := $(WORKING_DIR)
LOCAL_PATH := $(WORKING_DIR)
...
@@ -37,7 +31,7 @@ LOCAL_CPP_EXTENSION := .cc
...
@@ -37,7 +31,7 @@ LOCAL_CPP_EXTENSION := .cc
LOCAL_SRC_FILES := vpx_jni.cc
LOCAL_SRC_FILES := vpx_jni.cc
LOCAL_LDLIBS := -llog -lz -lm -landroid
LOCAL_LDLIBS := -llog -lz -lm -landroid
LOCAL_SHARED_LIBRARIES := libvpx
LOCAL_SHARED_LIBRARIES := libvpx
LOCAL_STATIC_LIBRARIES :=
libyuv_static
cpufeatures
LOCAL_STATIC_LIBRARIES := cpufeatures
include $(BUILD_SHARED_LIBRARY)
include $(BUILD_SHARED_LIBRARY)
$(call import-module,android/cpufeatures)
$(call import-module,android/cpufeatures)
extensions/vp9/src/main/jni/vpx_jni.cc
View file @
19144c4c
...
@@ -30,8 +30,6 @@
...
@@ -30,8 +30,6 @@
#include <cstring>
#include <cstring>
#include <new>
#include <new>
#include "libyuv.h" // NOLINT
#define VPX_CODEC_DISABLE_COMPAT 1
#define VPX_CODEC_DISABLE_COMPAT 1
#include "vpx/vpx_decoder.h"
#include "vpx/vpx_decoder.h"
#include "vpx/vp8dx.h"
#include "vpx/vp8dx.h"
...
@@ -61,7 +59,6 @@
...
@@ -61,7 +59,6 @@
(JNIEnv* env, jobject thiz, ##__VA_ARGS__)\
(JNIEnv* env, jobject thiz, ##__VA_ARGS__)\
// JNI references for VpxOutputBuffer class.
// JNI references for VpxOutputBuffer class.
static
jmethodID
initForRgbFrame
;
static
jmethodID
initForYuvFrame
;
static
jmethodID
initForYuvFrame
;
static
jfieldID
dataField
;
static
jfieldID
dataField
;
static
jfieldID
outputModeField
;
static
jfieldID
outputModeField
;
...
@@ -393,11 +390,7 @@ class JniBufferManager {
...
@@ -393,11 +390,7 @@ class JniBufferManager {
};
};
struct
JniCtx
{
struct
JniCtx
{
JniCtx
(
bool
enableBufferManager
)
{
JniCtx
()
{
buffer_manager
=
new
JniBufferManager
();
}
if
(
enableBufferManager
)
{
buffer_manager
=
new
JniBufferManager
();
}
}
~
JniCtx
()
{
~
JniCtx
()
{
if
(
native_window
)
{
if
(
native_window
)
{
...
@@ -440,9 +433,8 @@ int vpx_release_frame_buffer(void* priv, vpx_codec_frame_buffer_t* fb) {
...
@@ -440,9 +433,8 @@ int vpx_release_frame_buffer(void* priv, vpx_codec_frame_buffer_t* fb) {
return
buffer_manager
->
release
(
*
(
int
*
)
fb
->
priv
);
return
buffer_manager
->
release
(
*
(
int
*
)
fb
->
priv
);
}
}
DECODER_FUNC
(
jlong
,
vpxInit
,
jboolean
disableLoopFilter
,
jlong
vpxInit
(
JNIEnv
*
env
,
jboolean
disableLoopFilter
)
{
jboolean
enableBufferManager
)
{
JniCtx
*
context
=
new
JniCtx
();
JniCtx
*
context
=
new
JniCtx
(
enableBufferManager
);
context
->
decoder
=
new
vpx_codec_ctx_t
();
context
->
decoder
=
new
vpx_codec_ctx_t
();
vpx_codec_dec_cfg_t
cfg
=
{
0
,
0
,
0
};
vpx_codec_dec_cfg_t
cfg
=
{
0
,
0
,
0
};
cfg
.
threads
=
android_getCpuCount
();
cfg
.
threads
=
android_getCpuCount
();
...
@@ -469,14 +461,12 @@ DECODER_FUNC(jlong, vpxInit, jboolean disableLoopFilter,
...
@@ -469,14 +461,12 @@ DECODER_FUNC(jlong, vpxInit, jboolean disableLoopFilter,
}
}
#endif
#endif
}
}
if
(
enableBufferManager
)
{
err
=
vpx_codec_set_frame_buffer_functions
(
err
=
vpx_codec_set_frame_buffer_functions
(
context
->
decoder
,
vpx_get_frame_buffer
,
vpx_release_frame_buffer
,
context
->
decoder
,
vpx_get_frame_buffer
,
vpx_release_frame_buffer
,
context
->
buffer_manager
);
context
->
buffer_manager
);
if
(
err
)
{
if
(
err
)
{
LOGE
(
"ERROR: Failed to set libvpx frame buffer functions, error = %d."
,
LOGE
(
"ERROR: Failed to set libvpx frame buffer functions, error = %d."
,
err
);
err
);
}
}
}
// Populate JNI References.
// Populate JNI References.
...
@@ -484,8 +474,6 @@ DECODER_FUNC(jlong, vpxInit, jboolean disableLoopFilter,
...
@@ -484,8 +474,6 @@ DECODER_FUNC(jlong, vpxInit, jboolean disableLoopFilter,
"com/google/android/exoplayer2/ext/vp9/VpxOutputBuffer"
);
"com/google/android/exoplayer2/ext/vp9/VpxOutputBuffer"
);
initForYuvFrame
=
env
->
GetMethodID
(
outputBufferClass
,
"initForYuvFrame"
,
initForYuvFrame
=
env
->
GetMethodID
(
outputBufferClass
,
"initForYuvFrame"
,
"(IIIII)Z"
);
"(IIIII)Z"
);
initForRgbFrame
=
env
->
GetMethodID
(
outputBufferClass
,
"initForRgbFrame"
,
"(II)Z"
);
dataField
=
env
->
GetFieldID
(
outputBufferClass
,
"data"
,
dataField
=
env
->
GetFieldID
(
outputBufferClass
,
"data"
,
"Ljava/nio/ByteBuffer;"
);
"Ljava/nio/ByteBuffer;"
);
outputModeField
=
env
->
GetFieldID
(
outputBufferClass
,
"mode"
,
"I"
);
outputModeField
=
env
->
GetFieldID
(
outputBufferClass
,
"mode"
,
"I"
);
...
@@ -494,6 +482,15 @@ DECODER_FUNC(jlong, vpxInit, jboolean disableLoopFilter,
...
@@ -494,6 +482,15 @@ DECODER_FUNC(jlong, vpxInit, jboolean disableLoopFilter,
return
reinterpret_cast
<
intptr_t
>
(
context
);
return
reinterpret_cast
<
intptr_t
>
(
context
);
}
}
DECODER_FUNC
(
jlong
,
vpxInit
,
jboolean
disableLoopFilter
,
jboolean
enableBufferManager
)
{
return
vpxInit
(
env
,
disableLoopFilter
);
}
DECODER_FUNC
(
jlong
,
vpxInitilization
,
jboolean
disableLoopFilter
)
{
return
vpxInit
(
env
,
disableLoopFilter
);
}
DECODER_FUNC
(
jlong
,
vpxDecode
,
jlong
jContext
,
jobject
encoded
,
jint
len
)
{
DECODER_FUNC
(
jlong
,
vpxDecode
,
jlong
jContext
,
jobject
encoded
,
jint
len
)
{
JniCtx
*
const
context
=
reinterpret_cast
<
JniCtx
*>
(
jContext
);
JniCtx
*
const
context
=
reinterpret_cast
<
JniCtx
*>
(
jContext
);
const
uint8_t
*
const
buffer
=
const
uint8_t
*
const
buffer
=
...
@@ -537,28 +534,10 @@ DECODER_FUNC(jint, vpxGetFrame, jlong jContext, jobject jOutputBuffer) {
...
@@ -537,28 +534,10 @@ DECODER_FUNC(jint, vpxGetFrame, jlong jContext, jobject jOutputBuffer) {
}
}
const
int
kOutputModeYuv
=
0
;
const
int
kOutputModeYuv
=
0
;
const
int
kOutputModeRgb
=
1
;
const
int
kOutputModeSurfaceYuv
=
1
;
const
int
kOutputModeSurfaceYuv
=
2
;
int
outputMode
=
env
->
GetIntField
(
jOutputBuffer
,
outputModeField
);
int
outputMode
=
env
->
GetIntField
(
jOutputBuffer
,
outputModeField
);
if
(
outputMode
==
kOutputModeRgb
)
{
if
(
outputMode
==
kOutputModeYuv
)
{
// resize buffer if required.
jboolean
initResult
=
env
->
CallBooleanMethod
(
jOutputBuffer
,
initForRgbFrame
,
img
->
d_w
,
img
->
d_h
);
if
(
env
->
ExceptionCheck
()
||
!
initResult
)
{
return
-
1
;
}
// get pointer to the data buffer.
const
jobject
dataObject
=
env
->
GetObjectField
(
jOutputBuffer
,
dataField
);
uint8_t
*
const
dst
=
reinterpret_cast
<
uint8_t
*>
(
env
->
GetDirectBufferAddress
(
dataObject
));
libyuv
::
I420ToRGB565
(
img
->
planes
[
VPX_PLANE_Y
],
img
->
stride
[
VPX_PLANE_Y
],
img
->
planes
[
VPX_PLANE_U
],
img
->
stride
[
VPX_PLANE_U
],
img
->
planes
[
VPX_PLANE_V
],
img
->
stride
[
VPX_PLANE_V
],
dst
,
img
->
d_w
*
2
,
img
->
d_w
,
img
->
d_h
);
}
else
if
(
outputMode
==
kOutputModeYuv
)
{
const
int
kColorspaceUnknown
=
0
;
const
int
kColorspaceUnknown
=
0
;
const
int
kColorspaceBT601
=
1
;
const
int
kColorspaceBT601
=
1
;
const
int
kColorspaceBT709
=
2
;
const
int
kColorspaceBT709
=
2
;
...
@@ -616,9 +595,6 @@ DECODER_FUNC(jint, vpxGetFrame, jlong jContext, jobject jOutputBuffer) {
...
@@ -616,9 +595,6 @@ DECODER_FUNC(jint, vpxGetFrame, jlong jContext, jobject jOutputBuffer) {
}
}
}
else
if
(
outputMode
==
kOutputModeSurfaceYuv
&&
}
else
if
(
outputMode
==
kOutputModeSurfaceYuv
&&
img
->
fmt
!=
VPX_IMG_FMT_I42016
)
{
img
->
fmt
!=
VPX_IMG_FMT_I42016
)
{
if
(
!
context
->
buffer_manager
)
{
return
-
1
;
// enableBufferManager was not set in vpxInit.
}
int
id
=
*
(
int
*
)
img
->
fb_priv
;
int
id
=
*
(
int
*
)
img
->
fb_priv
;
context
->
buffer_manager
->
add_ref
(
id
);
context
->
buffer_manager
->
add_ref
(
id
);
JniFrameBuffer
*
jfb
=
context
->
buffer_manager
->
get_buffer
(
id
);
JniFrameBuffer
*
jfb
=
context
->
buffer_manager
->
get_buffer
(
id
);
...
...
library/core/proguard-rules.txt
View file @
19144c4c
...
@@ -3,7 +3,7 @@
...
@@ -3,7 +3,7 @@
# Constructors accessed via reflection in DefaultRenderersFactory
# Constructors accessed via reflection in DefaultRenderersFactory
-dontnote com.google.android.exoplayer2.ext.vp9.LibvpxVideoRenderer
-dontnote com.google.android.exoplayer2.ext.vp9.LibvpxVideoRenderer
-keepclassmembers class com.google.android.exoplayer2.ext.vp9.LibvpxVideoRenderer {
-keepclassmembers class com.google.android.exoplayer2.ext.vp9.LibvpxVideoRenderer {
<init>(
boolean,
long, android.os.Handler, com.google.android.exoplayer2.video.VideoRendererEventListener, int);
<init>(long, android.os.Handler, com.google.android.exoplayer2.video.VideoRendererEventListener, int);
}
}
-dontnote com.google.android.exoplayer2.ext.opus.LibopusAudioRenderer
-dontnote com.google.android.exoplayer2.ext.opus.LibopusAudioRenderer
-keepclassmembers class com.google.android.exoplayer2.ext.opus.LibopusAudioRenderer {
-keepclassmembers class com.google.android.exoplayer2.ext.opus.LibopusAudioRenderer {
...
...
library/core/src/main/java/com/google/android/exoplayer2/DefaultRenderersFactory.java
View file @
19144c4c
...
@@ -233,7 +233,6 @@ public class DefaultRenderersFactory implements RenderersFactory {
...
@@ -233,7 +233,6 @@ public class DefaultRenderersFactory implements RenderersFactory {
Class
<?>
clazz
=
Class
.
forName
(
"com.google.android.exoplayer2.ext.vp9.LibvpxVideoRenderer"
);
Class
<?>
clazz
=
Class
.
forName
(
"com.google.android.exoplayer2.ext.vp9.LibvpxVideoRenderer"
);
Constructor
<?>
constructor
=
Constructor
<?>
constructor
=
clazz
.
getConstructor
(
clazz
.
getConstructor
(
boolean
.
class
,
long
.
class
,
long
.
class
,
android
.
os
.
Handler
.
class
,
android
.
os
.
Handler
.
class
,
com
.
google
.
android
.
exoplayer2
.
video
.
VideoRendererEventListener
.
class
,
com
.
google
.
android
.
exoplayer2
.
video
.
VideoRendererEventListener
.
class
,
...
@@ -242,7 +241,6 @@ public class DefaultRenderersFactory implements RenderersFactory {
...
@@ -242,7 +241,6 @@ public class DefaultRenderersFactory implements RenderersFactory {
Renderer
renderer
=
Renderer
renderer
=
(
Renderer
)
(
Renderer
)
constructor
.
newInstance
(
constructor
.
newInstance
(
true
,
allowedVideoJoiningTimeMs
,
allowedVideoJoiningTimeMs
,
eventHandler
,
eventHandler
,
eventListener
,
eventListener
,
...
...
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