Merge "media: Fix ImageReader only using maxImages=1 no matter what" into klp-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
aa973d1d0b
@ -20,7 +20,6 @@ import android.graphics.ImageFormat;
|
|||||||
import android.graphics.PixelFormat;
|
import android.graphics.PixelFormat;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.os.Message;
|
|
||||||
import android.view.Surface;
|
import android.view.Surface;
|
||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
@ -130,11 +129,26 @@ public final class ImageReader implements AutoCloseable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>Get the next Image from the ImageReader's queue. Returns {@code null}
|
* <p>
|
||||||
* if no new image is available.</p>
|
* Get the next Image from the ImageReader's queue. Returns {@code null} if
|
||||||
|
* no new image is available.
|
||||||
|
* </p>
|
||||||
|
* <p>
|
||||||
|
* This operation will fail by throwing an
|
||||||
|
* {@link Surface.OutOfResourcesException OutOfResourcesException} if too
|
||||||
|
* many images have been acquired with {@link #getNextImage}. In particular
|
||||||
|
* a sequence of {@link #getNextImage} calls greater than {@link #getMaxImages}
|
||||||
|
* without calling {@link Image#close} or {@link #releaseImage} in-between
|
||||||
|
* will exhaust the underlying queue. At such a time,
|
||||||
|
* {@link Surface.OutOfResourcesException OutOfResourcesException} will be
|
||||||
|
* thrown until more images are released with {@link Image#close} or
|
||||||
|
* {@link #releaseImage}.
|
||||||
|
* </p>
|
||||||
*
|
*
|
||||||
* @return a new frame of image data, or {@code null} if no image data is
|
* @return a new frame of image data, or {@code null} if no image data is
|
||||||
* available.
|
* available.
|
||||||
|
* @throws Surface.OutOfResourcesException if too many images are currently
|
||||||
|
* acquired
|
||||||
*/
|
*/
|
||||||
public Image getNextImage() {
|
public Image getNextImage() {
|
||||||
SurfaceImage si = new SurfaceImage();
|
SurfaceImage si = new SurfaceImage();
|
||||||
@ -172,6 +186,8 @@ public final class ImageReader implements AutoCloseable {
|
|||||||
* @param listener the listener that will be run
|
* @param listener the listener that will be run
|
||||||
* @param handler The handler on which the listener should be invoked, or null
|
* @param handler The handler on which the listener should be invoked, or null
|
||||||
* if the listener should be invoked on the calling thread's looper.
|
* if the listener should be invoked on the calling thread's looper.
|
||||||
|
*
|
||||||
|
* @throws IllegalArgumentException if no handler specified and the calling thread has no looper
|
||||||
*/
|
*/
|
||||||
public void setImageAvailableListener(OnImageAvailableListener listener, Handler handler) {
|
public void setImageAvailableListener(OnImageAvailableListener listener, Handler handler) {
|
||||||
mImageListener = listener;
|
mImageListener = listener;
|
||||||
@ -260,8 +276,9 @@ public final class ImageReader implements AutoCloseable {
|
|||||||
* Called from Native code when an Event happens.
|
* Called from Native code when an Event happens.
|
||||||
*/
|
*/
|
||||||
private static void postEventFromNative(Object selfRef) {
|
private static void postEventFromNative(Object selfRef) {
|
||||||
WeakReference weakSelf = (WeakReference)selfRef;
|
@SuppressWarnings("unchecked")
|
||||||
final ImageReader ir = (ImageReader)weakSelf.get();
|
WeakReference<ImageReader> weakSelf = (WeakReference<ImageReader>)selfRef;
|
||||||
|
final ImageReader ir = weakSelf.get();
|
||||||
if (ir == null) {
|
if (ir == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -44,6 +44,9 @@
|
|||||||
|
|
||||||
using namespace android;
|
using namespace android;
|
||||||
|
|
||||||
|
static const char* const OutOfResourcesException =
|
||||||
|
"android/view/Surface$OutOfResourcesException";
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
IMAGE_READER_MAX_NUM_PLANES = 3,
|
IMAGE_READER_MAX_NUM_PLANES = 3,
|
||||||
};
|
};
|
||||||
@ -609,7 +612,8 @@ static void ImageReader_init(JNIEnv* env, jobject thiz, jobject weakThiz,
|
|||||||
nativeFormat = Image_getPixelFormat(env, format);
|
nativeFormat = Image_getPixelFormat(env, format);
|
||||||
|
|
||||||
sp<BufferQueue> bq = new BufferQueue();
|
sp<BufferQueue> bq = new BufferQueue();
|
||||||
sp<CpuConsumer> consumer = new CpuConsumer(bq, true, maxImages);
|
sp<CpuConsumer> consumer = new CpuConsumer(bq, maxImages,
|
||||||
|
/*controlledByApp*/true);
|
||||||
// TODO: throw dvm exOutOfMemoryError?
|
// TODO: throw dvm exOutOfMemoryError?
|
||||||
if (consumer == NULL) {
|
if (consumer == NULL) {
|
||||||
jniThrowRuntimeException(env, "Failed to allocate native CpuConsumer");
|
jniThrowRuntimeException(env, "Failed to allocate native CpuConsumer");
|
||||||
@ -702,7 +706,17 @@ static jboolean ImageReader_imageSetup(JNIEnv* env, jobject thiz,
|
|||||||
status_t res = consumer->lockNextBuffer(buffer);
|
status_t res = consumer->lockNextBuffer(buffer);
|
||||||
if (res != NO_ERROR) {
|
if (res != NO_ERROR) {
|
||||||
if (res != BAD_VALUE /*no buffers*/) {
|
if (res != BAD_VALUE /*no buffers*/) {
|
||||||
ALOGE("%s Fail to lockNextBuffer with error: %d ", __FUNCTION__, res);
|
if (res == NOT_ENOUGH_DATA) {
|
||||||
|
jniThrowException(env, OutOfResourcesException,
|
||||||
|
"Too many outstanding images, close existing images"
|
||||||
|
" to be able to acquire more.");
|
||||||
|
} else {
|
||||||
|
ALOGE("%s Fail to lockNextBuffer with error: %d ",
|
||||||
|
__FUNCTION__, res);
|
||||||
|
jniThrowExceptionFmt(env, "java/lang/IllegalStateException",
|
||||||
|
"Unknown error (%d) when we tried to lock buffer.",
|
||||||
|
res);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -714,6 +728,7 @@ static jboolean ImageReader_imageSetup(JNIEnv* env, jobject thiz,
|
|||||||
ALOGE("crop left: %d, top = %d", lt.x, lt.y);
|
ALOGE("crop left: %d, top = %d", lt.x, lt.y);
|
||||||
jniThrowException(env, "java/lang/UnsupportedOperationException",
|
jniThrowException(env, "java/lang/UnsupportedOperationException",
|
||||||
"crop left top corner need to at origin");
|
"crop left top corner need to at origin");
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the producer buffer configurations match what ImageReader configured.
|
// Check if the producer buffer configurations match what ImageReader configured.
|
||||||
|
Reference in New Issue
Block a user