427 Commits

Author SHA1 Message Date
samrobinson
a36967c19b Move Encoder quality API to VideoEncoderSettings.
Some other minor nits and adjustments to the API logic.

PiperOrigin-RevId: 459490431
2022-07-07 18:26:35 +00:00
huangdarwin
4230ea94e9 HDR: Remove ColorInfo.SDR constant
The SDR constant also specified a color space and range, in addition to
C.COLOR_TRANSFER_SDR. However, it turns out that SDR videos may use different color
space and range values, so following prior ExoPlayer conventions to have `null`
mean "generic SDR" is preferable here.

PiperOrigin-RevId: 459296746
2022-07-07 18:15:38 +00:00
huangdarwin
77d353b58b HDR: Throw error if attempting HDR editing under API 31.
HDR editing is not supported under API 31

PiperOrigin-RevId: 459211106
2022-07-07 18:08:47 +00:00
huangdarwin
bbbb009608 HDR: Remove unused EGL_GL_COLORSPACE_KHR attribute.
PiperOrigin-RevId: 459106221
2022-07-07 17:58:02 +00:00
samrobinson
d5b02e7584 Implement device based encoder bitrate mapping.
This feature is disabled by default for now.

PiperOrigin-RevId: 458932471
2022-07-07 17:54:40 +00:00
hschlueter
474e2f2c77 Fallback to SDR if encoder doesn't support HDR (HLG only).
If the input is HDR (HLG), check encoder capabilities for HDR support
and request tone-mapping to SDR during decoder configuration otherwise.
Capabilities are only checked for API 31 and above, as HDR editing is
not supported before.

As the encoder capabilities check needs to happen before selecting the
encoder to use (as this may depend on the resolution output by the
effects chain), the EncoderWrapper checks all candidate encoders
for the MIME type for HDR capabilities and only requests fallback to
SDR if none of them support it.

When the actual encoder is selected, the wrapper checks that it matches
one of the encoders is checked capabilities for.

PiperOrigin-RevId: 458511599
2022-07-07 17:47:46 +00:00
huangdarwin
53db305612 HDR: Configure GL shaders and encoder.
Configure the GL shaders and encoder to take in HDR metadata.

This mostly just consists of passing the Format.colorInfo through
the VideoTranscodingSamplePipeline down to the encoder, rather than passing
the PQ-ness down to the GL step.

Due to b/237674316, this will remove HDR10+ support temporarily to introduce
support for HLG10.

Manually tested to confirm that HLG10 operations that don't affect color display
correctly after this CL with "HDR editing" in the demo checked, and continue to display incorrectly (as before this CL) without the option unchecked.

PiperOrigin-RevId: 458490810
2022-07-07 17:44:14 +00:00
claincly
2b6f62b2a1 Fix error in frame rate handling.
The old getString() will throw because FRAME_RATE can only be float or int.

PiperOrigin-RevId: 458481251
2022-07-07 17:40:55 +00:00
claincly
8f89eba59c Find only REGULAR_CODECS in EncoderUtil.
We used "ALL_COOECS" previously, and it is not necessary because "ALL_CODECS"
additionally the codecs that support tunneling/secure decoding, which there
is no use case in Transformer.

PiperOrigin-RevId: 458470278
2022-07-07 17:34:12 +00:00
claincly
821ab26702 Round the frame rate in MediaFormat
Although MediaCodec claims supporting float frame rate, encoder init failed on
API21 Nexus 5. Since it's just a performance hint to the codec, it's OK to
generalize it to other API versions.

PiperOrigin-RevId: 458434650
2022-07-07 17:30:49 +00:00
hschlueter
f41e6796ce Move DebugViewProvider out of Transformer class.
The GlEffectsFrameProcessor that will be part of the effects module
uses the DebugViewProvider. So it does not make sense for it
to be an inner interface of Transformer.

