diff --git a/library/src/main/java/com/bumptech/glide/Glide.java b/library/src/main/java/com/bumptech/glide/Glide.java index f8ffd69c50..a46ac5786b 100644 --- a/library/src/main/java/com/bumptech/glide/Glide.java +++ b/library/src/main/java/com/bumptech/glide/Glide.java @@ -560,6 +560,16 @@ Uri.class, Bitmap.class, new ResourceBitmapDecoder(resourceDrawableDecoder, bitm bitmapPool, bitmapBytesTranscoder, gifDrawableBytesTranscoder)) .register(GifDrawable.class, byte[].class, gifDrawableBytesTranscoder); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + ResourceDecoder byteBufferVideoDecoder = + VideoDecoder.byteBuffer(bitmapPool); + registry.append(ByteBuffer.class, Bitmap.class, byteBufferVideoDecoder); + registry.append( + ByteBuffer.class, + BitmapDrawable.class, + new BitmapDrawableDecoder<>(resources, byteBufferVideoDecoder)); + } + ImageViewTargetFactory imageViewTargetFactory = new ImageViewTargetFactory(); glideContext = new GlideContext( diff --git a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/VideoDecoder.java b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/VideoDecoder.java index 2b1a880788..6c08fda199 100644 --- a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/VideoDecoder.java +++ b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/VideoDecoder.java @@ -3,6 +3,7 @@ import android.annotation.TargetApi; import android.content.res.AssetFileDescriptor; import android.graphics.Bitmap; +import android.media.MediaDataSource; import android.media.MediaMetadataRetriever; import android.os.Build; import android.os.Build.VERSION_CODES; @@ -10,6 +11,7 @@ import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.annotation.RequiresApi; import androidx.annotation.VisibleForTesting; import com.bumptech.glide.load.Option; import com.bumptech.glide.load.Options; @@ -120,6 +122,11 @@ public static ResourceDecoder parcel(BitmapPool bi return new VideoDecoder<>(bitmapPool, new ParcelFileDescriptorInitializer()); } + @RequiresApi(api = VERSION_CODES.M) + public static ResourceDecoder byteBuffer(BitmapPool bitmapPool) { + return new VideoDecoder<>(bitmapPool, new ByteBufferInitializer()); + } + VideoDecoder(BitmapPool bitmapPool, MediaMetadataRetrieverInitializer initializer) { this(bitmapPool, initializer, DEFAULT_FACTORY); } @@ -299,4 +306,34 @@ public void initialize(MediaMetadataRetriever retriever, ParcelFileDescriptor da retriever.setDataSource(data.getFileDescriptor()); } } + + @RequiresApi(Build.VERSION_CODES.M) + static final class ByteBufferInitializer + implements MediaMetadataRetrieverInitializer { + + @Override + public void initialize(MediaMetadataRetriever retriever, final ByteBuffer data) { + retriever.setDataSource( + new MediaDataSource() { + @Override + public int readAt(long position, byte[] buffer, int offset, int size) { + if (position >= data.limit()) { + return -1; + } + data.position((int) position); + int numBytesRead = Math.min(size, data.remaining()); + data.get(buffer, offset, numBytesRead); + return numBytesRead; + } + + @Override + public long getSize() { + return data.limit(); + } + + @Override + public void close() {} + }); + } + } }