Commit graph

250 commits

Author SHA1 Message Date
hschlueter
73b57d3c77 Implement chaining GlTextureProcessor.Listener.
In follow-ups the FrameProcessorChain will set an instance of this
listener for each GlTextureProcessor to chain it with its previous
and next GlTextureProcesssor.

PiperOrigin-RevId: 455628942
(cherry picked from commit 981baae709)
2022-06-17 16:57:46 +01:00
hschlueter
c16e5ac47c Wrap processor chain executor service for better exception handling.
The wrapper
* catches exceptions for each task and notifies the
  listener (this will be used more in follow-ups when processFrame
  is split into lots of listeners and callbacks),
* removes finished tasks from the queue and signals any exceptions
  that occurred to the listener each time a new task is executed.

PiperOrigin-RevId: 455345184
(cherry picked from commit ee847d92c5)
2022-06-16 10:41:23 +00:00
hschlueter
8c465a7860 Replace FrameProcessorChain#isEnded with listener method.
PiperOrigin-RevId: 455114693
(cherry picked from commit fdfca88019)
2022-06-15 13:27:35 +00:00
hschlueter
b7118486dc Use FrameProcessorChain#SurfaceProvider for encoder compat transform.
This change adds a SurfaceProvider interface which is necessary to
allow for texture processors whose output size becomes available
asynchronously in follow-ups.
VTSP's implementation of this interface wraps the encoder and provides
its input surface together with the output frame width, height, and
orientation as used for encoder configuration.
The FrameProcessorChain converts the output frames to the provided
orientation and resolution using a ScaleToFitTransformation and
Presentation replacing EncoderCompatibilityTransformation.

PiperOrigin-RevId: 455112598
(cherry picked from commit ea7f1ca1e3)
2022-06-15 13:14:56 +00:00
hschlueter
56f234ea75 Check targetSdkVersion for frame dropping workaround.
Based on
https://developer.android.com/reference/android/media/MediaCodec#using-an-output-surface,
frame dropping behaviour depends on the target SDK version.
After this change transformer will only use
MediaFormat#KEY_ALLOW_FRAME_DROP if both the target and system SDK
version are at least 29 and default to its pre 29 behaviour where each
decoder output frame must be processed before a new one is rendered
to prevent frame dropping otherwise.

Also remove deprecated Transformer.Builder constructor without a
context and the context setter.

PiperOrigin-RevId: 453971097
(cherry picked from commit a105d033a7)
2022-06-09 18:22:39 +00:00
hschlueter
0b08396255 Make GlUtil.GlException checked and remove flag to disable it.
Transformer always enabled glAssertionsEnabled, so there should
be no functional change.

ExoPlayer previously disabled glAssertionsEnabled, so GlUtil logged
GlExceptions instead of throwing them. The GlExceptions are now
caught and logged by the callers so that there should also be no
functional change overall.

This change also replaces EGLSurfaceTexture#GlException with
GlUtil#GlException.

PiperOrigin-RevId: 453963741
(cherry picked from commit cc1f32d094)
2022-06-09 17:53:39 +00:00
huangdarwin
5349312f50 Transformer GL: Split Presentation and Crop.
This removes the prior restriction of needing to remember not to crop and set aspect ratio in the same Presentation.Builder, and makes each class a bit more targeted.

This is partially made feasible by the past work to merge consecutive
MatrixTransformations into a single MatrixTransformationFrameProcessor, which
ensures that there's no loss in quality between successive MatrixTransformations.

PiperOrigin-RevId: 453660582
(cherry picked from commit c5b881e089)
2022-06-08 12:51:28 +00:00
hschlueter
8973efd199 Mention alpha for matrix transformation background color.
PiperOrigin-RevId: 453633920
(cherry picked from commit cdb8038782)
2022-06-08 09:50:18 +00:00
hschlueter
dac3878273 Implement default GlTextureProcessor in SingleFrameGlTextureProcessor.
SingleFrameGlTextureProcessor is now an abstract class containing a
default implementation of the more flexible GlTextureProcessor interface
while still exposing the same simple abstract methods for single frame
processing it previously did.