PiperOrigin-RevId: 458014932
2022-07-07 17:16:30 +00:00
hschlueter
e5527a8add FrameProcessor: Replace SurfaceInfo.Provider with setter.
The FinalMatrixTransformationProcessorWrapper ensures that the
surface is only replaced when it is not being rendered to and vice
versa.

PiperOrigin-RevId: 458007639
2022-07-07 17:12:50 +00:00
hschlueter
c74cf1f1aa Fix outputHeight pass-through condition.
The outputHeight in the TransformationRequest is the height of
the frame as it would be displayed (i.e., after applying any
rotation specified in the format). So pass-through should only
be used if the requested outputHeight matches the input
format's height after applying the rotation.

PiperOrigin-RevId: 457934867
2022-07-07 17:02:56 +00:00
hschlueter
bfa663d2b1 Allow changing input pixelWidthHeightRatio for GlEffectsFrameProcessor.
pixelWidthHeightRatio is now passed to setInputFrameInfo instead of
the factory.

PiperOrigin-RevId: 457696703
2022-07-07 16:53:01 +00:00
hschlueter
20d220193e Rename setVideoFrameEffects to setVideoEffects.
PiperOrigin-RevId: 457023382
2022-06-27 12:03:04 +01:00
hschlueter
a230d59f1b Allow FrameProcessor input surface size changes.
This will be useful for downgrading to a lower resolution during
a slow preview and for processing slide-shows once sequential
multi-asset editing is supported.

PiperOrigin-RevId: 457017255
2022-06-27 11:59:48 +01:00
hschlueter
1b5dd92dec Extract FrameProcessor interface from GlEffectsFrameProcessor.
PiperOrigin-RevId: 456814150
2022-06-27 11:53:24 +01:00
hschlueter
d9c63c1e87 Disable flaky transformer emulator test on API 31.
videoEncoderFormatUnsupported_completesWithError() has recently
been flaky on API 31 emulators on presubmit because a different
exception than the expected exception is thrown.
This disables it on those emulators to reduce testing noise
until the underlying problem is investigated and resolved.

PiperOrigin-RevId: 456765512
2022-06-27 11:50:05 +01:00
hschlueter
216fefd669 Rename FrameProcessorChain to GlEffectsFrameProcessor.
This change is just renaming. There is no functional change intended.
The FrameProcessor interface will be created in a follow-up.

PiperOrigin-RevId: 456741628
2022-06-27 11:43:32 +01:00
samrobinson
19bdff96ba Add a Builder for DefaultEncoderFactory.
PiperOrigin-RevId: 456728032
2022-06-27 11:40:04 +01:00
hschlueter
e25bf81195 Use GlTextureProcessor to avoid redundant copy in MediaPipeProcessor.
After this change GlEffects can use any GlTextureProcessor not just
SingleFrameGlTextureProcessor.
MediaPipeProcessor now implements GlTextureProcessor directly which
allows it to reuse MediaPipe's output texture for its output texture
and avoids an extra copy shader step.

PiperOrigin-RevId: 456530718
2022-06-27 11:33:30 +01:00
hschlueter
3a96691654 Support chaining async GlTextureProcessors in FrameProcessorChain.
After this change, FrameProcessorChain chains any GlTextureProcessors
instead of only SingleFrameGlTextureProcessors.

The GlTextureProcessors are chained in a bidirectional manner using
ChainingGlTextureProcessorListener to feed input and output related
events forward and release events backwards.

