The workaround in ExternalTextureManager.forceSignalEndOfStream
was being applied even when the decoder did output all frames, and only
the GL pipeline was slow.
This change ensures that workaround is not applied when the decoder
has already produced all output frames.
PiperOrigin-RevId: 680471587
This is no longer needed now our `compileSdk` implies a new-enough AGP
which does this out-lining automatically via R8. See also
https://issuetracker.google.com/345472586#comment7
There's no plan to remove the `ApiXXX` classes, but no new ones need
to be added.
PiperOrigin-RevId: 675940634
If the task executor handles an available frame (task submitted in the
SurfaceTexture listener) between the call to registerInputFrame() and
the execution of the task submitted in the method (in this CL), it
should be rejected.
PiperOrigin-RevId: 672903756
Seeking was causing the player to hang in the following scenario:
1. The surfaceTexture's onFrameAvailableListener is called in
ExternalTextureManager to notify that a new frame is available.
2. This call submits a task on the GL thread.
3. A seek is performed and DefaultVideoFrameProcessor.flush() is called
before the task submitted in 2 is executed.
4. DefaultVideoFrameProcessor.flush() flushes the task executor, so that
the task submitted in 2 never gets executed.
5. Once the seek is over, the first frame is registered and rendered on
the surface texture.
6. Playback hangs because the onFrameAvailableListener is never called
for this new frame. This is because surfaceTexture.updateTexImage()
was never called on the frame that became available in 1.
This fix is making sure that the task submitted in 2 always gets executed.
Issue: androidx/media#1535
PiperOrigin-RevId: 671389215
Make ByteBufferGlEffect public.
Build a speed test, and end to end test that verify
frames can be copied to CPU-accessible ByteBuffer
PiperOrigin-RevId: 670213343
Adds a class that represents an image rectangle
in OpenGL coordinate convention.
android.graphics.Rect puts (0, 0) as the top-left corner:
it enforces `Rect.top <= Rect.bottom` and this matches
`android.graphics.Bitmap` coordinates: docs https://developer.android.com/reference/android/graphics/Rect
This is different from OpenGL coordinates where (0, 0) is
at the bottom-left corner. I.e. GlRect.bottom <= GlRect.top: docs https://registry.khronos.org/OpenGL-Refpages/es3.0/html/glReadPixels.xhtml
The reason for this change is to allow a public API GlRect
getScaledRegion() which selects a region of pixels of a GL texture
to be copied to CPU memory.
PiperOrigin-RevId: 669231826
The existing logic was not working sometimes because:
1. The repeated scheduling in releaseAllFramesFromMediaCodec was
starving the thread on which the SurfaceTexture frameAvailableListener
was called.
2. The case where a pending frame arrives on the surface after flush
finishes executing was not handled.
The consequence of both problems is that availableFrameCount ended up
being > pendingFrames.size().
PiperOrigin-RevId: 668916256
OpenGL ES 3.0 likely can be used since Android 18.
Moving to a higher version context more often can make
sharing GL context easier for apps
PiperOrigin-RevId: 667915331
* Changes to GlUtil to manage Pixel Buffer Objects and asynchronous
GPU -> CPU glReadPixels
* Make ByteBufferConcurrentEffect non-blocking
PiperOrigin-RevId: 667908805
* new ByteBufferGlEffect GlEffect that enables API users to
implement an effect that accesses video frame data via CPU-mapped ByteBuffer
* ByteBufferConcurrentEffect responsible for reading
video frame data in CPU-accessible ByteBuffer
PiperOrigin-RevId: 666375594
Implement a QueuingGlShaderProgram which queues up OpenGL frames and allows
asynchronous execution of effects that operate on video frames without a
performance penalty.
PiperOrigin-RevId: 666326611
Previously in MultiInputVideoGraph, each VFP would destroy the shared
eglContext, such that the same eglContext object is destroyed multiple times.
Adding a flag to disallow this.
The alternative being we could add a flag on the VFP constructor, but I think
that is too subscriptive (meaning if we later might want to add another boolean
to control another GL behaviour, multiple booleans would make the class less
reason-able), and would incur a lot of code changes at places.
PiperOrigin-RevId: 660354367
Transformer.experimentalSetMaxFramesInEncoder controls max number
of frames in encoder.
VideoFrameProcessor now allows delayed releasing of frames to Surface,
while still using the original presentation time.
VideoSampleExporter can now configure video graphs to not render frames
automatically to output surface.
VideoSampleExporter.VideoGraphWrapper tracks how many frames are ready
to be rendered to Surface, and how many frames are already in-use by encoder.
PiperOrigin-RevId: 658429969
Public methods either assert they're running GL thread, or
submit a task to run on GL thread.
Move methods to keep interface implementations together.
Add javadoc to VideoFrameProcessingTaskExecutor to clarify which
thread can call each public method.
PiperOrigin-RevId: 655978796
Build upon Transformer.videoFrameProcessorFactory in MultipleInputVideoGraph
Check that Transformer.videoFrameProcessorFactory is DefaultVideoFrameProcessor
for multi-input video
Fixes https://github.com/androidx/media/issues/1509
PiperOrigin-RevId: 655232381
eglDestroySurface only destroys the surface when it's made not current.
Pass the placeholder surface in FinalShaderProgramWrapper and use it
when destroying eglSurface.
PiperOrigin-RevId: 655139661
Add VideoFrameProcessingTaskExecutor.invoke() method that blocks until
Task has executed on GL thread.
Use that for FinalShaderProgramWrapper.setOutputSurfaceInfo
PiperOrigin-RevId: 655119768
This is because the force EOS workaround for videos is longer than the original
muxer timeout. This way the apps depending on Transformer won't have to manually
set the muxer timeout on emulators.
PiperOrigin-RevId: 651355755
Deprecate `setInputDefaultBufferSize` and `setRequireRegisteringAllInputFrames`
as the new input stream type replaces these (as far as we know they are always
used together).
This is in preparation for supporting asset loaders signaling that they require
these features, specifically for recording from a surface.
PiperOrigin-RevId: 648686087
Previously, if renderFramesAutomatically = false, DefaultVideoFrameProcessor
may call onInputStreamProcessedListener after all frames have been
onOutputFrameAvailableForRendering, but before they had all been rendered and
freed.
Delay onInputStreamProcessedListener being called and subsequent DVFP
reconfiguration of effects, until all frames are rendered.
Tested using exoplayer setVideoEffects demo with playlist
PiperOrigin-RevId: 642963100
useHdr is unused option and doesn't make sense is the dynamic range of the overlay and video must match
Also reorders and adds javadoc in line with coding conventions
PiperOrigin-RevId: 642555396
Avoid scaling the lanczos windown function when scaling up.
When scaling up (output > input), we shouldn't scale the window
function or we risk not sampling any of the input pixels.
PiperOrigin-RevId: 641838149
Add SeparableConvolution.configure(inputSize) to allow effect configuration
depending on input dimensions.
Add LanczosResample.scaleToFit method to scale input images to fit inside
given dimensions.
PiperOrigin-RevId: 640498008
fragment_shader_separable_convolution_es2.glsl had optimizations that assumed
all convolution coefficients are positive. Support negative coefficients,
and add tests.
PiperOrigin-RevId: 640104741
Switch from 4-channel RGBA_16F lookup texture to 1-channel R_16F.
Do not use a bitmap when creating the lookup table texture.
Instead, fill the texture directly.
Do not manually convert 32-bit float to 16-bit. Instead, let OpenGL
libraries do this for us.
PiperOrigin-RevId: 639717235
Add DefaultVideosFrameProcessor experimental flag that controls
whether input Bitmaps are sampled once for a repeating sequence of
output frames with the same contents, or once for each output frame.
PiperOrigin-RevId: 637921350
Only sample from input bitmap when the input image has changed.
Introduce GainmapShaderProgram.newImmutableBitmap API that signals
input bitmap changes to GainmapShaderProgram (DefaultShaderProgram).
PiperOrigin-RevId: 637920207