FrameProcessorChain and GlEffect will be changed to use
GlTextureProcessor in follow-ups.

PiperOrigin-RevId: 453633000
(cherry picked from commit 457f446114)
2022-06-08 09:44:25 +00:00
hschlueter
f4dfbdbc37 Add interface for async texture processors.
Implementations of this interface will be able to drop or add frames,
change timestamps, accept multiple input frames before producing
output, and process frames on their own background thread.

A default implementation of this interface will be added to SingleFrameGlTextureProcessor in a follow-up.

PiperOrigin-RevId: 453159835
(cherry picked from commit 63436390de)
2022-06-06 10:18:26 +00:00
hschlueter
27f23041cf Add async error listener to transformer to avoid exception wrapping.
This internal listener avoids wrapping the TransformationExceptions
in PlaybackExceptions that are handled via the Player.Listener and
is also used for FrameProcessingExceptions which already avoided
the PlaybackException layer previously.

This listener will also be useful in follow-ups for encoder-related
TransformationExceptions that are thrown in the SurfaceProvider that
will be called on the GL thread.

PiperOrigin-RevId: 452074575
(cherry picked from commit 35b5147eb1)
2022-05-31 17:01:02 +00:00
hschlueter
22ee071b53 Move program initialization to texture processor constructor.
Once the more advanced GlTextureProcessor interface exists,
it will be possible to change the output size of a GlTextureProcessor
between frames. To keep the re-configuration based on the frame sizes
minimal, things indepedent of the frame size, such as the GlProgram,
can be initialized in the constructor.

PiperOrigin-RevId: 451997584
(cherry picked from commit 87ab96d352)
2022-05-31 09:36:18 +00:00
andrewlewis
b25d00a795 Retain stream time offsets through codecs
ExoPlayer applies a large time offset to buffers so that, if the input has negative timestamps, generally buffers seen by the decoders should have positive timestamps. Modify how the offset is handled in `Transformer` so that decoders and encoders generally see positive timestamps, by leaving the offset on samples when reading them in the base renderer (remove the code that removed the offset), and then removing the offset when muxing. Also update the frame processor chain and slow motion flattening code to retain the existing behavior after this change (these both need original media presentation timestamps)

Tested via existing end-to-end tests and manually verified that the overlay frame processor shows the expected original media timestamps.

Aside: we don't need the same logic as ExoPlayer to track stream offsets across the decoder yet, because we don't try to handle stream changes during playback in single asset editing. (There is an edge case of multi-period DASH that may not work but I doubt anyone will use that as input to `Transformer` before we change the code to handle multi-asset properly.) In future we should try to refactor interaction with the decoder to use the same code for Transformer and ExoPlayer.
PiperOrigin-RevId: 451846055
2022-05-30 16:45:15 +00:00
hschlueter
9649411a4f Use video passthrough if clipping starts at key frame.
PiperOrigin-RevId: 451380267
2022-05-30 16:37:19 +00:00
huangdarwin
099a542dac Transformer: Skip SSIM in tests when fallback is applied.
SSIM calculation requires the input and output dimensions to be identical.

For devices that can't encode the input dimensions, skip SSIM calculations and
log the cause. Only apply this on tests where the encoder may not support the
input file dimensions.

PiperOrigin-RevId: 451364904
2022-05-30 16:35:35 +00:00
hschlueter
fe3831c5b4 Fix handling clipping in transformer renderers.
Decode-only video frames (needed when the frame at / first frame after the
clipping start is not a key frame) need to be decoded but not passed to
the frame processor chain or encoder.

The clipping start offset needs to be removed from the frame timestamps
in the passthrough and video pipelines.
There are no changes needed for this in the audio pipeline, as it doesn't
use the input timestamps -- it uses its own timestamps derived from the
buffer sizes instead.

