diff options
author | Ruben Brunk <rubenbrunk@google.com> | 2014-12-10 21:55:55 +0000 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2014-12-10 21:55:55 +0000 |
commit | 1fcae5927d4354b4e963c233bf77246631a852c5 (patch) | |
tree | 496d643090650b202b80e6f78441ef1429ab47ab /services/camera/libcameraservice/api2/CameraDeviceClient.cpp | |
parent | c6ac859f5a82ea8642bc6351a45508a15f224f32 (diff) | |
parent | 3b46819eb0dd9ea510619c351d7ffdc244ed511d (diff) | |
download | frameworks_av-1fcae5927d4354b4e963c233bf77246631a852c5.zip frameworks_av-1fcae5927d4354b4e963c233bf77246631a852c5.tar.gz frameworks_av-1fcae5927d4354b4e963c233bf77246631a852c5.tar.bz2 |
am 3b46819e: Merge commit \'2340e5a8\' into manualmerge
* commit '3b46819eb0dd9ea510619c351d7ffdc244ed511d':
Camera2: Round unsupported surface sizes in configure.
Diffstat (limited to 'services/camera/libcameraservice/api2/CameraDeviceClient.cpp')
-rw-r--r-- | services/camera/libcameraservice/api2/CameraDeviceClient.cpp | 76 |
1 files changed, 72 insertions, 4 deletions
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp index 920adf6..6a1ee44 100644 --- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp +++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp @@ -359,6 +359,14 @@ status_t CameraDeviceClient::createStream(int width, int height, int format, useAsync = true; } + int32_t disallowedFlags = GraphicBuffer::USAGE_HW_VIDEO_ENCODER | + GRALLOC_USAGE_RENDERSCRIPT; + int32_t allowedFlags = GraphicBuffer::USAGE_SW_READ_MASK | + GraphicBuffer::USAGE_HW_TEXTURE | + GraphicBuffer::USAGE_HW_COMPOSER; + bool flexibleConsumer = (consumerUsage & disallowedFlags) == 0 && + (consumerUsage & allowedFlags) != 0; + sp<IBinder> binder = IInterface::asBinder(bufferProducer); sp<ANativeWindow> anw = new Surface(bufferProducer, useAsync); @@ -384,14 +392,18 @@ status_t CameraDeviceClient::createStream(int width, int height, int format, // IMPLEMENTATION_DEFINED. b/9487482 if (format >= HAL_PIXEL_FORMAT_RGBA_8888 && format <= HAL_PIXEL_FORMAT_BGRA_8888) { - ALOGW("%s: Camera %d: Overriding format 0x%x to IMPLEMENTATION_DEFINED", + ALOGW("%s: Camera %d: Overriding format %#x to IMPLEMENTATION_DEFINED", __FUNCTION__, mCameraId, format); format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED; } - // TODO: add startConfigure/stopConfigure call to CameraDeviceBase - // this will make it so Camera3Device doesn't call configure_streams - // after each call, but only once we are done with all. + // Round dimensions to the nearest dimensions available for this format + if (flexibleConsumer && !CameraDeviceClient::roundBufferDimensionNearest(width, height, + format, mDevice->info(), /*out*/&width, /*out*/&height)) { + ALOGE("%s: No stream configurations with the format %#x defined, failed to create stream.", + __FUNCTION__, format); + return BAD_VALUE; + } int streamId = -1; res = mDevice->createStream(anw, width, height, format, &streamId); @@ -427,6 +439,62 @@ status_t CameraDeviceClient::createStream(int width, int height, int format, return res; } + +bool CameraDeviceClient::roundBufferDimensionNearest(int32_t width, int32_t height, + int32_t format, const CameraMetadata& info, + /*out*/int32_t* outWidth, /*out*/int32_t* outHeight) { + + camera_metadata_ro_entry streamConfigs = + info.find(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS); + + int32_t bestWidth = -1; + int32_t bestHeight = -1; + + // Iterate through listed stream configurations and find the one with the smallest euclidean + // distance from the given dimensions for the given format. + for (size_t i = 0; i < streamConfigs.count; i += 4) { + int32_t fmt = streamConfigs.data.i32[i]; + int32_t w = streamConfigs.data.i32[i + 1]; + int32_t h = streamConfigs.data.i32[i + 2]; + + // Ignore input/output type for now + if (fmt == format) { + if (w == width && h == height) { + bestWidth = width; + bestHeight = height; + break; + } else if (w <= ROUNDING_WIDTH_CAP && (bestWidth == -1 || + CameraDeviceClient::euclidDistSquare(w, h, width, height) < + CameraDeviceClient::euclidDistSquare(bestWidth, bestHeight, width, height))) { + bestWidth = w; + bestHeight = h; + } + } + } + + if (bestWidth == -1) { + // Return false if no configurations for this format were listed + return false; + } + + // Set the outputs to the closet width/height + if (outWidth != NULL) { + *outWidth = bestWidth; + } + if (outHeight != NULL) { + *outHeight = bestHeight; + } + + // Return true if at least one configuration for this format was listed + return true; +} + +int64_t CameraDeviceClient::euclidDistSquare(int32_t x0, int32_t y0, int32_t x1, int32_t y1) { + int64_t d0 = x0 - x1; + int64_t d1 = y0 - y1; + return d0 * d0 + d1 * d1; +} + // Create a request object from a template. status_t CameraDeviceClient::createDefaultRequest(int templateId, /*out*/ |