From 03accb0d8cfe050293702273d66d9088499c98d7 Mon Sep 17 00:00:00 2001 From: Thompson3142 <115718208+Thompson3142@users.noreply.github.com> Date: Wed, 2 Oct 2024 01:59:22 +0200 Subject: [PATCH] Fix the fix --- .../SeekbarPreviewThumbnailHolder.java | 28 ++++++++++++------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/player/seekbarpreview/SeekbarPreviewThumbnailHolder.java b/app/src/main/java/org/schabi/newpipe/player/seekbarpreview/SeekbarPreviewThumbnailHolder.java index 8a8e0fc94a9..4bb0e7899c7 100644 --- a/app/src/main/java/org/schabi/newpipe/player/seekbarpreview/SeekbarPreviewThumbnailHolder.java +++ b/app/src/main/java/org/schabi/newpipe/player/seekbarpreview/SeekbarPreviewThumbnailHolder.java @@ -109,6 +109,7 @@ private void generateDataFrom(final Frameset frameset, final UUID updateRequestI final Stopwatch sw = Log.isLoggable(TAG, Log.DEBUG) ? Stopwatch.createStarted() : null; int currentPosMs = 0; + int pos = 1; final int urlFrameCount = frameset.getFramesPerPageX() * frameset.getFramesPerPageY(); @@ -117,14 +118,6 @@ private void generateDataFrom(final Frameset frameset, final UUID updateRequestI // get the bitmap final Bitmap srcBitMap = getBitMapFrom(url); - // It can happen, that the original bitmap could not be downloaded - // In such a case - we don't want a NullPointer - simply return null - // Recycled bitmaps can also not be created, so we also need to check for that - if (srcBitMap == null || srcBitMap.isRecycled()) { - Log.e(TAG, "Failed to retrieve or use bitmap from url: " + url); - continue; - } - // The data is not added directly to "seekbarPreviewData" due to // concurrency and checks for "updateRequestIdentifier" final var generatedDataForUrl = new SparseArrayCompat>(urlFrameCount); @@ -133,19 +126,34 @@ private void generateDataFrom(final Frameset frameset, final UUID updateRequestI // foreach frame in the returned bitmap for (int i = 0; i < urlFrameCount; i++) { // Frames outside the video length are skipped - if (i >= frameset.getTotalCount()) { + if (pos > frameset.getTotalCount()) { break; } // Get the bounds where the frame is found final int[] bounds = frameset.getFrameBoundsAt(currentPosMs); generatedDataForUrl.put(currentPosMs, () -> { + // It can happen, that the original bitmap could not be downloaded + // In such a case - we don't want a NullPointer - simply return null; + // Recycled bitmaps are also unusable here so we should check for that too + if (srcBitMap == null || srcBitMap.isRecycled()) { + return null; + } + // Cut out the corresponding bitmap form the "srcBitMap" - return Bitmap.createBitmap(srcBitMap, bounds[1], bounds[2], + final Bitmap cutOutBitmap = Bitmap.createBitmap(srcBitMap, bounds[1], bounds[2], frameset.getFrameWidth(), frameset.getFrameHeight()); + + // We need to copy the bitmap to create a new instance since createBitmap + // allows itself to return the original object that is was created with + // this leads to recycled bitmaps being returned (if they are identical) + // Reference: https://stackoverflow.com/a/23683075 + first comment + // Fixes: https://github.com/TeamNewPipe/NewPipe/issues/11461 + return cutOutBitmap.copy(cutOutBitmap.getConfig(), true); }); currentPosMs += frameset.getDurationPerFrame(); + pos++; } // Check if we are still the latest request