PiperOrigin-RevId: 456478414
2022-06-27 11:30:18 +01:00
huangdarwin
d1357e8b59 FrameProcessor: Use factories instead of a builder for Presentation.
PiperOrigin-RevId: 456064021
2022-06-27 11:20:18 +01:00
hschlueter
c92e18ec58 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
2022-06-27 11:13:25 +01:00
hschlueter
bf9fa12411 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
2022-06-16 11:27:18 +00:00
hschlueter
10050a1e8c Replace FrameProcessorChain#isEnded with listener method.
PiperOrigin-RevId: 455114693
2022-06-15 15:15:02 +00:00
hschlueter
d20f684986 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
2022-06-15 15:11:31 +00:00
hschlueter
3f718b0d10 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
2022-06-09 18:41:03 +00:00
hschlueter
dc668f2b59 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
2022-06-09 18:37:29 +00:00
claincly
fa22efb705 Ensure re-encode on performance tests
PiperOrigin-RevId: 453933854
2022-06-09 17:18:25 +00:00
huangdarwin
b33dc5e57b 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
2022-06-09 17:07:18 +00:00
hschlueter
d5e4faa9ef Mention alpha for matrix transformation background color.
PiperOrigin-RevId: 453633920
2022-06-09 17:00:03 +00:00
hschlueter
0b37d860d1 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
2022-06-09 16:56:11 +00:00
hschlueter
023d19c8c5 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
2022-06-07 10:37:40 +00:00
hschlueter
960422e36f 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
2022-06-07 10:27:55 +00:00
hschlueter
54d44d38b6 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
2022-05-31 11:02:40 +00:00
claincly
d411461dfa Skip BitrateAnalysisTest if device is incapable.
Add bitrate check to the "can encode" criteria.

PiperOrigin-RevId: 451868042
2022-05-30 17:57:29 +00:00
andrewlewis
84efc5e8d0 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 17:47:03 +00:00
samrobinson
38720a6b6d Treat pixels as unsigned and correct pixel count division.
PiperOrigin-RevId: 451428202
2022-05-30 17:40:06 +00:00
huangdarwin
983e074fc9 Transformer: Add 8k24fps transform test.
Most devices won't support 8k decoding, so they'll skip this test entirely.

As the video is quite short, this test shouldn't be any longer than the nearby,
long-running 4k60 test.

PiperOrigin-RevId: 451423368
2022-05-30 17:36:38 +00:00
samrobinson
1becb45c62 Clarify variables and improve documentation of SSIM.
PiperOrigin-RevId: 451392021
2022-05-30 17:33:05 +00:00
samrobinson
a96dd2d43e Use updated test name in BUILD and docs.
PiperOrigin-RevId: 451384408
2022-05-30 17:29:11 +00:00
hschlueter
6b521b2952 Use video passthrough if clipping starts at key frame.
PiperOrigin-RevId: 451380267
2022-05-30 17:22:16 +00:00
hschlueter
89e239eed1 Expand SSIM skipping to all Nexus API 21 devices.
PiperOrigin-RevId: 451371681
2022-05-30 17:18:46 +00:00
huangdarwin
14fc3179fb 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 17:15:25 +00:00
hschlueter
541460a01d 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 17:11:57 +00:00
hschlueter
d37cf34131 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 17:01:17 +00:00
hschlueter
2b4642f663 Skip SSIM calculation on Nexus 5 API 21.
There is a problem with the ImageReader formats used by the
SSIM helper that only occurs for Nexus 5 API 21, so as a workaround
we can skip the SSIM calculation on Nexus 5 API 21.

This skips just the SSIM calculation (by setting the value to
1.0 instead and logging). The tests still run when SSIM is skipped
so that we can detect other failures.

PiperOrigin-RevId: 450903183
2022-05-26 13:04:03 +00:00
hschlueter
52ad75c0a4 Replace 640x360 H264 test video with 320x240 H264 video.
Decoding and encoding 320x240 H264 video should be supported
on all devices from Android 5.0 based on CDD requirements.
https://source.android.com/compatibility/5.0/android-5.0-cdd#5_2_video_encoding

640x360 encoding doesn't seem to be supported on Nexus 5.

PiperOrigin-RevId: 450901715
2022-05-26 13:00:27 +00:00
hschlueter
066327daf9 Skip transform4K60 test if 4K decoding is not supported.
4K decoding is not supported (not required to be supported) on all
devices, e.g., Nexus 5 does not support it.

PiperOrigin-RevId: 450682519
2022-05-26 12:49:39 +00:00