diff --git a/library/core/src/main/java/com/google/android/exoplayer2/surfacecapturer/SurfaceCapturer.java b/library/core/src/main/java/com/google/android/exoplayer2/surfacecapturer/SurfaceCapturer.java deleted file mode 100644 index 4a7fd71494..0000000000 --- a/library/core/src/main/java/com/google/android/exoplayer2/surfacecapturer/SurfaceCapturer.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.google.android.exoplayer2.surfacecapturer; - -import android.graphics.Bitmap; -import android.view.Surface; - -/** - * A surface capturer, which captures image drawn into its surface as bitmaps. - * - *

It constructs a {@link Surface}, which can be used as the output surface for an image producer - * to draw images to. As images are being drawn into this surface, this capturer will capture these - * images, and return them via {@link Callback}. The output images will have a fixed frame size of - * (width, height), and any image drawn into the surface will be stretched to fit this frame size. - */ -public abstract class SurfaceCapturer { - - /** The callback to be notified of the image capturing result. */ - public interface Callback { - - /** - * Called when the surface capturer has been able to capture its surface into a {@link Bitmap}. - * This will happen whenever the producer updates the image on the wrapped surface. - */ - void onSurfaceCaptured(Bitmap bitmap); - - /** Called when the surface capturer couldn't capture its surface due to an error. */ - void onSurfaceCaptureError(Exception e); - } - - /** The callback to be notified of the image capturing result. */ - private final Callback callback; - /** The width of the output images. */ - private final int outputWidth; - /** The height of the output images. */ - private final int outputHeight; - - /** - * Constructs a new instance. - * - * @param callback See {@link #callback}. - * @param outputWidth See {@link #outputWidth}. - * @param outputHeight See {@link #outputHeight}. - */ - protected SurfaceCapturer(Callback callback, int outputWidth, int outputHeight) { - this.callback = callback; - this.outputWidth = outputWidth; - this.outputHeight = outputHeight; - } - - /** Returns the callback to be notified of the image capturing result. */ - protected Callback getCallback() { - return callback; - } - - /** Returns the width of the output images. */ - public int getOutputWidth() { - return outputWidth; - } - - /** Returns the height of the output images. */ - public int getOutputHeight() { - return outputHeight; - } - - /** Returns a {@link Surface} that image producers (camera, video codec etc...) can draw to. */ - public abstract Surface getSurface(); - - /** Releases all kept resources. This instance cannot be used after this call. */ - public abstract void release(); -} diff --git a/testutils/src/main/java/com/google/android/exoplayer2/testutil/TestUtil.java b/testutils/src/main/java/com/google/android/exoplayer2/testutil/TestUtil.java index ee17068242..e62186f595 100644 --- a/testutils/src/main/java/com/google/android/exoplayer2/testutil/TestUtil.java +++ b/testutils/src/main/java/com/google/android/exoplayer2/testutil/TestUtil.java @@ -19,6 +19,8 @@ import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.fail; import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.Color; import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.extractor.Extractor; import com.google.android.exoplayer2.testutil.FakeExtractorInput.SimulatedIOException; @@ -166,4 +168,55 @@ public class TestUtil { } } + /** + * Asserts whether actual bitmap is very similar to the expected bitmap at some quality level. + * + *

This is defined as their PSNR value is greater than or equal to the threshold. The higher + * the threshold, the more similar they are. + * + * @param expectedBitmap The expected bitmap. + * @param actualBitmap The actual bitmap. + * @param psnrThresholdDb The PSNR threshold (in dB), at or above which bitmaps are considered + * very similar. + */ + public static void assertBitmapsAreSimilar( + Bitmap expectedBitmap, Bitmap actualBitmap, double psnrThresholdDb) { + assertThat(getPsnr(expectedBitmap, actualBitmap) >= psnrThresholdDb).isTrue(); + } + + /** + * Calculates the Peak-Signal-to-Noise-Ratio value for 2 bitmaps. + * + *

It is calculated as the logarithmic decibel(dB) value of the ratio between square of peak + * R/G/B values (255.0 * 255.0), and the average mean-squared-error of R/G/B values from the two + * bitmaps. The higher the value, the more similar they are. + * + * @param firstBitmap The first bitmap. + * @param secondBitmap The second bitmap. + * @return The PSNR value calculated from these 2 bitmaps. + */ + private static double getPsnr(Bitmap firstBitmap, Bitmap secondBitmap) { + assertThat(firstBitmap.getWidth()).isEqualTo(secondBitmap.getWidth()); + assertThat(firstBitmap.getHeight()).isEqualTo(secondBitmap.getHeight()); + double mse = 0; + for (int i = 0; i < firstBitmap.getWidth(); i++) { + for (int j = 0; j < firstBitmap.getHeight(); j++) { + int firstColorInt = firstBitmap.getPixel(i, j); + double firstRed = Color.red(firstColorInt); + double firstGreen = Color.green(firstColorInt); + double firstBlue = Color.blue(firstColorInt); + int secondColorInt = secondBitmap.getPixel(i, j); + double secondRed = Color.red(secondColorInt); + double secondGreen = Color.green(secondColorInt); + double secondBlue = Color.blue(secondColorInt); + mse += + ((firstRed - secondRed) * (firstRed - secondRed) + + (firstGreen - secondGreen) * (firstGreen - secondGreen) + + (firstBlue - secondBlue) * (firstBlue - secondBlue)) + / 3.0; + } + } + mse = mse / (firstBitmap.getWidth() * firstBitmap.getHeight()); + return 10 * Math.log10(255.0 * 255.0 / mse); + } }