android_media_Utils.cpp revision 2584cda885964370f612a2b9251f7d6cf9ebf29a
179f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong/* 279f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong * Copyright 2011, The Android Open Source Project 379f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong * 479f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong * Licensed under the Apache License, Version 2.0 (the "License"); 579f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong * you may not use this file except in compliance with the License. 679f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong * You may obtain a copy of the License at 779f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong * 879f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong * http://www.apache.org/licenses/LICENSE-2.0 979f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong * 1079f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong * Unless required by applicable law or agreed to in writing, software 1179f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong * distributed under the License is distributed on an "AS IS" BASIS, 1279f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1379f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong * See the License for the specific language governing permissions and 1479f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong * limitations under the License. 1579f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong */ 1679f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong 1779f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong// #define LOG_NDEBUG 0 1879f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong#define LOG_TAG "AndroidMediaUtils" 1979f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong 2079f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong#include <utils/Log.h> 2179f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong#include "android_media_Utils.h" 2279f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong 2388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <media/stagefright/foundation/ADebug.h> 2488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <media/stagefright/foundation/ABuffer.h> 2588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <media/stagefright/foundation/AMessage.h> 2688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 278d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber#include <nativehelper/ScopedLocalRef.h> 288d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber 290ab416269a866c8afa8f65d9351afa2407abee4cZhijun He#define ALIGN(x, mask) ( ((x) + (mask) - 1) & ~((mask) - 1) ) 300ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 3179f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dongnamespace android { 3279f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong 336e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung ChungAssetStream::AssetStream(SkStream* stream) 342584cda885964370f612a2b9251f7d6cf9ebf29aSungsoo Lim : mStream(stream), mPosition(0) { 356e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung} 366e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung 376e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung ChungAssetStream::~AssetStream() { 386e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung} 396e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung 406e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chungpiex::Error AssetStream::GetData( 416e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung const size_t offset, const size_t length, std::uint8_t* data) { 426e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung // Seek first. 436e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung if (mPosition != offset) { 446e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung if (!mStream->seek(offset)) { 456e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung return piex::Error::kFail; 466e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung } 476e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung } 486e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung 496e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung // Read bytes. 506e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung size_t size = mStream->read((void*)data, length); 512584cda885964370f612a2b9251f7d6cf9ebf29aSungsoo Lim mPosition = offset + size; 526e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung 536e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung return size == length ? piex::Error::kOk : piex::Error::kFail; 546e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung} 556e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung 566e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung ChungBufferedStream::BufferedStream(SkStream* stream) 576e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung : mStream(stream) { 586e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung} 596e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung 606e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung ChungBufferedStream::~BufferedStream() { 616e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung} 626e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung 636e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chungpiex::Error BufferedStream::GetData( 646e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung const size_t offset, const size_t length, std::uint8_t* data) { 656e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung // Seek first. 666e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung if (offset + length > mStreamBuffer.bytesWritten()) { 676e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung size_t sizeToRead = offset + length - mStreamBuffer.bytesWritten(); 686e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung if (sizeToRead <= kMinSizeToRead) { 696e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung sizeToRead = kMinSizeToRead; 706e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung } 716e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung void* tempBuffer = malloc(sizeToRead); 726e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung if (tempBuffer != NULL) { 736e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung size_t bytesRead = mStream->read(tempBuffer, sizeToRead); 746e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung if (bytesRead != sizeToRead) { 756e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung free(tempBuffer); 766e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung return piex::Error::kFail; 776e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung } 786e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung mStreamBuffer.write(tempBuffer, bytesRead); 796e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung free(tempBuffer); 806e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung } 816e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung } 826e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung 836e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung // Read bytes. 846e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung if (mStreamBuffer.read((void*)data, offset, length)) { 856e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung return piex::Error::kOk; 866e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung } else { 876e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung return piex::Error::kFail; 886e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung } 896e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung} 906e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung 9115ef59e081846b43660635391d536361c3253a22Jaesung ChungFileStream::FileStream(const int fd) 926e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung : mPosition(0) { 9315ef59e081846b43660635391d536361c3253a22Jaesung Chung mFile = fdopen(fd, "r"); 9415ef59e081846b43660635391d536361c3253a22Jaesung Chung if (mFile == NULL) { 9515ef59e081846b43660635391d536361c3253a22Jaesung Chung return; 9615ef59e081846b43660635391d536361c3253a22Jaesung Chung } 9715ef59e081846b43660635391d536361c3253a22Jaesung Chung} 9815ef59e081846b43660635391d536361c3253a22Jaesung Chung 998409c0691fb128fef6244305977342776bddf919Jaesung ChungFileStream::FileStream(const String8 filename) 1006e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung : mPosition(0) { 1018409c0691fb128fef6244305977342776bddf919Jaesung Chung mFile = fopen(filename.string(), "r"); 1028409c0691fb128fef6244305977342776bddf919Jaesung Chung if (mFile == NULL) { 1038409c0691fb128fef6244305977342776bddf919Jaesung Chung return; 1048409c0691fb128fef6244305977342776bddf919Jaesung Chung } 1058409c0691fb128fef6244305977342776bddf919Jaesung Chung} 1068409c0691fb128fef6244305977342776bddf919Jaesung Chung 1078409c0691fb128fef6244305977342776bddf919Jaesung ChungFileStream::~FileStream() { 1088409c0691fb128fef6244305977342776bddf919Jaesung Chung if (mFile != NULL) { 1098409c0691fb128fef6244305977342776bddf919Jaesung Chung fclose(mFile); 1108409c0691fb128fef6244305977342776bddf919Jaesung Chung mFile = NULL; 1118409c0691fb128fef6244305977342776bddf919Jaesung Chung } 1128409c0691fb128fef6244305977342776bddf919Jaesung Chung} 1138409c0691fb128fef6244305977342776bddf919Jaesung Chung 1148409c0691fb128fef6244305977342776bddf919Jaesung Chungpiex::Error FileStream::GetData( 1158409c0691fb128fef6244305977342776bddf919Jaesung Chung const size_t offset, const size_t length, std::uint8_t* data) { 1168409c0691fb128fef6244305977342776bddf919Jaesung Chung if (mFile == NULL) { 1178409c0691fb128fef6244305977342776bddf919Jaesung Chung return piex::Error::kFail; 1188409c0691fb128fef6244305977342776bddf919Jaesung Chung } 1198409c0691fb128fef6244305977342776bddf919Jaesung Chung 1208409c0691fb128fef6244305977342776bddf919Jaesung Chung // Seek first. 1218409c0691fb128fef6244305977342776bddf919Jaesung Chung if (mPosition != offset) { 1228409c0691fb128fef6244305977342776bddf919Jaesung Chung fseek(mFile, offset, SEEK_SET); 1238409c0691fb128fef6244305977342776bddf919Jaesung Chung } 1248409c0691fb128fef6244305977342776bddf919Jaesung Chung 1258409c0691fb128fef6244305977342776bddf919Jaesung Chung // Read bytes. 1268409c0691fb128fef6244305977342776bddf919Jaesung Chung size_t size = fread((void*)data, sizeof(std::uint8_t), length, mFile); 1278409c0691fb128fef6244305977342776bddf919Jaesung Chung mPosition += size; 1288409c0691fb128fef6244305977342776bddf919Jaesung Chung 1298409c0691fb128fef6244305977342776bddf919Jaesung Chung // Handle errors. 1306e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung if (ferror(mFile)) { 1318409c0691fb128fef6244305977342776bddf919Jaesung Chung ALOGV("GetData read failed: (offset: %zu, length: %zu)", offset, length); 1328409c0691fb128fef6244305977342776bddf919Jaesung Chung return piex::Error::kFail; 1338409c0691fb128fef6244305977342776bddf919Jaesung Chung } 1348409c0691fb128fef6244305977342776bddf919Jaesung Chung return piex::Error::kOk; 1358409c0691fb128fef6244305977342776bddf919Jaesung Chung} 1368409c0691fb128fef6244305977342776bddf919Jaesung Chung 1378409c0691fb128fef6244305977342776bddf919Jaesung Chungbool FileStream::exists() const { 1388409c0691fb128fef6244305977342776bddf919Jaesung Chung return mFile != NULL; 1398409c0691fb128fef6244305977342776bddf919Jaesung Chung} 1408409c0691fb128fef6244305977342776bddf919Jaesung Chung 1418409c0691fb128fef6244305977342776bddf919Jaesung Chungbool GetExifFromRawImage( 1426e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung piex::StreamInterface* stream, const String8& filename, 1436e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung piex::PreviewImageData& image_data) { 1448f7a8f1eba590f4a0bb21988fc2a876dcb72dccdAnton Daubert // Reset the PreviewImageData to its default. 1458f7a8f1eba590f4a0bb21988fc2a876dcb72dccdAnton Daubert image_data = piex::PreviewImageData(); 1468409c0691fb128fef6244305977342776bddf919Jaesung Chung 1478409c0691fb128fef6244305977342776bddf919Jaesung Chung if (!piex::IsRaw(stream)) { 1488409c0691fb128fef6244305977342776bddf919Jaesung Chung // Format not supported. 1498409c0691fb128fef6244305977342776bddf919Jaesung Chung ALOGV("Format not supported: %s", filename.string()); 1508409c0691fb128fef6244305977342776bddf919Jaesung Chung return false; 1518409c0691fb128fef6244305977342776bddf919Jaesung Chung } 1528409c0691fb128fef6244305977342776bddf919Jaesung Chung 1538409c0691fb128fef6244305977342776bddf919Jaesung Chung piex::Error err = piex::GetPreviewImageData(stream, &image_data); 1548409c0691fb128fef6244305977342776bddf919Jaesung Chung 1558409c0691fb128fef6244305977342776bddf919Jaesung Chung if (err != piex::Error::kOk) { 1568409c0691fb128fef6244305977342776bddf919Jaesung Chung // The input data seems to be broken. 1578409c0691fb128fef6244305977342776bddf919Jaesung Chung ALOGV("Raw image not detected: %s (piex error code: %d)", filename.string(), (int32_t)err); 1588409c0691fb128fef6244305977342776bddf919Jaesung Chung return false; 1598409c0691fb128fef6244305977342776bddf919Jaesung Chung } 1608409c0691fb128fef6244305977342776bddf919Jaesung Chung 1618409c0691fb128fef6244305977342776bddf919Jaesung Chung return true; 1628409c0691fb128fef6244305977342776bddf919Jaesung Chung} 1638409c0691fb128fef6244305977342776bddf919Jaesung Chung 16479f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dongbool ConvertKeyValueArraysToKeyedVector( 16579f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong JNIEnv *env, jobjectArray keys, jobjectArray values, 16679f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong KeyedVector<String8, String8>* keyedVector) { 16779f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong 16879f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong int nKeyValuePairs = 0; 16979f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong bool failed = false; 17079f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong if (keys != NULL && values != NULL) { 17179f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong nKeyValuePairs = env->GetArrayLength(keys); 17279f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong failed = (nKeyValuePairs != env->GetArrayLength(values)); 17379f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong } 17479f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong 17579f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong if (!failed) { 17679f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong failed = ((keys != NULL && values == NULL) || 17779f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong (keys == NULL && values != NULL)); 17879f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong } 17979f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong 18079f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong if (failed) { 1813762c311729fe9f3af085c14c5c1fb471d994c03Steve Block ALOGE("keys and values arrays have different length"); 18279f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong jniThrowException(env, "java/lang/IllegalArgumentException", NULL); 18379f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong return false; 18479f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong } 18579f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong 18679f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong for (int i = 0; i < nKeyValuePairs; ++i) { 18779f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong // No need to check on the ArrayIndexOutOfBoundsException, since 18879f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong // it won't happen here. 18979f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong jstring key = (jstring) env->GetObjectArrayElement(keys, i); 19079f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong jstring value = (jstring) env->GetObjectArrayElement(values, i); 19179f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong 19279f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong const char* keyStr = env->GetStringUTFChars(key, NULL); 19379f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong if (!keyStr) { // OutOfMemoryError 19479f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong return false; 19579f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong } 19679f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong 19779f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong const char* valueStr = env->GetStringUTFChars(value, NULL); 19879f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong if (!valueStr) { // OutOfMemoryError 19979f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong env->ReleaseStringUTFChars(key, keyStr); 20079f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong return false; 20179f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong } 20279f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong 20379f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong keyedVector->add(String8(keyStr), String8(valueStr)); 20479f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong 20579f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong env->ReleaseStringUTFChars(key, keyStr); 20679f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong env->ReleaseStringUTFChars(value, valueStr); 20779f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong env->DeleteLocalRef(key); 20879f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong env->DeleteLocalRef(value); 20979f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong } 21079f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong return true; 21179f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong} 21279f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong 21388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic jobject makeIntegerObject(JNIEnv *env, int32_t value) { 2148d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber ScopedLocalRef<jclass> clazz(env, env->FindClass("java/lang/Integer")); 2158d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber CHECK(clazz.get() != NULL); 21688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 2178d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber jmethodID integerConstructID = 2188d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env->GetMethodID(clazz.get(), "<init>", "(I)V"); 21988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(integerConstructID != NULL); 22088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 2218d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber return env->NewObject(clazz.get(), integerConstructID, value); 22288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 22388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 22407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huberstatic jobject makeLongObject(JNIEnv *env, int64_t value) { 2258d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber ScopedLocalRef<jclass> clazz(env, env->FindClass("java/lang/Long")); 2268d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber CHECK(clazz.get() != NULL); 22707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber 2288d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber jmethodID longConstructID = env->GetMethodID(clazz.get(), "<init>", "(J)V"); 22907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber CHECK(longConstructID != NULL); 23007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber 2318d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber return env->NewObject(clazz.get(), longConstructID, value); 23207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber} 23307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber 23488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic jobject makeFloatObject(JNIEnv *env, float value) { 2358d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber ScopedLocalRef<jclass> clazz(env, env->FindClass("java/lang/Float")); 2368d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber CHECK(clazz.get() != NULL); 23788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 2388d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber jmethodID floatConstructID = 2398d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env->GetMethodID(clazz.get(), "<init>", "(F)V"); 24088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(floatConstructID != NULL); 24188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 2428d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber return env->NewObject(clazz.get(), floatConstructID, value); 24388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 24488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 24588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic jobject makeByteBufferObject( 24688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, const void *data, size_t size) { 24788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jbyteArray byteArrayObj = env->NewByteArray(size); 24888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->SetByteArrayRegion(byteArrayObj, 0, size, (const jbyte *)data); 24988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 2508d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber ScopedLocalRef<jclass> clazz(env, env->FindClass("java/nio/ByteBuffer")); 2518d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber CHECK(clazz.get() != NULL); 25288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 25388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jmethodID byteBufWrapID = 2548d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env->GetStaticMethodID( 2558d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber clazz.get(), "wrap", "([B)Ljava/nio/ByteBuffer;"); 25688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(byteBufWrapID != NULL); 25788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 25888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobject byteBufObj = env->CallStaticObjectMethod( 2598d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber clazz.get(), byteBufWrapID, byteArrayObj); 26088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 26188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->DeleteLocalRef(byteArrayObj); byteArrayObj = NULL; 26288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 26388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return byteBufObj; 26488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 26588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 266b842599e51e2d3611503c3c7db1111358f99186dAndreas Huberstatic void SetMapInt32( 267b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber JNIEnv *env, jobject hashMapObj, jmethodID hashMapPutID, 268b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber const char *key, int32_t value) { 269b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber jstring keyObj = env->NewStringUTF(key); 270b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber jobject valueObj = makeIntegerObject(env, value); 271b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber 2725a15d0d31b877ef512b3379eac033c6bb041c86aAndreas Gampe env->CallObjectMethod(hashMapObj, hashMapPutID, keyObj, valueObj); 273b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber 274b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber env->DeleteLocalRef(valueObj); valueObj = NULL; 275b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber env->DeleteLocalRef(keyObj); keyObj = NULL; 276b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber} 277b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber 27888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t ConvertMessageToMap( 27988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, const sp<AMessage> &msg, jobject *map) { 2808d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber ScopedLocalRef<jclass> hashMapClazz( 2818d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env, env->FindClass("java/util/HashMap")); 28288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 2838d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber if (hashMapClazz.get() == NULL) { 28488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return -EINVAL; 28588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 28688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 28788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jmethodID hashMapConstructID = 2888d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env->GetMethodID(hashMapClazz.get(), "<init>", "()V"); 28988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 29088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (hashMapConstructID == NULL) { 29188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return -EINVAL; 29288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 29388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 29488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jmethodID hashMapPutID = 29588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->GetMethodID( 2968d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber hashMapClazz.get(), 29788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber "put", 29888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); 29988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 30088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (hashMapPutID == NULL) { 30188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return -EINVAL; 30288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 30388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 3048d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber jobject hashMap = env->NewObject(hashMapClazz.get(), hashMapConstructID); 30588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 30688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber for (size_t i = 0; i < msg->countEntries(); ++i) { 30788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber AMessage::Type valueType; 30888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber const char *key = msg->getEntryNameAt(i, &valueType); 30988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 310c04399feab8e51531975a4b404327511b094bbf6Lajos Molnar if (!strncmp(key, "android._", 9)) { 311c04399feab8e51531975a4b404327511b094bbf6Lajos Molnar // don't expose private keys (starting with android._) 312c04399feab8e51531975a4b404327511b094bbf6Lajos Molnar continue; 313c04399feab8e51531975a4b404327511b094bbf6Lajos Molnar } 314c04399feab8e51531975a4b404327511b094bbf6Lajos Molnar 31588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobject valueObj = NULL; 31688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 31788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber switch (valueType) { 31888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber case AMessage::kTypeInt32: 31988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { 32088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber int32_t val; 32188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(msg->findInt32(key, &val)); 32288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 32388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber valueObj = makeIntegerObject(env, val); 32407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber break; 32507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber } 32607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber 32707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber case AMessage::kTypeInt64: 32807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber { 32907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber int64_t val; 33007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber CHECK(msg->findInt64(key, &val)); 33107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber 33207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber valueObj = makeLongObject(env, val); 33388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber break; 33488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 33588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 33688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber case AMessage::kTypeFloat: 33788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { 33888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber float val; 33988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(msg->findFloat(key, &val)); 34088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 34188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber valueObj = makeFloatObject(env, val); 34288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber break; 34388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 34488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 34588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber case AMessage::kTypeString: 34688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { 34788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber AString val; 34888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(msg->findString(key, &val)); 34988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 35088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber valueObj = env->NewStringUTF(val.c_str()); 35188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber break; 35288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 35388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 3545c850396b39a57baabd37a9c0c8324f1bee408caAndreas Huber case AMessage::kTypeBuffer: 35588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { 3565c850396b39a57baabd37a9c0c8324f1bee408caAndreas Huber sp<ABuffer> buffer; 3575c850396b39a57baabd37a9c0c8324f1bee408caAndreas Huber CHECK(msg->findBuffer(key, &buffer)); 35888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 35988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber valueObj = makeByteBufferObject( 36088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env, buffer->data(), buffer->size()); 36188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber break; 36288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 36388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 364b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber case AMessage::kTypeRect: 365b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber { 366b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber int32_t left, top, right, bottom; 367b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber CHECK(msg->findRect(key, &left, &top, &right, &bottom)); 368b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber 369b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber SetMapInt32( 370b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber env, 371b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber hashMap, 372b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber hashMapPutID, 373f953ca2ec8e418d54ab7d4585302db22964bcb70Elliott Hughes AStringPrintf("%s-left", key).c_str(), 374b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber left); 375b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber 376b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber SetMapInt32( 377b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber env, 378b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber hashMap, 379b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber hashMapPutID, 380f953ca2ec8e418d54ab7d4585302db22964bcb70Elliott Hughes AStringPrintf("%s-top", key).c_str(), 381b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber top); 382b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber 383b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber SetMapInt32( 384b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber env, 385b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber hashMap, 386b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber hashMapPutID, 387f953ca2ec8e418d54ab7d4585302db22964bcb70Elliott Hughes AStringPrintf("%s-right", key).c_str(), 388b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber right); 389b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber 390b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber SetMapInt32( 391b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber env, 392b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber hashMap, 393b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber hashMapPutID, 394f953ca2ec8e418d54ab7d4585302db22964bcb70Elliott Hughes AStringPrintf("%s-bottom", key).c_str(), 395b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber bottom); 396b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber break; 397b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber } 398b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber 39988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber default: 40088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber break; 40188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 40288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 40388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (valueObj != NULL) { 40488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jstring keyObj = env->NewStringUTF(key); 40588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 4065a15d0d31b877ef512b3379eac033c6bb041c86aAndreas Gampe env->CallObjectMethod(hashMap, hashMapPutID, keyObj, valueObj); 40788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 40888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->DeleteLocalRef(keyObj); keyObj = NULL; 40988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->DeleteLocalRef(valueObj); valueObj = NULL; 41088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 41188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 41288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 41388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber *map = hashMap; 41488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 41588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return OK; 41688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 41788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 41888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t ConvertKeyValueArraysToMessage( 41988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobjectArray keys, jobjectArray values, 42088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<AMessage> *out) { 4218d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber ScopedLocalRef<jclass> stringClass(env, env->FindClass("java/lang/String")); 4228d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber CHECK(stringClass.get() != NULL); 4238d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber ScopedLocalRef<jclass> integerClass(env, env->FindClass("java/lang/Integer")); 4248d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber CHECK(integerClass.get() != NULL); 4258d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber ScopedLocalRef<jclass> longClass(env, env->FindClass("java/lang/Long")); 4268d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber CHECK(longClass.get() != NULL); 4278d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber ScopedLocalRef<jclass> floatClass(env, env->FindClass("java/lang/Float")); 4288d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber CHECK(floatClass.get() != NULL); 4298d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber ScopedLocalRef<jclass> byteBufClass(env, env->FindClass("java/nio/ByteBuffer")); 4308d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber CHECK(byteBufClass.get() != NULL); 43188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 43288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<AMessage> msg = new AMessage; 43388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 43488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jsize numEntries = 0; 43588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 43688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (keys != NULL) { 43788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (values == NULL) { 43888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return -EINVAL; 43988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 44088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 44188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber numEntries = env->GetArrayLength(keys); 44288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 44388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (numEntries != env->GetArrayLength(values)) { 44488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return -EINVAL; 44588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 44688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } else if (values != NULL) { 44788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return -EINVAL; 44888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 44988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 45088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber for (jsize i = 0; i < numEntries; ++i) { 45188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobject keyObj = env->GetObjectArrayElement(keys, i); 45288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 4538d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber if (!env->IsInstanceOf(keyObj, stringClass.get())) { 45488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return -EINVAL; 45588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 45688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 45788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber const char *tmp = env->GetStringUTFChars((jstring)keyObj, NULL); 45888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 45988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (tmp == NULL) { 46088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return -ENOMEM; 46188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 46288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 46388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber AString key = tmp; 46488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 46588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->ReleaseStringUTFChars((jstring)keyObj, tmp); 46688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber tmp = NULL; 46788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 468c04399feab8e51531975a4b404327511b094bbf6Lajos Molnar if (key.startsWith("android._")) { 469c04399feab8e51531975a4b404327511b094bbf6Lajos Molnar // don't propagate private keys (starting with android._) 470c04399feab8e51531975a4b404327511b094bbf6Lajos Molnar continue; 471c04399feab8e51531975a4b404327511b094bbf6Lajos Molnar } 472c04399feab8e51531975a4b404327511b094bbf6Lajos Molnar 47388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobject valueObj = env->GetObjectArrayElement(values, i); 47488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 4758d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber if (env->IsInstanceOf(valueObj, stringClass.get())) { 47688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber const char *value = env->GetStringUTFChars((jstring)valueObj, NULL); 47788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 47888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (value == NULL) { 47988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return -ENOMEM; 48088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 48188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 48288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber msg->setString(key.c_str(), value); 48388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 48488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->ReleaseStringUTFChars((jstring)valueObj, value); 48588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber value = NULL; 4868d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber } else if (env->IsInstanceOf(valueObj, integerClass.get())) { 48788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jmethodID intValueID = 4888d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env->GetMethodID(integerClass.get(), "intValue", "()I"); 48988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(intValueID != NULL); 49088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 49188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jint value = env->CallIntMethod(valueObj, intValueID); 49288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 49388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber msg->setInt32(key.c_str(), value); 4948d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber } else if (env->IsInstanceOf(valueObj, longClass.get())) { 4958d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber jmethodID longValueID = 4968d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env->GetMethodID(longClass.get(), "longValue", "()J"); 4978d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber CHECK(longValueID != NULL); 4988d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber 4998d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber jlong value = env->CallLongMethod(valueObj, longValueID); 5008d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber 5018d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber msg->setInt64(key.c_str(), value); 5028d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber } else if (env->IsInstanceOf(valueObj, floatClass.get())) { 50388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jmethodID floatValueID = 5048d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env->GetMethodID(floatClass.get(), "floatValue", "()F"); 50588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(floatValueID != NULL); 50688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 50788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jfloat value = env->CallFloatMethod(valueObj, floatValueID); 50888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 50988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber msg->setFloat(key.c_str(), value); 5108d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber } else if (env->IsInstanceOf(valueObj, byteBufClass.get())) { 51188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jmethodID positionID = 5128d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env->GetMethodID(byteBufClass.get(), "position", "()I"); 51388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(positionID != NULL); 51488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 51588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jmethodID limitID = 5168d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env->GetMethodID(byteBufClass.get(), "limit", "()I"); 51788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(limitID != NULL); 51888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 51988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jint position = env->CallIntMethod(valueObj, positionID); 52088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jint limit = env->CallIntMethod(valueObj, limitID); 52188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 52288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<ABuffer> buffer = new ABuffer(limit - position); 52388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 52488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber void *data = env->GetDirectBufferAddress(valueObj); 52588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 52688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (data != NULL) { 52788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber memcpy(buffer->data(), 52888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (const uint8_t *)data + position, 52988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber buffer->size()); 53088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } else { 53188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jmethodID arrayID = 5328d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env->GetMethodID(byteBufClass.get(), "array", "()[B"); 53388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(arrayID != NULL); 53488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 53588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jbyteArray byteArray = 53688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (jbyteArray)env->CallObjectMethod(valueObj, arrayID); 53788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(byteArray != NULL); 53888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 53988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->GetByteArrayRegion( 54088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber byteArray, 54188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber position, 54288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber buffer->size(), 54388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (jbyte *)buffer->data()); 54488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 54588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->DeleteLocalRef(byteArray); byteArray = NULL; 54688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 54788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 5489b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huber msg->setBuffer(key.c_str(), buffer); 54988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 55088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 55188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 55288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber *out = msg; 55388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 55488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return OK; 55588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 55688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 5570ab416269a866c8afa8f65d9351afa2407abee4cZhijun He// -----------Utility functions used by ImageReader/Writer JNI----------------- 5580ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 5590ab416269a866c8afa8f65d9351afa2407abee4cZhijun Heenum { 5600ab416269a866c8afa8f65d9351afa2407abee4cZhijun He IMAGE_MAX_NUM_PLANES = 3, 5610ab416269a866c8afa8f65d9351afa2407abee4cZhijun He}; 5620ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 5630ab416269a866c8afa8f65d9351afa2407abee4cZhijun Hebool usingRGBAToJpegOverride(int32_t imageFormat, 5640ab416269a866c8afa8f65d9351afa2407abee4cZhijun He int32_t containerFormat) { 5650ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return containerFormat == HAL_PIXEL_FORMAT_BLOB && imageFormat == HAL_PIXEL_FORMAT_RGBA_8888; 5660ab416269a866c8afa8f65d9351afa2407abee4cZhijun He} 5670ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 5680ab416269a866c8afa8f65d9351afa2407abee4cZhijun Heint32_t applyFormatOverrides(int32_t imageFormat, int32_t containerFormat) { 5690ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Using HAL_PIXEL_FORMAT_RGBA_8888 gralloc buffers containing JPEGs to get around SW 5700ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // write limitations for some platforms (b/17379185). 5710ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (usingRGBAToJpegOverride(imageFormat, containerFormat)) { 5720ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return HAL_PIXEL_FORMAT_BLOB; 5730ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 5740ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return containerFormat; 5750ab416269a866c8afa8f65d9351afa2407abee4cZhijun He} 5760ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 5770ab416269a866c8afa8f65d9351afa2407abee4cZhijun Hebool isFormatOpaque(int format) { 5780ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // This is the only opaque format exposed in the ImageFormat public API. 5790ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Note that we do support CPU access for HAL_PIXEL_FORMAT_RAW_OPAQUE 5800ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // (ImageFormat#RAW_PRIVATE) so it doesn't count as opaque here. 5810ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED; 5820ab416269a866c8afa8f65d9351afa2407abee4cZhijun He} 5830ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 5840ab416269a866c8afa8f65d9351afa2407abee4cZhijun Hebool isPossiblyYUV(PixelFormat format) { 5850ab416269a866c8afa8f65d9351afa2407abee4cZhijun He switch (static_cast<int>(format)) { 5860ab416269a866c8afa8f65d9351afa2407abee4cZhijun He case HAL_PIXEL_FORMAT_RGBA_8888: 5870ab416269a866c8afa8f65d9351afa2407abee4cZhijun He case HAL_PIXEL_FORMAT_RGBX_8888: 5880ab416269a866c8afa8f65d9351afa2407abee4cZhijun He case HAL_PIXEL_FORMAT_RGB_888: 5890ab416269a866c8afa8f65d9351afa2407abee4cZhijun He case HAL_PIXEL_FORMAT_RGB_565: 5900ab416269a866c8afa8f65d9351afa2407abee4cZhijun He case HAL_PIXEL_FORMAT_BGRA_8888: 5910ab416269a866c8afa8f65d9351afa2407abee4cZhijun He case HAL_PIXEL_FORMAT_Y8: 5920ab416269a866c8afa8f65d9351afa2407abee4cZhijun He case HAL_PIXEL_FORMAT_Y16: 5930ab416269a866c8afa8f65d9351afa2407abee4cZhijun He case HAL_PIXEL_FORMAT_RAW16: 5940ab416269a866c8afa8f65d9351afa2407abee4cZhijun He case HAL_PIXEL_FORMAT_RAW10: 5950ab416269a866c8afa8f65d9351afa2407abee4cZhijun He case HAL_PIXEL_FORMAT_RAW_OPAQUE: 5960ab416269a866c8afa8f65d9351afa2407abee4cZhijun He case HAL_PIXEL_FORMAT_BLOB: 5970ab416269a866c8afa8f65d9351afa2407abee4cZhijun He case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED: 5980ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return false; 5990ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 6000ab416269a866c8afa8f65d9351afa2407abee4cZhijun He case HAL_PIXEL_FORMAT_YV12: 6010ab416269a866c8afa8f65d9351afa2407abee4cZhijun He case HAL_PIXEL_FORMAT_YCbCr_420_888: 6020ab416269a866c8afa8f65d9351afa2407abee4cZhijun He case HAL_PIXEL_FORMAT_YCrCb_420_SP: 6030ab416269a866c8afa8f65d9351afa2407abee4cZhijun He default: 6040ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return true; 6050ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 6060ab416269a866c8afa8f65d9351afa2407abee4cZhijun He} 6070ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 6080ab416269a866c8afa8f65d9351afa2407abee4cZhijun Heuint32_t Image_getJpegSize(LockedImage* buffer, bool usingRGBAOverride) { 6090ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGV("%s", __FUNCTION__); 6100ab416269a866c8afa8f65d9351afa2407abee4cZhijun He LOG_ALWAYS_FATAL_IF(buffer == NULL, "Input buffer is NULL!!!"); 6110ab416269a866c8afa8f65d9351afa2407abee4cZhijun He uint32_t size = 0; 6120ab416269a866c8afa8f65d9351afa2407abee4cZhijun He uint32_t width = buffer->width; 6130ab416269a866c8afa8f65d9351afa2407abee4cZhijun He uint8_t* jpegBuffer = buffer->data; 6140ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 6150ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (usingRGBAOverride) { 6160ab416269a866c8afa8f65d9351afa2407abee4cZhijun He width = (buffer->width + buffer->stride * (buffer->height - 1)) * 4; 6170ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 6180ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 6190ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // First check for JPEG transport header at the end of the buffer 6200ab416269a866c8afa8f65d9351afa2407abee4cZhijun He uint8_t* header = jpegBuffer + (width - sizeof(struct camera3_jpeg_blob)); 6210ab416269a866c8afa8f65d9351afa2407abee4cZhijun He struct camera3_jpeg_blob *blob = (struct camera3_jpeg_blob*)(header); 6220ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (blob->jpeg_blob_id == CAMERA3_JPEG_BLOB_ID) { 6230ab416269a866c8afa8f65d9351afa2407abee4cZhijun He size = blob->jpeg_size; 6240ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGV("%s: Jpeg size = %d", __FUNCTION__, size); 6250ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 6260ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 6270ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // failed to find size, default to whole buffer 6280ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (size == 0) { 6290ab416269a866c8afa8f65d9351afa2407abee4cZhijun He /* 6300ab416269a866c8afa8f65d9351afa2407abee4cZhijun He * This is a problem because not including the JPEG header 6310ab416269a866c8afa8f65d9351afa2407abee4cZhijun He * means that in certain rare situations a regular JPEG blob 6320ab416269a866c8afa8f65d9351afa2407abee4cZhijun He * will be mis-identified as having a header, in which case 6330ab416269a866c8afa8f65d9351afa2407abee4cZhijun He * we will get a garbage size value. 6340ab416269a866c8afa8f65d9351afa2407abee4cZhijun He */ 6350ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGW("%s: No JPEG header detected, defaulting to size=width=%d", 6360ab416269a866c8afa8f65d9351afa2407abee4cZhijun He __FUNCTION__, width); 6370ab416269a866c8afa8f65d9351afa2407abee4cZhijun He size = width; 6380ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 6390ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 6400ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return size; 6410ab416269a866c8afa8f65d9351afa2407abee4cZhijun He} 6420ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 6430ab416269a866c8afa8f65d9351afa2407abee4cZhijun Hestatus_t getLockedImageInfo(LockedImage* buffer, int idx, 6440ab416269a866c8afa8f65d9351afa2407abee4cZhijun He int32_t containerFormat, uint8_t **base, uint32_t *size, int *pixelStride, int *rowStride) { 6450ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGV("%s", __FUNCTION__); 6460ab416269a866c8afa8f65d9351afa2407abee4cZhijun He LOG_ALWAYS_FATAL_IF(buffer == NULL, "Input buffer is NULL!!!"); 6470ab416269a866c8afa8f65d9351afa2407abee4cZhijun He LOG_ALWAYS_FATAL_IF(base == NULL, "base is NULL!!!"); 6480ab416269a866c8afa8f65d9351afa2407abee4cZhijun He LOG_ALWAYS_FATAL_IF(size == NULL, "size is NULL!!!"); 6490ab416269a866c8afa8f65d9351afa2407abee4cZhijun He LOG_ALWAYS_FATAL_IF(pixelStride == NULL, "pixelStride is NULL!!!"); 6500ab416269a866c8afa8f65d9351afa2407abee4cZhijun He LOG_ALWAYS_FATAL_IF(rowStride == NULL, "rowStride is NULL!!!"); 6510ab416269a866c8afa8f65d9351afa2407abee4cZhijun He LOG_ALWAYS_FATAL_IF((idx >= IMAGE_MAX_NUM_PLANES) || (idx < 0), "idx (%d) is illegal", idx); 6520ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 6530ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGV("%s: buffer: %p", __FUNCTION__, buffer); 6540ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 6550ab416269a866c8afa8f65d9351afa2407abee4cZhijun He uint32_t dataSize, ySize, cSize, cStride; 6560ab416269a866c8afa8f65d9351afa2407abee4cZhijun He uint32_t pStride = 0, rStride = 0; 6570ab416269a866c8afa8f65d9351afa2407abee4cZhijun He uint8_t *cb, *cr; 6580ab416269a866c8afa8f65d9351afa2407abee4cZhijun He uint8_t *pData = NULL; 6590ab416269a866c8afa8f65d9351afa2407abee4cZhijun He int bytesPerPixel = 0; 6600ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 6610ab416269a866c8afa8f65d9351afa2407abee4cZhijun He dataSize = ySize = cSize = cStride = 0; 6620ab416269a866c8afa8f65d9351afa2407abee4cZhijun He int32_t fmt = buffer->flexFormat; 6630ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 6640ab416269a866c8afa8f65d9351afa2407abee4cZhijun He bool usingRGBAOverride = usingRGBAToJpegOverride(fmt, containerFormat); 6650ab416269a866c8afa8f65d9351afa2407abee4cZhijun He fmt = applyFormatOverrides(fmt, containerFormat); 6660ab416269a866c8afa8f65d9351afa2407abee4cZhijun He switch (fmt) { 6670ab416269a866c8afa8f65d9351afa2407abee4cZhijun He case HAL_PIXEL_FORMAT_YCbCr_420_888: 6680ab416269a866c8afa8f65d9351afa2407abee4cZhijun He pData = 6690ab416269a866c8afa8f65d9351afa2407abee4cZhijun He (idx == 0) ? 6700ab416269a866c8afa8f65d9351afa2407abee4cZhijun He buffer->data : 6710ab416269a866c8afa8f65d9351afa2407abee4cZhijun He (idx == 1) ? 6720ab416269a866c8afa8f65d9351afa2407abee4cZhijun He buffer->dataCb : 6730ab416269a866c8afa8f65d9351afa2407abee4cZhijun He buffer->dataCr; 6740ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // only map until last pixel 6750ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (idx == 0) { 6760ab416269a866c8afa8f65d9351afa2407abee4cZhijun He pStride = 1; 6770ab416269a866c8afa8f65d9351afa2407abee4cZhijun He rStride = buffer->stride; 6780ab416269a866c8afa8f65d9351afa2407abee4cZhijun He dataSize = buffer->stride * (buffer->height - 1) + buffer->width; 6790ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } else { 6800ab416269a866c8afa8f65d9351afa2407abee4cZhijun He pStride = buffer->chromaStep; 6810ab416269a866c8afa8f65d9351afa2407abee4cZhijun He rStride = buffer->chromaStride; 6820ab416269a866c8afa8f65d9351afa2407abee4cZhijun He dataSize = buffer->chromaStride * (buffer->height / 2 - 1) + 6830ab416269a866c8afa8f65d9351afa2407abee4cZhijun He buffer->chromaStep * (buffer->width / 2 - 1) + 1; 6840ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 6850ab416269a866c8afa8f65d9351afa2407abee4cZhijun He break; 6860ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // NV21 6870ab416269a866c8afa8f65d9351afa2407abee4cZhijun He case HAL_PIXEL_FORMAT_YCrCb_420_SP: 6880ab416269a866c8afa8f65d9351afa2407abee4cZhijun He cr = buffer->data + (buffer->stride * buffer->height); 6890ab416269a866c8afa8f65d9351afa2407abee4cZhijun He cb = cr + 1; 6900ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // only map until last pixel 6910ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ySize = buffer->width * (buffer->height - 1) + buffer->width; 6920ab416269a866c8afa8f65d9351afa2407abee4cZhijun He cSize = buffer->width * (buffer->height / 2 - 1) + buffer->width - 1; 6930ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 6940ab416269a866c8afa8f65d9351afa2407abee4cZhijun He pData = 6950ab416269a866c8afa8f65d9351afa2407abee4cZhijun He (idx == 0) ? 6960ab416269a866c8afa8f65d9351afa2407abee4cZhijun He buffer->data : 6970ab416269a866c8afa8f65d9351afa2407abee4cZhijun He (idx == 1) ? 6980ab416269a866c8afa8f65d9351afa2407abee4cZhijun He cb: 6990ab416269a866c8afa8f65d9351afa2407abee4cZhijun He cr; 7000ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 7010ab416269a866c8afa8f65d9351afa2407abee4cZhijun He dataSize = (idx == 0) ? ySize : cSize; 7020ab416269a866c8afa8f65d9351afa2407abee4cZhijun He pStride = (idx == 0) ? 1 : 2; 7030ab416269a866c8afa8f65d9351afa2407abee4cZhijun He rStride = buffer->width; 7040ab416269a866c8afa8f65d9351afa2407abee4cZhijun He break; 7050ab416269a866c8afa8f65d9351afa2407abee4cZhijun He case HAL_PIXEL_FORMAT_YV12: 7060ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Y and C stride need to be 16 pixel aligned. 7070ab416269a866c8afa8f65d9351afa2407abee4cZhijun He LOG_ALWAYS_FATAL_IF(buffer->stride % 16, 7080ab416269a866c8afa8f65d9351afa2407abee4cZhijun He "Stride is not 16 pixel aligned %d", buffer->stride); 7090ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 7100ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ySize = buffer->stride * buffer->height; 7110ab416269a866c8afa8f65d9351afa2407abee4cZhijun He cStride = ALIGN(buffer->stride / 2, 16); 7120ab416269a866c8afa8f65d9351afa2407abee4cZhijun He cr = buffer->data + ySize; 7130ab416269a866c8afa8f65d9351afa2407abee4cZhijun He cSize = cStride * buffer->height / 2; 7140ab416269a866c8afa8f65d9351afa2407abee4cZhijun He cb = cr + cSize; 7150ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 7160ab416269a866c8afa8f65d9351afa2407abee4cZhijun He pData = 7170ab416269a866c8afa8f65d9351afa2407abee4cZhijun He (idx == 0) ? 7180ab416269a866c8afa8f65d9351afa2407abee4cZhijun He buffer->data : 7190ab416269a866c8afa8f65d9351afa2407abee4cZhijun He (idx == 1) ? 7200ab416269a866c8afa8f65d9351afa2407abee4cZhijun He cb : 7210ab416269a866c8afa8f65d9351afa2407abee4cZhijun He cr; 7220ab416269a866c8afa8f65d9351afa2407abee4cZhijun He dataSize = (idx == 0) ? ySize : cSize; 7230ab416269a866c8afa8f65d9351afa2407abee4cZhijun He pStride = 1; 7240ab416269a866c8afa8f65d9351afa2407abee4cZhijun He rStride = (idx == 0) ? buffer->stride : ALIGN(buffer->stride / 2, 16); 7250ab416269a866c8afa8f65d9351afa2407abee4cZhijun He break; 7260ab416269a866c8afa8f65d9351afa2407abee4cZhijun He case HAL_PIXEL_FORMAT_Y8: 7270ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Single plane, 8bpp. 7280ab416269a866c8afa8f65d9351afa2407abee4cZhijun He LOG_ALWAYS_FATAL_IF(idx != 0, "Wrong index: %d", idx); 7290ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 7300ab416269a866c8afa8f65d9351afa2407abee4cZhijun He pData = buffer->data; 7310ab416269a866c8afa8f65d9351afa2407abee4cZhijun He dataSize = buffer->stride * buffer->height; 7320ab416269a866c8afa8f65d9351afa2407abee4cZhijun He pStride = 1; 7330ab416269a866c8afa8f65d9351afa2407abee4cZhijun He rStride = buffer->stride; 7340ab416269a866c8afa8f65d9351afa2407abee4cZhijun He break; 7350ab416269a866c8afa8f65d9351afa2407abee4cZhijun He case HAL_PIXEL_FORMAT_Y16: 7360ab416269a866c8afa8f65d9351afa2407abee4cZhijun He bytesPerPixel = 2; 7370ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Single plane, 16bpp, strides are specified in pixels, not in bytes 7380ab416269a866c8afa8f65d9351afa2407abee4cZhijun He LOG_ALWAYS_FATAL_IF(idx != 0, "Wrong index: %d", idx); 7390ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 7400ab416269a866c8afa8f65d9351afa2407abee4cZhijun He pData = buffer->data; 7410ab416269a866c8afa8f65d9351afa2407abee4cZhijun He dataSize = buffer->stride * buffer->height * bytesPerPixel; 7420ab416269a866c8afa8f65d9351afa2407abee4cZhijun He pStride = bytesPerPixel; 7430ab416269a866c8afa8f65d9351afa2407abee4cZhijun He rStride = buffer->stride * 2; 7440ab416269a866c8afa8f65d9351afa2407abee4cZhijun He break; 7450ab416269a866c8afa8f65d9351afa2407abee4cZhijun He case HAL_PIXEL_FORMAT_BLOB: 7460ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Used for JPEG data, height must be 1, width == size, single plane. 7470ab416269a866c8afa8f65d9351afa2407abee4cZhijun He LOG_ALWAYS_FATAL_IF(idx != 0, "Wrong index: %d", idx); 7487b7909025276dc9c78afb68c84a77f2ee5456b4dYin-Chia Yeh // When RGBA override is being used, buffer height will be equal to width 7497b7909025276dc9c78afb68c84a77f2ee5456b4dYin-Chia Yeh if (usingRGBAOverride) { 7507b7909025276dc9c78afb68c84a77f2ee5456b4dYin-Chia Yeh LOG_ALWAYS_FATAL_IF(buffer->height != buffer->width, 7517b7909025276dc9c78afb68c84a77f2ee5456b4dYin-Chia Yeh "RGBA override BLOB format buffer should have height == width"); 7527b7909025276dc9c78afb68c84a77f2ee5456b4dYin-Chia Yeh } else { 7537b7909025276dc9c78afb68c84a77f2ee5456b4dYin-Chia Yeh LOG_ALWAYS_FATAL_IF(buffer->height != 1, 7547b7909025276dc9c78afb68c84a77f2ee5456b4dYin-Chia Yeh "BLOB format buffer should have height value 1"); 7557b7909025276dc9c78afb68c84a77f2ee5456b4dYin-Chia Yeh } 7567b7909025276dc9c78afb68c84a77f2ee5456b4dYin-Chia Yeh 7570ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 7580ab416269a866c8afa8f65d9351afa2407abee4cZhijun He pData = buffer->data; 7590ab416269a866c8afa8f65d9351afa2407abee4cZhijun He dataSize = Image_getJpegSize(buffer, usingRGBAOverride); 7600ab416269a866c8afa8f65d9351afa2407abee4cZhijun He pStride = 0; 7610ab416269a866c8afa8f65d9351afa2407abee4cZhijun He rStride = 0; 7620ab416269a866c8afa8f65d9351afa2407abee4cZhijun He break; 7630ab416269a866c8afa8f65d9351afa2407abee4cZhijun He case HAL_PIXEL_FORMAT_RAW16: 7640ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Single plane 16bpp bayer data. 7650ab416269a866c8afa8f65d9351afa2407abee4cZhijun He bytesPerPixel = 2; 7660ab416269a866c8afa8f65d9351afa2407abee4cZhijun He LOG_ALWAYS_FATAL_IF(idx != 0, "Wrong index: %d", idx); 7670ab416269a866c8afa8f65d9351afa2407abee4cZhijun He pData = buffer->data; 7680ab416269a866c8afa8f65d9351afa2407abee4cZhijun He dataSize = buffer->stride * buffer->height * bytesPerPixel; 7690ab416269a866c8afa8f65d9351afa2407abee4cZhijun He pStride = bytesPerPixel; 7700ab416269a866c8afa8f65d9351afa2407abee4cZhijun He rStride = buffer->stride * 2; 7710ab416269a866c8afa8f65d9351afa2407abee4cZhijun He break; 7720ab416269a866c8afa8f65d9351afa2407abee4cZhijun He case HAL_PIXEL_FORMAT_RAW_OPAQUE: 7730ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Used for RAW_OPAQUE data, height must be 1, width == size, single plane. 7740ab416269a866c8afa8f65d9351afa2407abee4cZhijun He LOG_ALWAYS_FATAL_IF(idx != 0, "Wrong index: %d", idx); 7750ab416269a866c8afa8f65d9351afa2407abee4cZhijun He LOG_ALWAYS_FATAL_IF(buffer->height != 1, 7760ab416269a866c8afa8f65d9351afa2407abee4cZhijun He "RAW_PRIVATE should has height value one but got %d", buffer->height); 7770ab416269a866c8afa8f65d9351afa2407abee4cZhijun He pData = buffer->data; 7780ab416269a866c8afa8f65d9351afa2407abee4cZhijun He dataSize = buffer->width; 7790ab416269a866c8afa8f65d9351afa2407abee4cZhijun He pStride = 0; // RAW OPAQUE doesn't have pixel stride 7800ab416269a866c8afa8f65d9351afa2407abee4cZhijun He rStride = 0; // RAW OPAQUE doesn't have row stride 7810ab416269a866c8afa8f65d9351afa2407abee4cZhijun He break; 7820ab416269a866c8afa8f65d9351afa2407abee4cZhijun He case HAL_PIXEL_FORMAT_RAW10: 7830ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Single plane 10bpp bayer data. 7840ab416269a866c8afa8f65d9351afa2407abee4cZhijun He LOG_ALWAYS_FATAL_IF(idx != 0, "Wrong index: %d", idx); 7850ab416269a866c8afa8f65d9351afa2407abee4cZhijun He LOG_ALWAYS_FATAL_IF(buffer->width % 4, 7860ab416269a866c8afa8f65d9351afa2407abee4cZhijun He "Width is not multiple of 4 %d", buffer->width); 7870ab416269a866c8afa8f65d9351afa2407abee4cZhijun He LOG_ALWAYS_FATAL_IF(buffer->height % 2, 7880ab416269a866c8afa8f65d9351afa2407abee4cZhijun He "Height is not even %d", buffer->height); 7890ab416269a866c8afa8f65d9351afa2407abee4cZhijun He LOG_ALWAYS_FATAL_IF(buffer->stride < (buffer->width * 10 / 8), 7900ab416269a866c8afa8f65d9351afa2407abee4cZhijun He "stride (%d) should be at least %d", 7910ab416269a866c8afa8f65d9351afa2407abee4cZhijun He buffer->stride, buffer->width * 10 / 8); 7920ab416269a866c8afa8f65d9351afa2407abee4cZhijun He pData = buffer->data; 7930ab416269a866c8afa8f65d9351afa2407abee4cZhijun He dataSize = buffer->stride * buffer->height; 7940ab416269a866c8afa8f65d9351afa2407abee4cZhijun He pStride = 0; 7950ab416269a866c8afa8f65d9351afa2407abee4cZhijun He rStride = buffer->stride; 7960ab416269a866c8afa8f65d9351afa2407abee4cZhijun He break; 7970ab416269a866c8afa8f65d9351afa2407abee4cZhijun He case HAL_PIXEL_FORMAT_RAW12: 7980ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Single plane 10bpp bayer data. 7990ab416269a866c8afa8f65d9351afa2407abee4cZhijun He LOG_ALWAYS_FATAL_IF(idx != 0, "Wrong index: %d", idx); 8000ab416269a866c8afa8f65d9351afa2407abee4cZhijun He LOG_ALWAYS_FATAL_IF(buffer->width % 4, 8010ab416269a866c8afa8f65d9351afa2407abee4cZhijun He "Width is not multiple of 4 %d", buffer->width); 8020ab416269a866c8afa8f65d9351afa2407abee4cZhijun He LOG_ALWAYS_FATAL_IF(buffer->height % 2, 8030ab416269a866c8afa8f65d9351afa2407abee4cZhijun He "Height is not even %d", buffer->height); 8040ab416269a866c8afa8f65d9351afa2407abee4cZhijun He LOG_ALWAYS_FATAL_IF(buffer->stride < (buffer->width * 12 / 8), 8050ab416269a866c8afa8f65d9351afa2407abee4cZhijun He "stride (%d) should be at least %d", 8060ab416269a866c8afa8f65d9351afa2407abee4cZhijun He buffer->stride, buffer->width * 12 / 8); 8070ab416269a866c8afa8f65d9351afa2407abee4cZhijun He pData = buffer->data; 8080ab416269a866c8afa8f65d9351afa2407abee4cZhijun He dataSize = buffer->stride * buffer->height; 8090ab416269a866c8afa8f65d9351afa2407abee4cZhijun He pStride = 0; 8100ab416269a866c8afa8f65d9351afa2407abee4cZhijun He rStride = buffer->stride; 8110ab416269a866c8afa8f65d9351afa2407abee4cZhijun He break; 8120ab416269a866c8afa8f65d9351afa2407abee4cZhijun He case HAL_PIXEL_FORMAT_RGBA_8888: 8130ab416269a866c8afa8f65d9351afa2407abee4cZhijun He case HAL_PIXEL_FORMAT_RGBX_8888: 8140ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Single plane, 32bpp. 8150ab416269a866c8afa8f65d9351afa2407abee4cZhijun He bytesPerPixel = 4; 8160ab416269a866c8afa8f65d9351afa2407abee4cZhijun He LOG_ALWAYS_FATAL_IF(idx != 0, "Wrong index: %d", idx); 8170ab416269a866c8afa8f65d9351afa2407abee4cZhijun He pData = buffer->data; 8180ab416269a866c8afa8f65d9351afa2407abee4cZhijun He dataSize = buffer->stride * buffer->height * bytesPerPixel; 8190ab416269a866c8afa8f65d9351afa2407abee4cZhijun He pStride = bytesPerPixel; 8200ab416269a866c8afa8f65d9351afa2407abee4cZhijun He rStride = buffer->stride * 4; 8210ab416269a866c8afa8f65d9351afa2407abee4cZhijun He break; 8220ab416269a866c8afa8f65d9351afa2407abee4cZhijun He case HAL_PIXEL_FORMAT_RGB_565: 8230ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Single plane, 16bpp. 8240ab416269a866c8afa8f65d9351afa2407abee4cZhijun He bytesPerPixel = 2; 8250ab416269a866c8afa8f65d9351afa2407abee4cZhijun He LOG_ALWAYS_FATAL_IF(idx != 0, "Wrong index: %d", idx); 8260ab416269a866c8afa8f65d9351afa2407abee4cZhijun He pData = buffer->data; 8270ab416269a866c8afa8f65d9351afa2407abee4cZhijun He dataSize = buffer->stride * buffer->height * bytesPerPixel; 8280ab416269a866c8afa8f65d9351afa2407abee4cZhijun He pStride = bytesPerPixel; 8290ab416269a866c8afa8f65d9351afa2407abee4cZhijun He rStride = buffer->stride * 2; 8300ab416269a866c8afa8f65d9351afa2407abee4cZhijun He break; 8310ab416269a866c8afa8f65d9351afa2407abee4cZhijun He case HAL_PIXEL_FORMAT_RGB_888: 8320ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Single plane, 24bpp. 8330ab416269a866c8afa8f65d9351afa2407abee4cZhijun He bytesPerPixel = 3; 8340ab416269a866c8afa8f65d9351afa2407abee4cZhijun He LOG_ALWAYS_FATAL_IF(idx != 0, "Wrong index: %d", idx); 8350ab416269a866c8afa8f65d9351afa2407abee4cZhijun He pData = buffer->data; 8360ab416269a866c8afa8f65d9351afa2407abee4cZhijun He dataSize = buffer->stride * buffer->height * bytesPerPixel; 8370ab416269a866c8afa8f65d9351afa2407abee4cZhijun He pStride = bytesPerPixel; 8380ab416269a866c8afa8f65d9351afa2407abee4cZhijun He rStride = buffer->stride * 3; 8390ab416269a866c8afa8f65d9351afa2407abee4cZhijun He break; 8400ab416269a866c8afa8f65d9351afa2407abee4cZhijun He default: 8410ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return BAD_VALUE; 8420ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 8430ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 8440ab416269a866c8afa8f65d9351afa2407abee4cZhijun He *base = pData; 8450ab416269a866c8afa8f65d9351afa2407abee4cZhijun He *size = dataSize; 8460ab416269a866c8afa8f65d9351afa2407abee4cZhijun He *pixelStride = pStride; 8470ab416269a866c8afa8f65d9351afa2407abee4cZhijun He *rowStride = rStride; 8480ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 8490ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return OK; 8500ab416269a866c8afa8f65d9351afa2407abee4cZhijun He} 8510ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 8520ab416269a866c8afa8f65d9351afa2407abee4cZhijun Hestatus_t lockImageFromBuffer(sp<GraphicBuffer> buffer, uint32_t inUsage, 8530ab416269a866c8afa8f65d9351afa2407abee4cZhijun He const Rect& rect, int fenceFd, LockedImage* outputImage) { 8540ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGV("%s: Try to lock the GraphicBuffer", __FUNCTION__); 8550ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 8560ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (buffer == nullptr || outputImage == nullptr) { 8570ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGE("Input BufferItem or output LockedImage is NULL!"); 8580ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return BAD_VALUE; 8590ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 8600ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (isFormatOpaque(buffer->getPixelFormat())) { 8610ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGE("Opaque format buffer is not lockable!"); 8620ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return BAD_VALUE; 8630ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 8640ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 8650ab416269a866c8afa8f65d9351afa2407abee4cZhijun He void* pData = NULL; 8660ab416269a866c8afa8f65d9351afa2407abee4cZhijun He android_ycbcr ycbcr = android_ycbcr(); 8670ab416269a866c8afa8f65d9351afa2407abee4cZhijun He status_t res; 8680ab416269a866c8afa8f65d9351afa2407abee4cZhijun He int format = buffer->getPixelFormat(); 8690ab416269a866c8afa8f65d9351afa2407abee4cZhijun He int flexFormat = format; 8700ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (isPossiblyYUV(format)) { 8710ab416269a866c8afa8f65d9351afa2407abee4cZhijun He res = buffer->lockAsyncYCbCr(inUsage, rect, &ycbcr, fenceFd); 8720ab416269a866c8afa8f65d9351afa2407abee4cZhijun He pData = ycbcr.y; 8730ab416269a866c8afa8f65d9351afa2407abee4cZhijun He flexFormat = HAL_PIXEL_FORMAT_YCbCr_420_888; 8740ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 8750ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 8760ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // lockAsyncYCbCr for YUV is unsuccessful. 8770ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (pData == NULL) { 8780ab416269a866c8afa8f65d9351afa2407abee4cZhijun He res = buffer->lockAsync(inUsage, rect, &pData, fenceFd); 8790ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (res != OK) { 8800ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGE("Lock buffer failed!"); 8810ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return res; 8820ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 8830ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 8840ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 8850ab416269a866c8afa8f65d9351afa2407abee4cZhijun He outputImage->data = reinterpret_cast<uint8_t*>(pData); 8860ab416269a866c8afa8f65d9351afa2407abee4cZhijun He outputImage->width = buffer->getWidth(); 8870ab416269a866c8afa8f65d9351afa2407abee4cZhijun He outputImage->height = buffer->getHeight(); 8880ab416269a866c8afa8f65d9351afa2407abee4cZhijun He outputImage->format = format; 8890ab416269a866c8afa8f65d9351afa2407abee4cZhijun He outputImage->flexFormat = flexFormat; 8900ab416269a866c8afa8f65d9351afa2407abee4cZhijun He outputImage->stride = 8910ab416269a866c8afa8f65d9351afa2407abee4cZhijun He (ycbcr.y != NULL) ? static_cast<uint32_t>(ycbcr.ystride) : buffer->getStride(); 8920ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 8930ab416269a866c8afa8f65d9351afa2407abee4cZhijun He outputImage->dataCb = reinterpret_cast<uint8_t*>(ycbcr.cb); 8940ab416269a866c8afa8f65d9351afa2407abee4cZhijun He outputImage->dataCr = reinterpret_cast<uint8_t*>(ycbcr.cr); 8950ab416269a866c8afa8f65d9351afa2407abee4cZhijun He outputImage->chromaStride = static_cast<uint32_t>(ycbcr.cstride); 8960ab416269a866c8afa8f65d9351afa2407abee4cZhijun He outputImage->chromaStep = static_cast<uint32_t>(ycbcr.chroma_step); 8970ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGV("%s: Successfully locked the image from the GraphicBuffer", __FUNCTION__); 8980ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Crop, transform, scalingMode, timestamp, and frameNumber should be set by caller, 8990ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // and cann't be set them here. 9000ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return OK; 9010ab416269a866c8afa8f65d9351afa2407abee4cZhijun He} 9020ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 9030ab416269a866c8afa8f65d9351afa2407abee4cZhijun Hestatus_t lockImageFromBuffer(BufferItem* bufferItem, uint32_t inUsage, 9040ab416269a866c8afa8f65d9351afa2407abee4cZhijun He int fenceFd, LockedImage* outputImage) { 9050ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGV("%s: Try to lock the BufferItem", __FUNCTION__); 9060ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (bufferItem == nullptr || outputImage == nullptr) { 9070ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGE("Input BufferItem or output LockedImage is NULL!"); 9080ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return BAD_VALUE; 9090ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 9100ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 9110ab416269a866c8afa8f65d9351afa2407abee4cZhijun He status_t res = lockImageFromBuffer(bufferItem->mGraphicBuffer, inUsage, bufferItem->mCrop, 9120ab416269a866c8afa8f65d9351afa2407abee4cZhijun He fenceFd, outputImage); 9130ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (res != OK) { 9140ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGE("%s: lock graphic buffer failed", __FUNCTION__); 9150ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return res; 9160ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 9170ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 9180ab416269a866c8afa8f65d9351afa2407abee4cZhijun He outputImage->crop = bufferItem->mCrop; 9190ab416269a866c8afa8f65d9351afa2407abee4cZhijun He outputImage->transform = bufferItem->mTransform; 9200ab416269a866c8afa8f65d9351afa2407abee4cZhijun He outputImage->scalingMode = bufferItem->mScalingMode; 9210ab416269a866c8afa8f65d9351afa2407abee4cZhijun He outputImage->timestamp = bufferItem->mTimestamp; 9220ab416269a866c8afa8f65d9351afa2407abee4cZhijun He outputImage->dataSpace = bufferItem->mDataSpace; 9230ab416269a866c8afa8f65d9351afa2407abee4cZhijun He outputImage->frameNumber = bufferItem->mFrameNumber; 9240ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGV("%s: Successfully locked the image from the BufferItem", __FUNCTION__); 9250ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return OK; 9260ab416269a866c8afa8f65d9351afa2407abee4cZhijun He} 9270ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 9280ab416269a866c8afa8f65d9351afa2407abee4cZhijun Heint getBufferWidth(BufferItem* buffer) { 9290ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (buffer == NULL) return -1; 9300ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 9310ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (!buffer->mCrop.isEmpty()) { 9320ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return buffer->mCrop.getWidth(); 9330ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 9340ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 9350ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGV("%s: buffer->mGraphicBuffer: %p", __FUNCTION__, buffer->mGraphicBuffer.get()); 9360ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return buffer->mGraphicBuffer->getWidth(); 9370ab416269a866c8afa8f65d9351afa2407abee4cZhijun He} 9380ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 9390ab416269a866c8afa8f65d9351afa2407abee4cZhijun Heint getBufferHeight(BufferItem* buffer) { 9400ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (buffer == NULL) return -1; 9410ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 9420ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (!buffer->mCrop.isEmpty()) { 9430ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return buffer->mCrop.getHeight(); 9440ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 9450ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 9460ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGV("%s: buffer->mGraphicBuffer: %p", __FUNCTION__, buffer->mGraphicBuffer.get()); 9470ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return buffer->mGraphicBuffer->getHeight(); 9480ab416269a866c8afa8f65d9351afa2407abee4cZhijun He} 9490ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 95079f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong} // namespace android 95179f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong 952