Also add demo option to try this out.

#minor-release

PiperOrigin-RevId: 451353609
2022-05-30 16:34:38 +00:00
hschlueter
0eaf3d30c8 Rename GlFrameProcessor to SingleFrameGlTextureProcessor.
Also update names of implementations to match design doc.
In follow-ups, SingleFrameGlTextureProcessor will become
an abstract implementation of a new GlTextureProcessor
interface.

Texture processor makes sense as it processes OpenGL textures.
The term frame processor will be used for something else in
follow-ups.

PiperOrigin-RevId: 451142085
2022-05-30 16:31:13 +00:00
hschlueter
196a99aa5f Don't reallocate EGLSurface for same debug surface.
Recreating an EGLSurface for a surface that already has an
EGLSurface is not allowed according to the
[documentation](https://www.khronos.org/registry/EGL/sdk/docs/man/html/eglCreatePlatformWindowSurface.xhtml).

This fix was tested on the devices listed in the bug
description (Pixel 5a, Nexus 5).

PiperOrigin-RevId: 450473569
2022-05-23 18:37:04 +01:00
andrewlewis
ce1ac5894d Track validity of debug SurfaceView
The debug surface view's output surface can become invalid during a transformation due to the parent activity pausing, for example. This can currently cause a crash when backing out of the `TransformerActivity` in the demo because the surface can be destroyed before the transformer has fully canceled.

Also clarify naming of the outputSurface and inline the private method that created `EGLSurface`s (it was shorter after removing the debug preview).

PiperOrigin-RevId: 449963440
2022-05-24 11:03:09 +01:00
andrewlewis
dcb58c767c Tidy releasing FrameProcessorChain
PiperOrigin-RevId: 449238525
2022-05-24 10:52:33 +01:00
andrewlewis
0e2bb8c8bd Update stale bug reference.
The old reference was just for prototyping HDR. The new reference is for planned work to use the correct formats for input and output for HDR editing in GL.

PiperOrigin-RevId: 449211792
2022-05-24 10:48:57 +01:00
hschlueter
d59186e53c Combine multiple matrix transformations in one shader.
When using a MatrixTransformationFrameProcessor per transformation
matrix, each frame processor's shader applies the matrix to the
vertices and clips the result to the NDC range when drawing the
output frame.
This change combines consecutive MatrixTransformations into a single
MatrixTransformationFrameProcessor by multiplying the individual
matrices while updating and clipping the visible polygon after
each matrix and mapping the resulting visible polygon back to the
input space so that its vertices and the combined transformation
matrix can be used in the shader.

PiperOrigin-RevId: 448521068
2022-05-24 10:44:15 +01:00
samrobinson
d72ffe4ba1 Expose decoder name to analysis files.
PiperOrigin-RevId: 447950623
2022-05-24 10:29:06 +01:00
samrobinson
f8f1a4d1ed Expose the codec name to the analysis files.
PiperOrigin-RevId: 447724152
2022-05-10 17:52:05 +01:00
hschlueter
63dcdf5803 Add listener for FrameProcessingExceptions.
This listener replaces
FrameProcessorChain#getAndRethrowBackgroundExceptions.
The listener uses a new exception type FrameProcessingException
separate from TransformationException as the frame processing
components will be made reusable outside of transformer soon.

PiperOrigin-RevId: 447455746
2022-05-10 17:47:22 +01:00
hschlueter
2e544224c2 Fix GlUtil vector size constant name.
This constant is used for https://docs.gl/es2/glVertexAttribPointer
which takes the number of components per generic vertex attribute
(meaning the size of the individual coordinate vectors here) not the
number of attributes (the number of vertices that the old constant
name referred to).

PiperOrigin-RevId: 447427241
2022-05-10 17:42:39 +01:00
samrobinson
ff7629aba5 Match the suggested bitrate to the actual Kush Gauge formula.
As defined in Kush Amerasinghe's paper 'H.264 For the rest of us'.

PiperOrigin-RevId: 446988272
2022-05-09 11:05:43 +01:00
huangdarwin
e60ba54ddf Transformer GL: Remove obsolete TODOs.
We won't try to provide/rethrow helpful error messages that are already
provided by GL, as this sort of task would expand into writing a GL verifier.
A Gl verifier is unnecessarily complex for minimal payoff, especially as Apps
expected to read GL error messages would mostly be those writing custom
GlFrameProcessors, who should be already be familiar with reading GL error
messages anyways.

PiperOrigin-RevId: 446950837
2022-05-09 11:04:05 +01:00
hschlueter
e9919f6da1 Remove redundant attribute from matrix transformation vertex shader.
The texture coordinates can be derived from the frame coordinates.

PiperOrigin-RevId: 446770538
2022-05-09 11:01:33 +01:00
hschlueter
4b8ff72d30 Use MatrixTransformation instead of wrapping its GlFrameProcssor.
ScaleToFitFrameProcessor, PresentationFrameProcessor,
and EncoderCompatibilityFrameProcessor now each implement
MatrixTransformation instead of wrapping
MatrixTransformationFrameProcessor.

PiperOrigin-RevId: 446480286
2022-05-09 10:58:56 +01:00
hschlueter
c94035278c Separate matrix effect specification and implementation.
This change splits AdvancedFrameProcessor into 4 files:
- MatrixTransformationFrameProcessor for the GlFrameProcessor
  implementation
- MatrixTransformation and GlMatrixTransformation for the GlEffect
  specification
- MatrixUtils for the static matrix helpers

PiperOrigin-RevId: 446236384
2022-05-09 10:51:14 +01:00
hschlueter
b410a922fe Introduce GlEffect interface for effect specification.
PiperOrigin-RevId: 446143537
2022-05-09 10:44:30 +01:00
hschlueter
3869c0a851 Return recommended output size for FrameProcessorChain.
Also add warning for what can happen if this is ignored.

Previously the return value was overridden by setOutputSurface, now
setOutputSurface only overrides the values using internally.

PiperOrigin-RevId: 445377036
2022-05-09 10:38:32 +01:00
huangdarwin
0de9955eb2 Transformer: Misc nits
* Add a /* paramName= */ comment
* Remove an unnecessary comma.
* Remove extra "internal " for a b/### link

PiperOrigin-RevId: 445169649
2022-05-09 10:30:18 +01:00
huangdarwin
0f3e63909c Transformer: Restrict frame buffer size for all omx decoders API >= 29.
PiperOrigin-RevId: 445119411
2022-05-09 10:27:58 +01:00
huangdarwin
f269963e89 Transformer GL: Add support for pixelWidthHeightRatio.
To ensure frame processor operations operate on square pixels,
make the frame taller or wider for non-square input pixels.

In addition to automated tests, this was tested by changing the
inputFormat.pixelWidthHeightRatio in the TransformerVideoRenderer.

PiperOrigin-RevId: 444553517
2022-05-09 10:11:18 +01:00
huangdarwin
f1cda5fe2a FrameProcessor: Avoid early rounding in Presentation output dimensions.
PiperOrigin-RevId: 444253425
2022-04-25 14:38:17 +01:00
hschlueter
02743456a0 Use last frame processor to draw on debug surface view.
The last frame processor could use a different drawing command
than a four vertex triangle strip. So we need call its drawing
method again instead of assuming the shape.

PiperOrigin-RevId: 444217274
2022-04-26 15:04:33 +01:00
huangdarwin
36d190bb66 Transformer GL: Avoid no-op ScaleToFit / Presentation FrameProcessors
Avoid no-op FrameProcessors in VideoTranscodingSamplePipeline, to avoid
creating resources for and executing GL for a no-op vertex+fragment shader.

EncoderCompatibilityFrameProcessor will still always be exercised.

PiperOrigin-RevId: 443675833
2022-04-26 15:03:22 +01:00
andrewlewis
0a378a4555 Fix encoder configuration before API 25
Float I-frame intervals are only supported from API 25 onwards (see https://developer.android.com/reference/android/media/MediaFormat#KEY_I_FRAME_INTERVAL).

Setting a null value for profile/level can cause a native crash when configuring the decoder.

PiperOrigin-RevId: 443647924
2022-04-26 14:59:44 +01:00
huangdarwin
3cfdfb41c6 FrameProcessor: Create EncoderCompatibilityFrameProcessor.
Split rotationDegrees changes to EncoderCompatibilityFrameProcessor, a new
FrameProcessor.

This removes automatic rotationDegrees adjustments from Presentation, which
allows Presentation to be used for changes before the end of a
FrameProcessorChain pipeline.

PiperOrigin-RevId: 443387226
2022-04-26 14:57:40 +01:00
andrewlewis
27c1876c9f Expand Samsung/1+ workaround to API 31 + 32
The issue with decoding getting stuck is still reproducible on `samsung/beyond1lteeea/beyond1:12/SP1A.210812.016/G973FXXUEGULB:user/release-keys`.

PiperOrigin-RevId: 443368546
2022-04-26 14:55:39 +01:00
claincly
f903e4a9f8 Apply resolution fix.
Some devices under report their resolution support, like 2144 for 2160 in
H265, 1072 for 1080 in H264. This CL only takes care of these two cases,

- reporting 1920x1080 is supported when the device reports 1920x1072, and
- reporting 3840x2160 is supported when the device reports 3840x2144

PiperOrigin-RevId: 443095042
2022-04-26 14:50:35 +01:00
huangdarwin
7f7e84bee3 FrameProcessor: Improve PresentationFrameProcessor javadocs.
PiperOrigin-RevId: 442835160
2022-04-26 14:47:21 +01:00
hschlueter
5248bbb882 Add context param to GlFrameProcessor initialize().
PiperOrigin-RevId: 442826391
2022-04-26 14:46:24 +01:00
hschlueter
afa551ab8f Block until FrameProcessorChain is released.
This is safer because it will prevent any future problems with
creating a new FrameProcessorChain before the previous one has
completed its async release.

From [eglDestroyContext documentation](https://www.khronos.org/registry/EGL/sdk/docs/man/html/eglDestroyContext.xhtml):
"If the EGL rendering context is not current to any thread,
eglDestroyContext destroys it immediately."
The context isn't current to any thread here because GlUtil calls
eglMakeCurrent with EGL_NO_CONTEXT before calling eglDestroyContext.
So everthing should be released once the FrameProcessorChain's
release task terminates.

PiperOrigin-RevId: 442807484
2022-04-26 14:45:31 +01:00
claincly
7a67609561 Add checks for device capability in tests.
PiperOrigin-RevId: 442751310
2022-04-26 14:42:31 +01:00
huangdarwin
3f4d03e731 FrameProcessor: Add checks to ensure width and height are positive.
Negative and zero values should be disallowed.

PiperOrigin-RevId: 441757246
2022-04-26 14:39:29 +01:00
hschlueter
22e016e851 Clarify TransformationRequest setResolution javadoc.
Scaling and rotation using ScaleToFitFrameProcessor may change the
the resolution and aspect ratio, so defaulting to the same as the
input is no longer accurate.

PiperOrigin-RevId: 441463349
2022-04-26 14:35:12 +01:00
hschlueter
f25c912c72 Rename GlFrameProcessor updateProgramAndDraw to drawFrame.
What a minimal implementation should include is now explained in the
interface javadoc while the method name reflects what the method does.

PiperOrigin-RevId: 441432059
2022-04-26 14:34:11 +01:00