mirror of
https://github.com/androidx/media.git
synced 2025-05-12 18:19:50 +08:00
HDR: Put force HDR as SDR into AssetLoader
This allows us to fix usage of HDR_MODE_EXPERIMENTAL_FORCE_INTERPRET_HDR_AS_SDR. Before, this was checked in the VideoSamplePipeline, which no longer decides on the decoder configuration input format. PiperOrigin-RevId: 510142097
This commit is contained in:
parent
221c5afb1b
commit
fb8bbce5f1
@ -34,6 +34,7 @@ public final class DefaultAssetLoaderFactory implements AssetLoader.Factory {
|
|||||||
|
|
||||||
private final Context context;
|
private final Context context;
|
||||||
private final Codec.DecoderFactory decoderFactory;
|
private final Codec.DecoderFactory decoderFactory;
|
||||||
|
private final boolean forceInterpretHdrAsSdr;
|
||||||
private final Clock clock;
|
private final Clock clock;
|
||||||
private final MediaSource.@MonotonicNonNull Factory mediaSourceFactory;
|
private final MediaSource.@MonotonicNonNull Factory mediaSourceFactory;
|
||||||
|
|
||||||
@ -45,13 +46,19 @@ public final class DefaultAssetLoaderFactory implements AssetLoader.Factory {
|
|||||||
* @param context The {@link Context}.
|
* @param context The {@link Context}.
|
||||||
* @param decoderFactory The {@link Codec.DecoderFactory} to use to decode the samples (if
|
* @param decoderFactory The {@link Codec.DecoderFactory} to use to decode the samples (if
|
||||||
* necessary).
|
* necessary).
|
||||||
|
* @param forceInterpretHdrAsSdr Whether to apply {@link
|
||||||
|
* TransformationRequest#HDR_MODE_EXPERIMENTAL_FORCE_INTERPRET_HDR_AS_SDR}.
|
||||||
* @param clock The {@link Clock} to use. It should always be {@link Clock#DEFAULT}, except for
|
* @param clock The {@link Clock} to use. It should always be {@link Clock#DEFAULT}, except for
|
||||||
* testing.
|
* testing.
|
||||||
*/
|
*/
|
||||||
public DefaultAssetLoaderFactory(
|
public DefaultAssetLoaderFactory(
|
||||||
Context context, Codec.DecoderFactory decoderFactory, Clock clock) {
|
Context context,
|
||||||
|
Codec.DecoderFactory decoderFactory,
|
||||||
|
boolean forceInterpretHdrAsSdr,
|
||||||
|
Clock clock) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.decoderFactory = decoderFactory;
|
this.decoderFactory = decoderFactory;
|
||||||
|
this.forceInterpretHdrAsSdr = forceInterpretHdrAsSdr;
|
||||||
this.clock = clock;
|
this.clock = clock;
|
||||||
this.mediaSourceFactory = null;
|
this.mediaSourceFactory = null;
|
||||||
}
|
}
|
||||||
@ -62,6 +69,8 @@ public final class DefaultAssetLoaderFactory implements AssetLoader.Factory {
|
|||||||
* @param context The {@link Context}.
|
* @param context The {@link Context}.
|
||||||
* @param decoderFactory The {@link Codec.DecoderFactory} to use to decode the samples (if
|
* @param decoderFactory The {@link Codec.DecoderFactory} to use to decode the samples (if
|
||||||
* necessary).
|
* necessary).
|
||||||
|
* @param forceInterpretHdrAsSdr Whether to apply {@link
|
||||||
|
* TransformationRequest#HDR_MODE_EXPERIMENTAL_FORCE_INTERPRET_HDR_AS_SDR}.
|
||||||
* @param clock The {@link Clock} to use. It should always be {@link Clock#DEFAULT}, except for
|
* @param clock The {@link Clock} to use. It should always be {@link Clock#DEFAULT}, except for
|
||||||
* testing.
|
* testing.
|
||||||
* @param mediaSourceFactory The {@link MediaSource.Factory} to use to retrieve the samples to
|
* @param mediaSourceFactory The {@link MediaSource.Factory} to use to retrieve the samples to
|
||||||
@ -70,10 +79,12 @@ public final class DefaultAssetLoaderFactory implements AssetLoader.Factory {
|
|||||||
public DefaultAssetLoaderFactory(
|
public DefaultAssetLoaderFactory(
|
||||||
Context context,
|
Context context,
|
||||||
Codec.DecoderFactory decoderFactory,
|
Codec.DecoderFactory decoderFactory,
|
||||||
|
boolean forceInterpretHdrAsSdr,
|
||||||
Clock clock,
|
Clock clock,
|
||||||
MediaSource.Factory mediaSourceFactory) {
|
MediaSource.Factory mediaSourceFactory) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.decoderFactory = decoderFactory;
|
this.decoderFactory = decoderFactory;
|
||||||
|
this.forceInterpretHdrAsSdr = forceInterpretHdrAsSdr;
|
||||||
this.clock = clock;
|
this.clock = clock;
|
||||||
this.mediaSourceFactory = mediaSourceFactory;
|
this.mediaSourceFactory = mediaSourceFactory;
|
||||||
}
|
}
|
||||||
@ -91,8 +102,10 @@ public final class DefaultAssetLoaderFactory implements AssetLoader.Factory {
|
|||||||
if (exoPlayerAssetLoaderFactory == null) {
|
if (exoPlayerAssetLoaderFactory == null) {
|
||||||
exoPlayerAssetLoaderFactory =
|
exoPlayerAssetLoaderFactory =
|
||||||
mediaSourceFactory != null
|
mediaSourceFactory != null
|
||||||
? new ExoPlayerAssetLoader.Factory(context, decoderFactory, clock, mediaSourceFactory)
|
? new ExoPlayerAssetLoader.Factory(
|
||||||
: new ExoPlayerAssetLoader.Factory(context, decoderFactory, clock);
|
context, decoderFactory, forceInterpretHdrAsSdr, clock, mediaSourceFactory)
|
||||||
|
: new ExoPlayerAssetLoader.Factory(
|
||||||
|
context, decoderFactory, forceInterpretHdrAsSdr, clock);
|
||||||
}
|
}
|
||||||
return exoPlayerAssetLoaderFactory.createAssetLoader(editedMediaItem, looper, listener);
|
return exoPlayerAssetLoaderFactory.createAssetLoader(editedMediaItem, looper, listener);
|
||||||
}
|
}
|
||||||
|
@ -135,6 +135,11 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Overrides the {@code inputFormat}. */
|
||||||
|
protected Format overrideFormat(Format inputFormat) throws ExportException {
|
||||||
|
return inputFormat;
|
||||||
|
}
|
||||||
|
|
||||||
/** Called when the {@link Format} of the samples fed to the renderer is known. */
|
/** Called when the {@link Format} of the samples fed to the renderer is known. */
|
||||||
protected void onInputFormatRead(Format inputFormat) {}
|
protected void onInputFormatRead(Format inputFormat) {}
|
||||||
|
|
||||||
@ -176,7 +181,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
|||||||
if (result != C.RESULT_FORMAT_READ) {
|
if (result != C.RESULT_FORMAT_READ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Format inputFormat = checkNotNull(formatHolder.format);
|
Format inputFormat = overrideFormat(checkNotNull(formatHolder.format));
|
||||||
@AssetLoader.SupportedOutputTypes
|
@AssetLoader.SupportedOutputTypes
|
||||||
int supportedOutputTypes = SUPPORTED_OUTPUT_TYPE_ENCODED | SUPPORTED_OUTPUT_TYPE_DECODED;
|
int supportedOutputTypes = SUPPORTED_OUTPUT_TYPE_ENCODED | SUPPORTED_OUTPUT_TYPE_DECODED;
|
||||||
sampleConsumer =
|
sampleConsumer =
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
package androidx.media3.transformer;
|
package androidx.media3.transformer;
|
||||||
|
|
||||||
import static androidx.media3.common.util.Assertions.checkNotNull;
|
import static androidx.media3.common.util.Assertions.checkNotNull;
|
||||||
|
import static androidx.media3.common.util.Util.SDK_INT;
|
||||||
|
|
||||||
import android.media.MediaCodec;
|
import android.media.MediaCodec;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
@ -35,6 +36,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
|||||||
|
|
||||||
private final boolean flattenForSlowMotion;
|
private final boolean flattenForSlowMotion;
|
||||||
private final Codec.DecoderFactory decoderFactory;
|
private final Codec.DecoderFactory decoderFactory;
|
||||||
|
private final boolean forceInterpretHdrAsSdr;
|
||||||
private final List<Long> decodeOnlyPresentationTimestamps;
|
private final List<Long> decodeOnlyPresentationTimestamps;
|
||||||
|
|
||||||
private @MonotonicNonNull SefSlowMotionFlattener sefVideoSlowMotionFlattener;
|
private @MonotonicNonNull SefSlowMotionFlattener sefVideoSlowMotionFlattener;
|
||||||
@ -43,11 +45,13 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
|||||||
public ExoAssetLoaderVideoRenderer(
|
public ExoAssetLoaderVideoRenderer(
|
||||||
boolean flattenForSlowMotion,
|
boolean flattenForSlowMotion,
|
||||||
Codec.DecoderFactory decoderFactory,
|
Codec.DecoderFactory decoderFactory,
|
||||||
|
boolean forceInterpretHdrAsSdr,
|
||||||
TransformerMediaClock mediaClock,
|
TransformerMediaClock mediaClock,
|
||||||
AssetLoader.Listener assetLoaderListener) {
|
AssetLoader.Listener assetLoaderListener) {
|
||||||
super(C.TRACK_TYPE_VIDEO, mediaClock, assetLoaderListener);
|
super(C.TRACK_TYPE_VIDEO, mediaClock, assetLoaderListener);
|
||||||
this.flattenForSlowMotion = flattenForSlowMotion;
|
this.flattenForSlowMotion = flattenForSlowMotion;
|
||||||
this.decoderFactory = decoderFactory;
|
this.decoderFactory = decoderFactory;
|
||||||
|
this.forceInterpretHdrAsSdr = forceInterpretHdrAsSdr;
|
||||||
decodeOnlyPresentationTimestamps = new ArrayList<>();
|
decodeOnlyPresentationTimestamps = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,6 +60,23 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
|||||||
return TAG;
|
return TAG;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Format overrideFormat(Format inputFormat) throws ExportException {
|
||||||
|
if (forceInterpretHdrAsSdr && ColorInfo.isTransferHdr(inputFormat.colorInfo)) {
|
||||||
|
if (SDK_INT < 29) {
|
||||||
|
throw ExportException.createForCodec(
|
||||||
|
new IllegalArgumentException(
|
||||||
|
"Interpreting HDR video as SDR is not supported on this device."),
|
||||||
|
ExportException.ERROR_CODE_DECODING_FORMAT_UNSUPPORTED,
|
||||||
|
/* isVideo= */ true,
|
||||||
|
/* isDecoder= */ true,
|
||||||
|
inputFormat);
|
||||||
|
}
|
||||||
|
return inputFormat.buildUpon().setColorInfo(ColorInfo.SDR_BT709_LIMITED).build();
|
||||||
|
}
|
||||||
|
return inputFormat;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onInputFormatRead(Format inputFormat) {
|
protected void onInputFormatRead(Format inputFormat) {
|
||||||
if (flattenForSlowMotion) {
|
if (flattenForSlowMotion) {
|
||||||
|
@ -64,6 +64,7 @@ public final class ExoPlayerAssetLoader implements AssetLoader {
|
|||||||
|
|
||||||
private final Context context;
|
private final Context context;
|
||||||
private final Codec.DecoderFactory decoderFactory;
|
private final Codec.DecoderFactory decoderFactory;
|
||||||
|
private final boolean forceInterpretHdrAsSdr;
|
||||||
private final Clock clock;
|
private final Clock clock;
|
||||||
@Nullable private final MediaSource.Factory mediaSourceFactory;
|
@Nullable private final MediaSource.Factory mediaSourceFactory;
|
||||||
|
|
||||||
@ -73,12 +74,19 @@ public final class ExoPlayerAssetLoader implements AssetLoader {
|
|||||||
* @param context The {@link Context}.
|
* @param context The {@link Context}.
|
||||||
* @param decoderFactory The {@link Codec.DecoderFactory} to use to decode the samples (if
|
* @param decoderFactory The {@link Codec.DecoderFactory} to use to decode the samples (if
|
||||||
* necessary).
|
* necessary).
|
||||||
|
* @param forceInterpretHdrAsSdr Whether to apply {@link
|
||||||
|
* TransformationRequest#HDR_MODE_EXPERIMENTAL_FORCE_INTERPRET_HDR_AS_SDR}.
|
||||||
* @param clock The {@link Clock} to use. It should always be {@link Clock#DEFAULT}, except for
|
* @param clock The {@link Clock} to use. It should always be {@link Clock#DEFAULT}, except for
|
||||||
* testing.
|
* testing.
|
||||||
*/
|
*/
|
||||||
public Factory(Context context, Codec.DecoderFactory decoderFactory, Clock clock) {
|
public Factory(
|
||||||
|
Context context,
|
||||||
|
Codec.DecoderFactory decoderFactory,
|
||||||
|
boolean forceInterpretHdrAsSdr,
|
||||||
|
Clock clock) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.decoderFactory = decoderFactory;
|
this.decoderFactory = decoderFactory;
|
||||||
|
this.forceInterpretHdrAsSdr = forceInterpretHdrAsSdr;
|
||||||
this.clock = clock;
|
this.clock = clock;
|
||||||
this.mediaSourceFactory = null;
|
this.mediaSourceFactory = null;
|
||||||
}
|
}
|
||||||
@ -89,6 +97,8 @@ public final class ExoPlayerAssetLoader implements AssetLoader {
|
|||||||
* @param context The {@link Context}.
|
* @param context The {@link Context}.
|
||||||
* @param decoderFactory The {@link Codec.DecoderFactory} to use to decode the samples (if
|
* @param decoderFactory The {@link Codec.DecoderFactory} to use to decode the samples (if
|
||||||
* necessary).
|
* necessary).
|
||||||
|
* @param forceInterpretHdrAsSdr Whether to apply {@link
|
||||||
|
* TransformationRequest#HDR_MODE_EXPERIMENTAL_FORCE_INTERPRET_HDR_AS_SDR}.
|
||||||
* @param clock The {@link Clock} to use. It should always be {@link Clock#DEFAULT}, except for
|
* @param clock The {@link Clock} to use. It should always be {@link Clock#DEFAULT}, except for
|
||||||
* testing.
|
* testing.
|
||||||
* @param mediaSourceFactory The {@link MediaSource.Factory} to use to retrieve the samples to
|
* @param mediaSourceFactory The {@link MediaSource.Factory} to use to retrieve the samples to
|
||||||
@ -97,10 +107,12 @@ public final class ExoPlayerAssetLoader implements AssetLoader {
|
|||||||
public Factory(
|
public Factory(
|
||||||
Context context,
|
Context context,
|
||||||
Codec.DecoderFactory decoderFactory,
|
Codec.DecoderFactory decoderFactory,
|
||||||
|
boolean forceInterpretHdrAsSdr,
|
||||||
Clock clock,
|
Clock clock,
|
||||||
MediaSource.Factory mediaSourceFactory) {
|
MediaSource.Factory mediaSourceFactory) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.decoderFactory = decoderFactory;
|
this.decoderFactory = decoderFactory;
|
||||||
|
this.forceInterpretHdrAsSdr = forceInterpretHdrAsSdr;
|
||||||
this.clock = clock;
|
this.clock = clock;
|
||||||
this.mediaSourceFactory = mediaSourceFactory;
|
this.mediaSourceFactory = mediaSourceFactory;
|
||||||
}
|
}
|
||||||
@ -117,7 +129,14 @@ public final class ExoPlayerAssetLoader implements AssetLoader {
|
|||||||
mediaSourceFactory = new DefaultMediaSourceFactory(context, defaultExtractorsFactory);
|
mediaSourceFactory = new DefaultMediaSourceFactory(context, defaultExtractorsFactory);
|
||||||
}
|
}
|
||||||
return new ExoPlayerAssetLoader(
|
return new ExoPlayerAssetLoader(
|
||||||
context, editedMediaItem, mediaSourceFactory, decoderFactory, looper, listener, clock);
|
context,
|
||||||
|
editedMediaItem,
|
||||||
|
mediaSourceFactory,
|
||||||
|
decoderFactory,
|
||||||
|
forceInterpretHdrAsSdr,
|
||||||
|
looper,
|
||||||
|
listener,
|
||||||
|
clock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,6 +151,7 @@ public final class ExoPlayerAssetLoader implements AssetLoader {
|
|||||||
EditedMediaItem editedMediaItem,
|
EditedMediaItem editedMediaItem,
|
||||||
MediaSource.Factory mediaSourceFactory,
|
MediaSource.Factory mediaSourceFactory,
|
||||||
Codec.DecoderFactory decoderFactory,
|
Codec.DecoderFactory decoderFactory,
|
||||||
|
boolean forceInterpretHdrAsSdr,
|
||||||
Looper looper,
|
Looper looper,
|
||||||
Listener listener,
|
Listener listener,
|
||||||
Clock clock) {
|
Clock clock) {
|
||||||
@ -161,6 +181,7 @@ public final class ExoPlayerAssetLoader implements AssetLoader {
|
|||||||
editedMediaItem.removeVideo,
|
editedMediaItem.removeVideo,
|
||||||
editedMediaItem.flattenForSlowMotion,
|
editedMediaItem.flattenForSlowMotion,
|
||||||
this.decoderFactory,
|
this.decoderFactory,
|
||||||
|
forceInterpretHdrAsSdr,
|
||||||
listener))
|
listener))
|
||||||
.setMediaSourceFactory(mediaSourceFactory)
|
.setMediaSourceFactory(mediaSourceFactory)
|
||||||
.setTrackSelector(trackSelector)
|
.setTrackSelector(trackSelector)
|
||||||
@ -223,6 +244,7 @@ public final class ExoPlayerAssetLoader implements AssetLoader {
|
|||||||
private final boolean removeVideo;
|
private final boolean removeVideo;
|
||||||
private final boolean flattenForSlowMotion;
|
private final boolean flattenForSlowMotion;
|
||||||
private final Codec.DecoderFactory decoderFactory;
|
private final Codec.DecoderFactory decoderFactory;
|
||||||
|
private final boolean forceInterpretHdrAsSdr;
|
||||||
private final Listener assetLoaderListener;
|
private final Listener assetLoaderListener;
|
||||||
|
|
||||||
public RenderersFactoryImpl(
|
public RenderersFactoryImpl(
|
||||||
@ -230,11 +252,13 @@ public final class ExoPlayerAssetLoader implements AssetLoader {
|
|||||||
boolean removeVideo,
|
boolean removeVideo,
|
||||||
boolean flattenForSlowMotion,
|
boolean flattenForSlowMotion,
|
||||||
Codec.DecoderFactory decoderFactory,
|
Codec.DecoderFactory decoderFactory,
|
||||||
|
boolean forceInterpretHdrAsSdr,
|
||||||
Listener assetLoaderListener) {
|
Listener assetLoaderListener) {
|
||||||
this.removeAudio = removeAudio;
|
this.removeAudio = removeAudio;
|
||||||
this.removeVideo = removeVideo;
|
this.removeVideo = removeVideo;
|
||||||
this.flattenForSlowMotion = flattenForSlowMotion;
|
this.flattenForSlowMotion = flattenForSlowMotion;
|
||||||
this.decoderFactory = decoderFactory;
|
this.decoderFactory = decoderFactory;
|
||||||
|
this.forceInterpretHdrAsSdr = forceInterpretHdrAsSdr;
|
||||||
this.assetLoaderListener = assetLoaderListener;
|
this.assetLoaderListener = assetLoaderListener;
|
||||||
mediaClock = new TransformerMediaClock();
|
mediaClock = new TransformerMediaClock();
|
||||||
}
|
}
|
||||||
@ -257,7 +281,11 @@ public final class ExoPlayerAssetLoader implements AssetLoader {
|
|||||||
if (!removeVideo) {
|
if (!removeVideo) {
|
||||||
renderers[index] =
|
renderers[index] =
|
||||||
new ExoAssetLoaderVideoRenderer(
|
new ExoAssetLoaderVideoRenderer(
|
||||||
flattenForSlowMotion, decoderFactory, mediaClock, assetLoaderListener);
|
flattenForSlowMotion,
|
||||||
|
decoderFactory,
|
||||||
|
forceInterpretHdrAsSdr,
|
||||||
|
mediaClock,
|
||||||
|
assetLoaderListener);
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
return renderers;
|
return renderers;
|
||||||
|
@ -437,7 +437,12 @@ public final class Transformer {
|
|||||||
}
|
}
|
||||||
if (assetLoaderFactory == null) {
|
if (assetLoaderFactory == null) {
|
||||||
assetLoaderFactory =
|
assetLoaderFactory =
|
||||||
new DefaultAssetLoaderFactory(context, new DefaultDecoderFactory(context), clock);
|
new DefaultAssetLoaderFactory(
|
||||||
|
context,
|
||||||
|
new DefaultDecoderFactory(context),
|
||||||
|
/* forceInterpretHdrAsSdr= */ transformationRequest.hdrMode
|
||||||
|
== TransformationRequest.HDR_MODE_EXPERIMENTAL_FORCE_INTERPRET_HDR_AS_SDR,
|
||||||
|
clock);
|
||||||
}
|
}
|
||||||
return new Transformer(
|
return new Transformer(
|
||||||
context,
|
context,
|
||||||
|
@ -18,9 +18,7 @@ package androidx.media3.transformer;
|
|||||||
|
|
||||||
import static androidx.media3.common.ColorInfo.isTransferHdr;
|
import static androidx.media3.common.ColorInfo.isTransferHdr;
|
||||||
import static androidx.media3.common.util.Assertions.checkNotNull;
|
import static androidx.media3.common.util.Assertions.checkNotNull;
|
||||||
import static androidx.media3.common.util.Util.SDK_INT;
|
|
||||||
import static androidx.media3.transformer.EncoderUtil.getSupportedEncodersForHdrEditing;
|
import static androidx.media3.transformer.EncoderUtil.getSupportedEncodersForHdrEditing;
|
||||||
import static androidx.media3.transformer.TransformationRequest.HDR_MODE_EXPERIMENTAL_FORCE_INTERPRET_HDR_AS_SDR;
|
|
||||||
import static androidx.media3.transformer.TransformationRequest.HDR_MODE_KEEP_HDR;
|
import static androidx.media3.transformer.TransformationRequest.HDR_MODE_KEEP_HDR;
|
||||||
import static androidx.media3.transformer.TransformationRequest.HDR_MODE_TONE_MAP_HDR_TO_SDR_USING_MEDIACODEC;
|
import static androidx.media3.transformer.TransformationRequest.HDR_MODE_TONE_MAP_HDR_TO_SDR_USING_MEDIACODEC;
|
||||||
import static androidx.media3.transformer.TransformationRequest.HDR_MODE_TONE_MAP_HDR_TO_SDR_USING_OPEN_GL;
|
import static androidx.media3.transformer.TransformationRequest.HDR_MODE_TONE_MAP_HDR_TO_SDR_USING_OPEN_GL;
|
||||||
@ -87,25 +85,6 @@ import org.checkerframework.dataflow.qual.Pure;
|
|||||||
throws ExportException {
|
throws ExportException {
|
||||||
super(firstInputFormat, streamStartPositionUs, muxerWrapper);
|
super(firstInputFormat, streamStartPositionUs, muxerWrapper);
|
||||||
|
|
||||||
boolean isGlToneMapping = false;
|
|
||||||
if (isTransferHdr(firstInputFormat.colorInfo)) {
|
|
||||||
if (transformationRequest.hdrMode == HDR_MODE_EXPERIMENTAL_FORCE_INTERPRET_HDR_AS_SDR) {
|
|
||||||
if (SDK_INT < 29) {
|
|
||||||
throw ExportException.createForCodec(
|
|
||||||
new IllegalArgumentException(
|
|
||||||
"Interpreting HDR video as SDR is not supported on this device."),
|
|
||||||
ExportException.ERROR_CODE_DECODING_FORMAT_UNSUPPORTED,
|
|
||||||
/* isVideo= */ true,
|
|
||||||
/* isDecoder= */ true,
|
|
||||||
firstInputFormat);
|
|
||||||
}
|
|
||||||
firstInputFormat =
|
|
||||||
firstInputFormat.buildUpon().setColorInfo(ColorInfo.SDR_BT709_LIMITED).build();
|
|
||||||
} else if (transformationRequest.hdrMode == HDR_MODE_TONE_MAP_HDR_TO_SDR_USING_OPEN_GL) {
|
|
||||||
isGlToneMapping = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
finalFramePresentationTimeUs = C.TIME_UNSET;
|
finalFramePresentationTimeUs = C.TIME_UNSET;
|
||||||
|
|
||||||
encoderOutputBuffer =
|
encoderOutputBuffer =
|
||||||
@ -122,6 +101,9 @@ import org.checkerframework.dataflow.qual.Pure;
|
|||||||
ColorInfo encoderInputColor = encoderWrapper.getSupportedInputColor();
|
ColorInfo encoderInputColor = encoderWrapper.getSupportedInputColor();
|
||||||
// If not tone mapping using OpenGL, the decoder will output the encoderInputColor,
|
// If not tone mapping using OpenGL, the decoder will output the encoderInputColor,
|
||||||
// possibly by tone mapping.
|
// possibly by tone mapping.
|
||||||
|
boolean isGlToneMapping =
|
||||||
|
ColorInfo.isTransferHdr(firstInputFormat.colorInfo)
|
||||||
|
&& transformationRequest.hdrMode == HDR_MODE_TONE_MAP_HDR_TO_SDR_USING_OPEN_GL;
|
||||||
videoFrameProcessorInputColor =
|
videoFrameProcessorInputColor =
|
||||||
isGlToneMapping ? checkNotNull(firstInputFormat.colorInfo) : encoderInputColor;
|
isGlToneMapping ? checkNotNull(firstInputFormat.colorInfo) : encoderInputColor;
|
||||||
// For consistency with the Android platform, OpenGL tone mapping outputs colors with
|
// For consistency with the Android platform, OpenGL tone mapping outputs colors with
|
||||||
|
@ -119,7 +119,8 @@ public class ExoPlayerAssetLoaderTest {
|
|||||||
Codec.DecoderFactory decoderFactory = new DefaultDecoderFactory(context);
|
Codec.DecoderFactory decoderFactory = new DefaultDecoderFactory(context);
|
||||||
EditedMediaItem editedMediaItem =
|
EditedMediaItem editedMediaItem =
|
||||||
new EditedMediaItem.Builder(MediaItem.fromUri("asset:///media/mp4/sample.mp4")).build();
|
new EditedMediaItem.Builder(MediaItem.fromUri("asset:///media/mp4/sample.mp4")).build();
|
||||||
return new ExoPlayerAssetLoader.Factory(context, decoderFactory, clock)
|
return new ExoPlayerAssetLoader.Factory(
|
||||||
|
context, decoderFactory, /* forceInterpretHdrAsSdr= */ false, clock)
|
||||||
.createAssetLoader(editedMediaItem, looper, listener);
|
.createAssetLoader(editedMediaItem, looper, listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -802,7 +802,12 @@ public final class TransformerEndToEndTest {
|
|||||||
context, new SlowExtractorsFactory(/* delayBetweenReadsMs= */ 10));
|
context, new SlowExtractorsFactory(/* delayBetweenReadsMs= */ 10));
|
||||||
Codec.DecoderFactory decoderFactory = new DefaultDecoderFactory(context);
|
Codec.DecoderFactory decoderFactory = new DefaultDecoderFactory(context);
|
||||||
AssetLoader.Factory assetLoaderFactory =
|
AssetLoader.Factory assetLoaderFactory =
|
||||||
new ExoPlayerAssetLoader.Factory(context, decoderFactory, clock, mediaSourceFactory);
|
new ExoPlayerAssetLoader.Factory(
|
||||||
|
context,
|
||||||
|
decoderFactory,
|
||||||
|
/* forceInterpretHdrAsSdr= */ false,
|
||||||
|
clock,
|
||||||
|
mediaSourceFactory);
|
||||||
Muxer.Factory muxerFactory = new TestMuxerFactory(/* maxDelayBetweenSamplesMs= */ 1);
|
Muxer.Factory muxerFactory = new TestMuxerFactory(/* maxDelayBetweenSamplesMs= */ 1);
|
||||||
Transformer transformer =
|
Transformer transformer =
|
||||||
createTransformerBuilder(/* enableFallback= */ false)
|
createTransformerBuilder(/* enableFallback= */ false)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user