Commit 4abd34d8 by tofunmi Committed by Tofunmi Adigun-Hameed

Image transcoding: Add support for heic/heif image formats

PiperOrigin-RevId: 530578549
parent 8c6da05f
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
package com.google.android.exoplayer2.effect; package com.google.android.exoplayer2.effect;
import static com.google.android.exoplayer2.util.Assertions.checkNotNull; import static com.google.android.exoplayer2.util.Assertions.checkNotNull;
import static com.google.android.exoplayer2.util.Assertions.checkState;
import static java.lang.Math.round; import static java.lang.Math.round;
import android.graphics.Bitmap; import android.graphics.Bitmap;
...@@ -25,6 +26,7 @@ import androidx.annotation.Nullable; ...@@ -25,6 +26,7 @@ import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.util.GlTextureInfo; import com.google.android.exoplayer2.util.GlTextureInfo;
import com.google.android.exoplayer2.util.GlUtil; import com.google.android.exoplayer2.util.GlUtil;
import com.google.android.exoplayer2.util.Util;
import com.google.android.exoplayer2.util.VideoFrameProcessingException; import com.google.android.exoplayer2.util.VideoFrameProcessingException;
import java.util.Queue; import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.LinkedBlockingQueue;
...@@ -37,6 +39,9 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; ...@@ -37,6 +39,9 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
* <p>Public methods in this class can be called from any thread. * <p>Public methods in this class can be called from any thread.
*/ */
/* package */ final class BitmapTextureManager implements TextureManager { /* package */ final class BitmapTextureManager implements TextureManager {
private static final String UNSUPPORTED_IMAGE_CONFIGURATION =
"Unsupported Image Configuration: No more than 8 bits of precision should be used for each"
+ " RGB channel.";
private final GlShaderProgram shaderProgram; private final GlShaderProgram shaderProgram;
private final VideoFrameProcessingTaskExecutor videoFrameProcessingTaskExecutor; private final VideoFrameProcessingTaskExecutor videoFrameProcessingTaskExecutor;
// The queue holds all bitmaps with one or more frames pending to be sent downstream. // The queue holds all bitmaps with one or more frames pending to be sent downstream.
...@@ -123,6 +128,14 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; ...@@ -123,6 +128,14 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
private void setupBitmap( private void setupBitmap(
Bitmap bitmap, long durationUs, long offsetUs, float frameRate, boolean useHdr) Bitmap bitmap, long durationUs, long offsetUs, float frameRate, boolean useHdr)
throws VideoFrameProcessingException { throws VideoFrameProcessingException {
if (Util.SDK_INT >= 26) {
checkState(
!bitmap.getConfig().equals(Bitmap.Config.RGBA_F16), UNSUPPORTED_IMAGE_CONFIGURATION);
}
if (Util.SDK_INT >= 33) {
checkState(
!bitmap.getConfig().equals(Bitmap.Config.RGBA_1010102), UNSUPPORTED_IMAGE_CONFIGURATION);
}
this.useHdr = useHdr; this.useHdr = useHdr;
int framesToAdd = round(frameRate * (durationUs / (float) C.MICROS_PER_SECOND)); int framesToAdd = round(frameRate * (durationUs / (float) C.MICROS_PER_SECOND));
double frameDurationUs = C.MICROS_PER_SECOND / frameRate; double frameDurationUs = C.MICROS_PER_SECOND / frameRate;
......
...@@ -25,6 +25,7 @@ import com.google.android.exoplayer2.MediaItem; ...@@ -25,6 +25,7 @@ import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.source.MediaSource; import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.util.Clock; import com.google.android.exoplayer2.util.Clock;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import java.util.Locale;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull; import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
/** The default {@link AssetLoader.Factory} implementation. */ /** The default {@link AssetLoader.Factory} implementation. */
...@@ -112,13 +113,14 @@ public final class DefaultAssetLoaderFactory implements AssetLoader.Factory { ...@@ -112,13 +113,14 @@ public final class DefaultAssetLoaderFactory implements AssetLoader.Factory {
if (localConfiguration == null) { if (localConfiguration == null) {
return false; return false;
} }
ImmutableList<String> supportedImageTypes = ImmutableList.of(".png", ".webp", ".jpg", ".jpeg"); ImmutableList<String> supportedImageTypes =
ImmutableList.of(".png", ".webp", ".jpg", ".jpeg", ".heic", ".heif");
String uriPath = checkNotNull(localConfiguration.uri.getPath()); String uriPath = checkNotNull(localConfiguration.uri.getPath());
int fileExtensionStart = uriPath.lastIndexOf("."); int fileExtensionStart = uriPath.lastIndexOf(".");
if (fileExtensionStart < 0) { if (fileExtensionStart < 0) {
return false; return false;
} }
String extension = uriPath.substring(fileExtensionStart); String extension = uriPath.substring(fileExtensionStart).toLowerCase(Locale.ENGLISH);
return supportedImageTypes.contains(extension); return supportedImageTypes.contains(extension);
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment