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 } 71cad166686787a494b6689b8adb013e016adfcd90Yujie Qin 726e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung void* tempBuffer = malloc(sizeToRead); 73cad166686787a494b6689b8adb013e016adfcd90Yujie Qin if (tempBuffer == NULL) { 74cad166686787a494b6689b8adb013e016adfcd90Yujie Qin return piex::Error::kFail; 75cad166686787a494b6689b8adb013e016adfcd90Yujie Qin } 76cad166686787a494b6689b8adb013e016adfcd90Yujie Qin 77cad166686787a494b6689b8adb013e016adfcd90Yujie Qin size_t bytesRead = mStream->read(tempBuffer, sizeToRead); 78cad166686787a494b6689b8adb013e016adfcd90Yujie Qin if (bytesRead != sizeToRead) { 796e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung free(tempBuffer); 80cad166686787a494b6689b8adb013e016adfcd90Yujie Qin return piex::Error::kFail; 816e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung } 82cad166686787a494b6689b8adb013e016adfcd90Yujie Qin mStreamBuffer.write(tempBuffer, bytesRead); 83cad166686787a494b6689b8adb013e016adfcd90Yujie Qin free(tempBuffer); 846e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung } 856e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung 866e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung // Read bytes. 876e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung if (mStreamBuffer.read((void*)data, offset, length)) { 886e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung return piex::Error::kOk; 896e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung } else { 906e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung return piex::Error::kFail; 916e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung } 926e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung} 936e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung 9415ef59e081846b43660635391d536361c3253a22Jaesung ChungFileStream::FileStream(const int fd) 956e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung : mPosition(0) { 9615ef59e081846b43660635391d536361c3253a22Jaesung Chung mFile = fdopen(fd, "r"); 9715ef59e081846b43660635391d536361c3253a22Jaesung Chung if (mFile == NULL) { 9815ef59e081846b43660635391d536361c3253a22Jaesung Chung return; 9915ef59e081846b43660635391d536361c3253a22Jaesung Chung } 10015ef59e081846b43660635391d536361c3253a22Jaesung Chung} 10115ef59e081846b43660635391d536361c3253a22Jaesung Chung 1028409c0691fb128fef6244305977342776bddf919Jaesung ChungFileStream::FileStream(const String8 filename) 1036e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung : mPosition(0) { 1048409c0691fb128fef6244305977342776bddf919Jaesung Chung mFile = fopen(filename.string(), "r"); 1058409c0691fb128fef6244305977342776bddf919Jaesung Chung if (mFile == NULL) { 1068409c0691fb128fef6244305977342776bddf919Jaesung Chung return; 1078409c0691fb128fef6244305977342776bddf919Jaesung Chung } 1088409c0691fb128fef6244305977342776bddf919Jaesung Chung} 1098409c0691fb128fef6244305977342776bddf919Jaesung Chung 1108409c0691fb128fef6244305977342776bddf919Jaesung ChungFileStream::~FileStream() { 1118409c0691fb128fef6244305977342776bddf919Jaesung Chung if (mFile != NULL) { 1128409c0691fb128fef6244305977342776bddf919Jaesung Chung fclose(mFile); 1138409c0691fb128fef6244305977342776bddf919Jaesung Chung mFile = NULL; 1148409c0691fb128fef6244305977342776bddf919Jaesung Chung } 1158409c0691fb128fef6244305977342776bddf919Jaesung Chung} 1168409c0691fb128fef6244305977342776bddf919Jaesung Chung 1178409c0691fb128fef6244305977342776bddf919Jaesung Chungpiex::Error FileStream::GetData( 1188409c0691fb128fef6244305977342776bddf919Jaesung Chung const size_t offset, const size_t length, std::uint8_t* data) { 1198409c0691fb128fef6244305977342776bddf919Jaesung Chung if (mFile == NULL) { 1208409c0691fb128fef6244305977342776bddf919Jaesung Chung return piex::Error::kFail; 1218409c0691fb128fef6244305977342776bddf919Jaesung Chung } 1228409c0691fb128fef6244305977342776bddf919Jaesung Chung 1238409c0691fb128fef6244305977342776bddf919Jaesung Chung // Seek first. 1248409c0691fb128fef6244305977342776bddf919Jaesung Chung if (mPosition != offset) { 1258409c0691fb128fef6244305977342776bddf919Jaesung Chung fseek(mFile, offset, SEEK_SET); 1268409c0691fb128fef6244305977342776bddf919Jaesung Chung } 1278409c0691fb128fef6244305977342776bddf919Jaesung Chung 1288409c0691fb128fef6244305977342776bddf919Jaesung Chung // Read bytes. 1298409c0691fb128fef6244305977342776bddf919Jaesung Chung size_t size = fread((void*)data, sizeof(std::uint8_t), length, mFile); 1308409c0691fb128fef6244305977342776bddf919Jaesung Chung mPosition += size; 1318409c0691fb128fef6244305977342776bddf919Jaesung Chung 132cad166686787a494b6689b8adb013e016adfcd90Yujie Qin // Handle errors and verify the size. 133cad166686787a494b6689b8adb013e016adfcd90Yujie Qin if (ferror(mFile) || size != length) { 1348409c0691fb128fef6244305977342776bddf919Jaesung Chung ALOGV("GetData read failed: (offset: %zu, length: %zu)", offset, length); 1358409c0691fb128fef6244305977342776bddf919Jaesung Chung return piex::Error::kFail; 1368409c0691fb128fef6244305977342776bddf919Jaesung Chung } 1378409c0691fb128fef6244305977342776bddf919Jaesung Chung return piex::Error::kOk; 1388409c0691fb128fef6244305977342776bddf919Jaesung Chung} 1398409c0691fb128fef6244305977342776bddf919Jaesung Chung 1408409c0691fb128fef6244305977342776bddf919Jaesung Chungbool FileStream::exists() const { 1418409c0691fb128fef6244305977342776bddf919Jaesung Chung return mFile != NULL; 1428409c0691fb128fef6244305977342776bddf919Jaesung Chung} 1438409c0691fb128fef6244305977342776bddf919Jaesung Chung 1448409c0691fb128fef6244305977342776bddf919Jaesung Chungbool GetExifFromRawImage( 1456e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung piex::StreamInterface* stream, const String8& filename, 1466e08d2b082acfc773907733f2ddab4e9b60616e1Jaesung Chung piex::PreviewImageData& image_data) { 1478f7a8f1eba590f4a0bb21988fc2a876dcb72dccdAnton Daubert // Reset the PreviewImageData to its default. 1488f7a8f1eba590f4a0bb21988fc2a876dcb72dccdAnton Daubert image_data = piex::PreviewImageData(); 1498409c0691fb128fef6244305977342776bddf919Jaesung Chung 1508409c0691fb128fef6244305977342776bddf919Jaesung Chung if (!piex::IsRaw(stream)) { 1518409c0691fb128fef6244305977342776bddf919Jaesung Chung // Format not supported. 1528409c0691fb128fef6244305977342776bddf919Jaesung Chung ALOGV("Format not supported: %s", filename.string()); 1538409c0691fb128fef6244305977342776bddf919Jaesung Chung return false; 1548409c0691fb128fef6244305977342776bddf919Jaesung Chung } 1558409c0691fb128fef6244305977342776bddf919Jaesung Chung 1568409c0691fb128fef6244305977342776bddf919Jaesung Chung piex::Error err = piex::GetPreviewImageData(stream, &image_data); 1578409c0691fb128fef6244305977342776bddf919Jaesung Chung 1588409c0691fb128fef6244305977342776bddf919Jaesung Chung if (err != piex::Error::kOk) { 1598409c0691fb128fef6244305977342776bddf919Jaesung Chung // The input data seems to be broken. 1608409c0691fb128fef6244305977342776bddf919Jaesung Chung ALOGV("Raw image not detected: %s (piex error code: %d)", filename.string(), (int32_t)err); 1618409c0691fb128fef6244305977342776bddf919Jaesung Chung return false; 1628409c0691fb128fef6244305977342776bddf919Jaesung Chung } 1638409c0691fb128fef6244305977342776bddf919Jaesung Chung 1648409c0691fb128fef6244305977342776bddf919Jaesung Chung return true; 1658409c0691fb128fef6244305977342776bddf919Jaesung Chung} 1668409c0691fb128fef6244305977342776bddf919Jaesung Chung 16779f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dongbool ConvertKeyValueArraysToKeyedVector( 16879f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong JNIEnv *env, jobjectArray keys, jobjectArray values, 16979f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong KeyedVector<String8, String8>* keyedVector) { 17079f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong 17179f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong int nKeyValuePairs = 0; 17279f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong bool failed = false; 17379f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong if (keys != NULL && values != NULL) { 17479f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong nKeyValuePairs = env->GetArrayLength(keys); 17579f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong failed = (nKeyValuePairs != env->GetArrayLength(values)); 17679f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong } 17779f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong 17879f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong if (!failed) { 17979f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong failed = ((keys != NULL && values == NULL) || 18079f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong (keys == NULL && values != NULL)); 18179f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong } 18279f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong 18379f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong if (failed) { 1843762c311729fe9f3af085c14c5c1fb471d994c03Steve Block ALOGE("keys and values arrays have different length"); 18579f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong jniThrowException(env, "java/lang/IllegalArgumentException", NULL); 18679f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong return false; 18779f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong } 18879f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong 18979f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong for (int i = 0; i < nKeyValuePairs; ++i) { 19079f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong // No need to check on the ArrayIndexOutOfBoundsException, since 19179f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong // it won't happen here. 19279f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong jstring key = (jstring) env->GetObjectArrayElement(keys, i); 19379f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong jstring value = (jstring) env->GetObjectArrayElement(values, i); 19479f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong 19579f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong const char* keyStr = env->GetStringUTFChars(key, NULL); 19679f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong if (!keyStr) { // OutOfMemoryError 19779f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong return false; 19879f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong } 19979f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong 20079f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong const char* valueStr = env->GetStringUTFChars(value, NULL); 20179f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong if (!valueStr) { // OutOfMemoryError 20279f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong env->ReleaseStringUTFChars(key, keyStr); 20379f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong return false; 20479f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong } 20579f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong 20679f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong keyedVector->add(String8(keyStr), String8(valueStr)); 20779f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong 20879f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong env->ReleaseStringUTFChars(key, keyStr); 20979f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong env->ReleaseStringUTFChars(value, valueStr); 21079f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong env->DeleteLocalRef(key); 21179f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong env->DeleteLocalRef(value); 21279f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong } 21379f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong return true; 21479f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong} 21579f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong 21688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic jobject makeIntegerObject(JNIEnv *env, int32_t value) { 2178d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber ScopedLocalRef<jclass> clazz(env, env->FindClass("java/lang/Integer")); 2188d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber CHECK(clazz.get() != NULL); 21988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 2208d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber jmethodID integerConstructID = 2218d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env->GetMethodID(clazz.get(), "<init>", "(I)V"); 22288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(integerConstructID != NULL); 22388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 2248d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber return env->NewObject(clazz.get(), integerConstructID, value); 22588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 22688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 22707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huberstatic jobject makeLongObject(JNIEnv *env, int64_t value) { 2288d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber ScopedLocalRef<jclass> clazz(env, env->FindClass("java/lang/Long")); 2298d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber CHECK(clazz.get() != NULL); 23007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber 2318d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber jmethodID longConstructID = env->GetMethodID(clazz.get(), "<init>", "(J)V"); 23207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber CHECK(longConstructID != NULL); 23307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber 2348d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber return env->NewObject(clazz.get(), longConstructID, value); 23507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber} 23607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber 23788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic jobject makeFloatObject(JNIEnv *env, float value) { 2388d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber ScopedLocalRef<jclass> clazz(env, env->FindClass("java/lang/Float")); 2398d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber CHECK(clazz.get() != NULL); 24088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 2418d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber jmethodID floatConstructID = 2428d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env->GetMethodID(clazz.get(), "<init>", "(F)V"); 24388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(floatConstructID != NULL); 24488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 2458d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber return env->NewObject(clazz.get(), floatConstructID, value); 24688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 24788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 24888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic jobject makeByteBufferObject( 24988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, const void *data, size_t size) { 25088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jbyteArray byteArrayObj = env->NewByteArray(size); 25188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->SetByteArrayRegion(byteArrayObj, 0, size, (const jbyte *)data); 25288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 2538d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber ScopedLocalRef<jclass> clazz(env, env->FindClass("java/nio/ByteBuffer")); 2548d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber CHECK(clazz.get() != NULL); 25588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 25688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jmethodID byteBufWrapID = 2578d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env->GetStaticMethodID( 2588d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber clazz.get(), "wrap", "([B)Ljava/nio/ByteBuffer;"); 25988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(byteBufWrapID != NULL); 26088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 26188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobject byteBufObj = env->CallStaticObjectMethod( 2628d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber clazz.get(), byteBufWrapID, byteArrayObj); 26388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 26488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->DeleteLocalRef(byteArrayObj); byteArrayObj = NULL; 26588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 26688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return byteBufObj; 26788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 26888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 269b842599e51e2d3611503c3c7db1111358f99186dAndreas Huberstatic void SetMapInt32( 270b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber JNIEnv *env, jobject hashMapObj, jmethodID hashMapPutID, 271b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber const char *key, int32_t value) { 272b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber jstring keyObj = env->NewStringUTF(key); 273b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber jobject valueObj = makeIntegerObject(env, value); 274b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber 2755a15d0d31b877ef512b3379eac033c6bb041c86aAndreas Gampe env->CallObjectMethod(hashMapObj, hashMapPutID, keyObj, valueObj); 276b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber 277b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber env->DeleteLocalRef(valueObj); valueObj = NULL; 278b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber env->DeleteLocalRef(keyObj); keyObj = NULL; 279b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber} 280b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber 28188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t ConvertMessageToMap( 28288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, const sp<AMessage> &msg, jobject *map) { 2838d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber ScopedLocalRef<jclass> hashMapClazz( 2848d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env, env->FindClass("java/util/HashMap")); 28588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 2868d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber if (hashMapClazz.get() == NULL) { 28788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return -EINVAL; 28888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 28988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 29088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jmethodID hashMapConstructID = 2918d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env->GetMethodID(hashMapClazz.get(), "<init>", "()V"); 29288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 29388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (hashMapConstructID == NULL) { 29488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return -EINVAL; 29588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 29688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 29788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jmethodID hashMapPutID = 29888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->GetMethodID( 2998d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber hashMapClazz.get(), 30088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber "put", 30188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); 30288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 30388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (hashMapPutID == NULL) { 30488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return -EINVAL; 30588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 30688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 3078d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber jobject hashMap = env->NewObject(hashMapClazz.get(), hashMapConstructID); 30888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 30988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber for (size_t i = 0; i < msg->countEntries(); ++i) { 31088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber AMessage::Type valueType; 31188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber const char *key = msg->getEntryNameAt(i, &valueType); 31288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 313c04399feab8e51531975a4b404327511b094bbf6Lajos Molnar if (!strncmp(key, "android._", 9)) { 314c04399feab8e51531975a4b404327511b094bbf6Lajos Molnar // don't expose private keys (starting with android._) 315c04399feab8e51531975a4b404327511b094bbf6Lajos Molnar continue; 316c04399feab8e51531975a4b404327511b094bbf6Lajos Molnar } 317c04399feab8e51531975a4b404327511b094bbf6Lajos Molnar 31888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobject valueObj = NULL; 31988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 32088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber switch (valueType) { 32188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber case AMessage::kTypeInt32: 32288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { 32388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber int32_t val; 32488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(msg->findInt32(key, &val)); 32588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 32688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber valueObj = makeIntegerObject(env, val); 32707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber break; 32807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber } 32907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber 33007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber case AMessage::kTypeInt64: 33107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber { 33207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber int64_t val; 33307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber CHECK(msg->findInt64(key, &val)); 33407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber 33507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber valueObj = makeLongObject(env, val); 33688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber break; 33788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 33888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 33988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber case AMessage::kTypeFloat: 34088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { 34188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber float val; 34288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(msg->findFloat(key, &val)); 34388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 34488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber valueObj = makeFloatObject(env, val); 34588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber break; 34688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 34788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 34888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber case AMessage::kTypeString: 34988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { 35088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber AString val; 35188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(msg->findString(key, &val)); 35288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 35388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber valueObj = env->NewStringUTF(val.c_str()); 35488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber break; 35588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 35688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 3575c850396b39a57baabd37a9c0c8324f1bee408caAndreas Huber case AMessage::kTypeBuffer: 35888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { 3595c850396b39a57baabd37a9c0c8324f1bee408caAndreas Huber sp<ABuffer> buffer; 3605c850396b39a57baabd37a9c0c8324f1bee408caAndreas Huber CHECK(msg->findBuffer(key, &buffer)); 36188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 36288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber valueObj = makeByteBufferObject( 36388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env, buffer->data(), buffer->size()); 36488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber break; 36588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 36688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 367b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber case AMessage::kTypeRect: 368b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber { 369b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber int32_t left, top, right, bottom; 370b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber CHECK(msg->findRect(key, &left, &top, &right, &bottom)); 371b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber 372b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber SetMapInt32( 373b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber env, 374b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber hashMap, 375b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber hashMapPutID, 376f953ca2ec8e418d54ab7d4585302db22964bcb70Elliott Hughes AStringPrintf("%s-left", key).c_str(), 377b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber left); 378b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber 379b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber SetMapInt32( 380b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber env, 381b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber hashMap, 382b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber hashMapPutID, 383f953ca2ec8e418d54ab7d4585302db22964bcb70Elliott Hughes AStringPrintf("%s-top", key).c_str(), 384b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber top); 385b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber 386b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber SetMapInt32( 387b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber env, 388b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber hashMap, 389b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber hashMapPutID, 390f953ca2ec8e418d54ab7d4585302db22964bcb70Elliott Hughes AStringPrintf("%s-right", key).c_str(), 391b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber right); 392b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber 393b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber SetMapInt32( 394b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber env, 395b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber hashMap, 396b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber hashMapPutID, 397f953ca2ec8e418d54ab7d4585302db22964bcb70Elliott Hughes AStringPrintf("%s-bottom", key).c_str(), 398b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber bottom); 399b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber break; 400b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber } 401b842599e51e2d3611503c3c7db1111358f99186dAndreas Huber 40288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber default: 40388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber break; 40488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 40588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 40688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (valueObj != NULL) { 40788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jstring keyObj = env->NewStringUTF(key); 40888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 4095a15d0d31b877ef512b3379eac033c6bb041c86aAndreas Gampe env->CallObjectMethod(hashMap, hashMapPutID, keyObj, valueObj); 41088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 41188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->DeleteLocalRef(keyObj); keyObj = NULL; 41288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->DeleteLocalRef(valueObj); valueObj = NULL; 41388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 41488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 41588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 41688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber *map = hashMap; 41788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 41888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return OK; 41988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 42088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 42188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t ConvertKeyValueArraysToMessage( 42288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobjectArray keys, jobjectArray values, 42388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<AMessage> *out) { 4248d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber ScopedLocalRef<jclass> stringClass(env, env->FindClass("java/lang/String")); 4258d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber CHECK(stringClass.get() != NULL); 4268d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber ScopedLocalRef<jclass> integerClass(env, env->FindClass("java/lang/Integer")); 4278d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber CHECK(integerClass.get() != NULL); 4288d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber ScopedLocalRef<jclass> longClass(env, env->FindClass("java/lang/Long")); 4298d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber CHECK(longClass.get() != NULL); 4308d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber ScopedLocalRef<jclass> floatClass(env, env->FindClass("java/lang/Float")); 4318d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber CHECK(floatClass.get() != NULL); 4328d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber ScopedLocalRef<jclass> byteBufClass(env, env->FindClass("java/nio/ByteBuffer")); 4338d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber CHECK(byteBufClass.get() != NULL); 43488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 43588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<AMessage> msg = new AMessage; 43688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 43788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jsize numEntries = 0; 43888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 43988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (keys != NULL) { 44088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (values == NULL) { 44188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return -EINVAL; 44288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 44388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 44488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber numEntries = env->GetArrayLength(keys); 44588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 44688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (numEntries != env->GetArrayLength(values)) { 44788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return -EINVAL; 44888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 44988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } else if (values != NULL) { 45088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return -EINVAL; 45188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 45288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 45388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber for (jsize i = 0; i < numEntries; ++i) { 45488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobject keyObj = env->GetObjectArrayElement(keys, i); 45588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 4568d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber if (!env->IsInstanceOf(keyObj, stringClass.get())) { 45788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return -EINVAL; 45888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 45988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 46088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber const char *tmp = env->GetStringUTFChars((jstring)keyObj, NULL); 46188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 46288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (tmp == NULL) { 46388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return -ENOMEM; 46488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 46588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 46688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber AString key = tmp; 46788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 46888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->ReleaseStringUTFChars((jstring)keyObj, tmp); 46988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber tmp = NULL; 47088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 471c04399feab8e51531975a4b404327511b094bbf6Lajos Molnar if (key.startsWith("android._")) { 472c04399feab8e51531975a4b404327511b094bbf6Lajos Molnar // don't propagate private keys (starting with android._) 473c04399feab8e51531975a4b404327511b094bbf6Lajos Molnar continue; 474c04399feab8e51531975a4b404327511b094bbf6Lajos Molnar } 475c04399feab8e51531975a4b404327511b094bbf6Lajos Molnar 47688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobject valueObj = env->GetObjectArrayElement(values, i); 47788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 4788d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber if (env->IsInstanceOf(valueObj, stringClass.get())) { 47988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber const char *value = env->GetStringUTFChars((jstring)valueObj, NULL); 48088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 48188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (value == NULL) { 48288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return -ENOMEM; 48388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 48488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 48588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber msg->setString(key.c_str(), value); 48688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 48788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->ReleaseStringUTFChars((jstring)valueObj, value); 48888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber value = NULL; 4898d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber } else if (env->IsInstanceOf(valueObj, integerClass.get())) { 49088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jmethodID intValueID = 4918d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env->GetMethodID(integerClass.get(), "intValue", "()I"); 49288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(intValueID != NULL); 49388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 49488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jint value = env->CallIntMethod(valueObj, intValueID); 49588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 49688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber msg->setInt32(key.c_str(), value); 4978d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber } else if (env->IsInstanceOf(valueObj, longClass.get())) { 4988d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber jmethodID longValueID = 4998d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env->GetMethodID(longClass.get(), "longValue", "()J"); 5008d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber CHECK(longValueID != NULL); 5018d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber 5028d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber jlong value = env->CallLongMethod(valueObj, longValueID); 5038d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber 5048d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber msg->setInt64(key.c_str(), value); 5058d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber } else if (env->IsInstanceOf(valueObj, floatClass.get())) { 50688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jmethodID floatValueID = 5078d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env->GetMethodID(floatClass.get(), "floatValue", "()F"); 50888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(floatValueID != NULL); 50988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 51088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jfloat value = env->CallFloatMethod(valueObj, floatValueID); 51188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 51288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber msg->setFloat(key.c_str(), value); 5138d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber } else if (env->IsInstanceOf(valueObj, byteBufClass.get())) { 51488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jmethodID positionID = 5158d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env->GetMethodID(byteBufClass.get(), "position", "()I"); 51688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(positionID != NULL); 51788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 51888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jmethodID limitID = 5198d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env->GetMethodID(byteBufClass.get(), "limit", "()I"); 52088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(limitID != NULL); 52188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 52288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jint position = env->CallIntMethod(valueObj, positionID); 52388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jint limit = env->CallIntMethod(valueObj, limitID); 52488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 52588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<ABuffer> buffer = new ABuffer(limit - position); 52688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 52788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber void *data = env->GetDirectBufferAddress(valueObj); 52888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 52988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (data != NULL) { 53088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber memcpy(buffer->data(), 53188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (const uint8_t *)data + position, 53288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber buffer->size()); 53388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } else { 53488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jmethodID arrayID = 5358d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env->GetMethodID(byteBufClass.get(), "array", "()[B"); 53688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(arrayID != NULL); 53788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 53888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jbyteArray byteArray = 53988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (jbyteArray)env->CallObjectMethod(valueObj, arrayID); 54088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(byteArray != NULL); 54188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 54288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->GetByteArrayRegion( 54388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber byteArray, 54488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber position, 54588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber buffer->size(), 54688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (jbyte *)buffer->data()); 54788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 54888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->DeleteLocalRef(byteArray); byteArray = NULL; 54988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 55088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 5519b8e496f4d143280deff137c5f30ca8907bc28dbAndreas Huber msg->setBuffer(key.c_str(), buffer); 55288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 55388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 55488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 55588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber *out = msg; 55688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 55788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return OK; 55888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 55988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 5600ab416269a866c8afa8f65d9351afa2407abee4cZhijun He// -----------Utility functions used by ImageReader/Writer JNI----------------- 5610ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 5620ab416269a866c8afa8f65d9351afa2407abee4cZhijun Heenum { 5630ab416269a866c8afa8f65d9351afa2407abee4cZhijun He IMAGE_MAX_NUM_PLANES = 3, 5640ab416269a866c8afa8f65d9351afa2407abee4cZhijun He}; 5650ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 5660ab416269a866c8afa8f65d9351afa2407abee4cZhijun Hebool usingRGBAToJpegOverride(int32_t imageFormat, 5670ab416269a866c8afa8f65d9351afa2407abee4cZhijun He int32_t containerFormat) { 5680ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return containerFormat == HAL_PIXEL_FORMAT_BLOB && imageFormat == HAL_PIXEL_FORMAT_RGBA_8888; 5690ab416269a866c8afa8f65d9351afa2407abee4cZhijun He} 5700ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 5710ab416269a866c8afa8f65d9351afa2407abee4cZhijun Heint32_t applyFormatOverrides(int32_t imageFormat, int32_t containerFormat) { 5720ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Using HAL_PIXEL_FORMAT_RGBA_8888 gralloc buffers containing JPEGs to get around SW 5730ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // write limitations for some platforms (b/17379185). 5740ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (usingRGBAToJpegOverride(imageFormat, containerFormat)) { 5750ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return HAL_PIXEL_FORMAT_BLOB; 5760ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 5770ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return containerFormat; 5780ab416269a866c8afa8f65d9351afa2407abee4cZhijun He} 5790ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 5800ab416269a866c8afa8f65d9351afa2407abee4cZhijun Hebool isFormatOpaque(int format) { 5810ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // This is the only opaque format exposed in the ImageFormat public API. 5820ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Note that we do support CPU access for HAL_PIXEL_FORMAT_RAW_OPAQUE 5830ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // (ImageFormat#RAW_PRIVATE) so it doesn't count as opaque here. 5840ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED; 5850ab416269a866c8afa8f65d9351afa2407abee4cZhijun He} 5860ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 5870ab416269a866c8afa8f65d9351afa2407abee4cZhijun Hebool isPossiblyYUV(PixelFormat format) { 5880ab416269a866c8afa8f65d9351afa2407abee4cZhijun He switch (static_cast<int>(format)) { 5890ab416269a866c8afa8f65d9351afa2407abee4cZhijun He case HAL_PIXEL_FORMAT_RGBA_8888: 5900ab416269a866c8afa8f65d9351afa2407abee4cZhijun He case HAL_PIXEL_FORMAT_RGBX_8888: 5910ab416269a866c8afa8f65d9351afa2407abee4cZhijun He case HAL_PIXEL_FORMAT_RGB_888: 5920ab416269a866c8afa8f65d9351afa2407abee4cZhijun He case HAL_PIXEL_FORMAT_RGB_565: 5930ab416269a866c8afa8f65d9351afa2407abee4cZhijun He case HAL_PIXEL_FORMAT_BGRA_8888: 5940ab416269a866c8afa8f65d9351afa2407abee4cZhijun He case HAL_PIXEL_FORMAT_Y8: 5950ab416269a866c8afa8f65d9351afa2407abee4cZhijun He case HAL_PIXEL_FORMAT_Y16: 5960ab416269a866c8afa8f65d9351afa2407abee4cZhijun He case HAL_PIXEL_FORMAT_RAW16: 5970ab416269a866c8afa8f65d9351afa2407abee4cZhijun He case HAL_PIXEL_FORMAT_RAW10: 5980ab416269a866c8afa8f65d9351afa2407abee4cZhijun He case HAL_PIXEL_FORMAT_RAW_OPAQUE: 5990ab416269a866c8afa8f65d9351afa2407abee4cZhijun He case HAL_PIXEL_FORMAT_BLOB: 6000ab416269a866c8afa8f65d9351afa2407abee4cZhijun He case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED: 6010ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return false; 6020ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 6030ab416269a866c8afa8f65d9351afa2407abee4cZhijun He case HAL_PIXEL_FORMAT_YV12: 6040ab416269a866c8afa8f65d9351afa2407abee4cZhijun He case HAL_PIXEL_FORMAT_YCbCr_420_888: 6050ab416269a866c8afa8f65d9351afa2407abee4cZhijun He case HAL_PIXEL_FORMAT_YCrCb_420_SP: 6060ab416269a866c8afa8f65d9351afa2407abee4cZhijun He default: 6070ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return true; 6080ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 6090ab416269a866c8afa8f65d9351afa2407abee4cZhijun He} 6100ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 6110ab416269a866c8afa8f65d9351afa2407abee4cZhijun Heuint32_t Image_getJpegSize(LockedImage* buffer, bool usingRGBAOverride) { 6120ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGV("%s", __FUNCTION__); 6130ab416269a866c8afa8f65d9351afa2407abee4cZhijun He LOG_ALWAYS_FATAL_IF(buffer == NULL, "Input buffer is NULL!!!"); 6140ab416269a866c8afa8f65d9351afa2407abee4cZhijun He uint32_t size = 0; 6150ab416269a866c8afa8f65d9351afa2407abee4cZhijun He uint32_t width = buffer->width; 6160ab416269a866c8afa8f65d9351afa2407abee4cZhijun He uint8_t* jpegBuffer = buffer->data; 6170ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 6180ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (usingRGBAOverride) { 6190ab416269a866c8afa8f65d9351afa2407abee4cZhijun He width = (buffer->width + buffer->stride * (buffer->height - 1)) * 4; 6200ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 6210ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 6220ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // First check for JPEG transport header at the end of the buffer 6230ab416269a866c8afa8f65d9351afa2407abee4cZhijun He uint8_t* header = jpegBuffer + (width - sizeof(struct camera3_jpeg_blob)); 6240ab416269a866c8afa8f65d9351afa2407abee4cZhijun He struct camera3_jpeg_blob *blob = (struct camera3_jpeg_blob*)(header); 6250ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (blob->jpeg_blob_id == CAMERA3_JPEG_BLOB_ID) { 6260ab416269a866c8afa8f65d9351afa2407abee4cZhijun He size = blob->jpeg_size; 6270ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGV("%s: Jpeg size = %d", __FUNCTION__, size); 6280ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 6290ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 6300ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // failed to find size, default to whole buffer 6310ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (size == 0) { 6320ab416269a866c8afa8f65d9351afa2407abee4cZhijun He /* 6330ab416269a866c8afa8f65d9351afa2407abee4cZhijun He * This is a problem because not including the JPEG header 6340ab416269a866c8afa8f65d9351afa2407abee4cZhijun He * means that in certain rare situations a regular JPEG blob 6350ab416269a866c8afa8f65d9351afa2407abee4cZhijun He * will be mis-identified as having a header, in which case 6360ab416269a866c8afa8f65d9351afa2407abee4cZhijun He * we will get a garbage size value. 6370ab416269a866c8afa8f65d9351afa2407abee4cZhijun He */ 6380ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGW("%s: No JPEG header detected, defaulting to size=width=%d", 6390ab416269a866c8afa8f65d9351afa2407abee4cZhijun He __FUNCTION__, width); 6400ab416269a866c8afa8f65d9351afa2407abee4cZhijun He size = width; 6410ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 6420ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 6430ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return size; 6440ab416269a866c8afa8f65d9351afa2407abee4cZhijun He} 6450ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 6460ab416269a866c8afa8f65d9351afa2407abee4cZhijun Hestatus_t getLockedImageInfo(LockedImage* buffer, int idx, 6470ab416269a866c8afa8f65d9351afa2407abee4cZhijun He int32_t containerFormat, uint8_t **base, uint32_t *size, int *pixelStride, int *rowStride) { 6480ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGV("%s", __FUNCTION__); 6490ab416269a866c8afa8f65d9351afa2407abee4cZhijun He LOG_ALWAYS_FATAL_IF(buffer == NULL, "Input buffer is NULL!!!"); 6500ab416269a866c8afa8f65d9351afa2407abee4cZhijun He LOG_ALWAYS_FATAL_IF(base == NULL, "base is NULL!!!"); 6510ab416269a866c8afa8f65d9351afa2407abee4cZhijun He LOG_ALWAYS_FATAL_IF(size == NULL, "size is NULL!!!"); 6520ab416269a866c8afa8f65d9351afa2407abee4cZhijun He LOG_ALWAYS_FATAL_IF(pixelStride == NULL, "pixelStride is NULL!!!"); 6530ab416269a866c8afa8f65d9351afa2407abee4cZhijun He LOG_ALWAYS_FATAL_IF(rowStride == NULL, "rowStride is NULL!!!"); 6540ab416269a866c8afa8f65d9351afa2407abee4cZhijun He LOG_ALWAYS_FATAL_IF((idx >= IMAGE_MAX_NUM_PLANES) || (idx < 0), "idx (%d) is illegal", idx); 6550ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 6560ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGV("%s: buffer: %p", __FUNCTION__, buffer); 6570ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 6580ab416269a866c8afa8f65d9351afa2407abee4cZhijun He uint32_t dataSize, ySize, cSize, cStride; 6590ab416269a866c8afa8f65d9351afa2407abee4cZhijun He uint32_t pStride = 0, rStride = 0; 6600ab416269a866c8afa8f65d9351afa2407abee4cZhijun He uint8_t *cb, *cr; 6610ab416269a866c8afa8f65d9351afa2407abee4cZhijun He uint8_t *pData = NULL; 6620ab416269a866c8afa8f65d9351afa2407abee4cZhijun He int bytesPerPixel = 0; 6630ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 6640ab416269a866c8afa8f65d9351afa2407abee4cZhijun He dataSize = ySize = cSize = cStride = 0; 6650ab416269a866c8afa8f65d9351afa2407abee4cZhijun He int32_t fmt = buffer->flexFormat; 6660ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 6670ab416269a866c8afa8f65d9351afa2407abee4cZhijun He bool usingRGBAOverride = usingRGBAToJpegOverride(fmt, containerFormat); 6680ab416269a866c8afa8f65d9351afa2407abee4cZhijun He fmt = applyFormatOverrides(fmt, containerFormat); 6690ab416269a866c8afa8f65d9351afa2407abee4cZhijun He switch (fmt) { 6700ab416269a866c8afa8f65d9351afa2407abee4cZhijun He case HAL_PIXEL_FORMAT_YCbCr_420_888: 6710ab416269a866c8afa8f65d9351afa2407abee4cZhijun He pData = 6720ab416269a866c8afa8f65d9351afa2407abee4cZhijun He (idx == 0) ? 6730ab416269a866c8afa8f65d9351afa2407abee4cZhijun He buffer->data : 6740ab416269a866c8afa8f65d9351afa2407abee4cZhijun He (idx == 1) ? 6750ab416269a866c8afa8f65d9351afa2407abee4cZhijun He buffer->dataCb : 6760ab416269a866c8afa8f65d9351afa2407abee4cZhijun He buffer->dataCr; 6770ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // only map until last pixel 6780ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (idx == 0) { 6790ab416269a866c8afa8f65d9351afa2407abee4cZhijun He pStride = 1; 6800ab416269a866c8afa8f65d9351afa2407abee4cZhijun He rStride = buffer->stride; 6810ab416269a866c8afa8f65d9351afa2407abee4cZhijun He dataSize = buffer->stride * (buffer->height - 1) + buffer->width; 6820ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } else { 6830ab416269a866c8afa8f65d9351afa2407abee4cZhijun He pStride = buffer->chromaStep; 6840ab416269a866c8afa8f65d9351afa2407abee4cZhijun He rStride = buffer->chromaStride; 6850ab416269a866c8afa8f65d9351afa2407abee4cZhijun He dataSize = buffer->chromaStride * (buffer->height / 2 - 1) + 6860ab416269a866c8afa8f65d9351afa2407abee4cZhijun He buffer->chromaStep * (buffer->width / 2 - 1) + 1; 6870ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 6880ab416269a866c8afa8f65d9351afa2407abee4cZhijun He break; 6890ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // NV21 6900ab416269a866c8afa8f65d9351afa2407abee4cZhijun He case HAL_PIXEL_FORMAT_YCrCb_420_SP: 6910ab416269a866c8afa8f65d9351afa2407abee4cZhijun He cr = buffer->data + (buffer->stride * buffer->height); 6920ab416269a866c8afa8f65d9351afa2407abee4cZhijun He cb = cr + 1; 6930ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // only map until last pixel 6940ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ySize = buffer->width * (buffer->height - 1) + buffer->width; 6950ab416269a866c8afa8f65d9351afa2407abee4cZhijun He cSize = buffer->width * (buffer->height / 2 - 1) + buffer->width - 1; 6960ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 6970ab416269a866c8afa8f65d9351afa2407abee4cZhijun He pData = 6980ab416269a866c8afa8f65d9351afa2407abee4cZhijun He (idx == 0) ? 6990ab416269a866c8afa8f65d9351afa2407abee4cZhijun He buffer->data : 7000ab416269a866c8afa8f65d9351afa2407abee4cZhijun He (idx == 1) ? 7010ab416269a866c8afa8f65d9351afa2407abee4cZhijun He cb: 7020ab416269a866c8afa8f65d9351afa2407abee4cZhijun He cr; 7030ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 7040ab416269a866c8afa8f65d9351afa2407abee4cZhijun He dataSize = (idx == 0) ? ySize : cSize; 7050ab416269a866c8afa8f65d9351afa2407abee4cZhijun He pStride = (idx == 0) ? 1 : 2; 7060ab416269a866c8afa8f65d9351afa2407abee4cZhijun He rStride = buffer->width; 7070ab416269a866c8afa8f65d9351afa2407abee4cZhijun He break; 7080ab416269a866c8afa8f65d9351afa2407abee4cZhijun He case HAL_PIXEL_FORMAT_YV12: 7090ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Y and C stride need to be 16 pixel aligned. 7100ab416269a866c8afa8f65d9351afa2407abee4cZhijun He LOG_ALWAYS_FATAL_IF(buffer->stride % 16, 7110ab416269a866c8afa8f65d9351afa2407abee4cZhijun He "Stride is not 16 pixel aligned %d", buffer->stride); 7120ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 7130ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ySize = buffer->stride * buffer->height; 7140ab416269a866c8afa8f65d9351afa2407abee4cZhijun He cStride = ALIGN(buffer->stride / 2, 16); 7150ab416269a866c8afa8f65d9351afa2407abee4cZhijun He cr = buffer->data + ySize; 7160ab416269a866c8afa8f65d9351afa2407abee4cZhijun He cSize = cStride * buffer->height / 2; 7170ab416269a866c8afa8f65d9351afa2407abee4cZhijun He cb = cr + cSize; 7180ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 7190ab416269a866c8afa8f65d9351afa2407abee4cZhijun He pData = 7200ab416269a866c8afa8f65d9351afa2407abee4cZhijun He (idx == 0) ? 7210ab416269a866c8afa8f65d9351afa2407abee4cZhijun He buffer->data : 7220ab416269a866c8afa8f65d9351afa2407abee4cZhijun He (idx == 1) ? 7230ab416269a866c8afa8f65d9351afa2407abee4cZhijun He cb : 7240ab416269a866c8afa8f65d9351afa2407abee4cZhijun He cr; 7250ab416269a866c8afa8f65d9351afa2407abee4cZhijun He dataSize = (idx == 0) ? ySize : cSize; 7260ab416269a866c8afa8f65d9351afa2407abee4cZhijun He pStride = 1; 7270ab416269a866c8afa8f65d9351afa2407abee4cZhijun He rStride = (idx == 0) ? buffer->stride : ALIGN(buffer->stride / 2, 16); 7280ab416269a866c8afa8f65d9351afa2407abee4cZhijun He break; 7290ab416269a866c8afa8f65d9351afa2407abee4cZhijun He case HAL_PIXEL_FORMAT_Y8: 7300ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Single plane, 8bpp. 7310ab416269a866c8afa8f65d9351afa2407abee4cZhijun He LOG_ALWAYS_FATAL_IF(idx != 0, "Wrong index: %d", idx); 7320ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 7330ab416269a866c8afa8f65d9351afa2407abee4cZhijun He pData = buffer->data; 7340ab416269a866c8afa8f65d9351afa2407abee4cZhijun He dataSize = buffer->stride * buffer->height; 7350ab416269a866c8afa8f65d9351afa2407abee4cZhijun He pStride = 1; 7360ab416269a866c8afa8f65d9351afa2407abee4cZhijun He rStride = buffer->stride; 7370ab416269a866c8afa8f65d9351afa2407abee4cZhijun He break; 7380ab416269a866c8afa8f65d9351afa2407abee4cZhijun He case HAL_PIXEL_FORMAT_Y16: 7390ab416269a866c8afa8f65d9351afa2407abee4cZhijun He bytesPerPixel = 2; 7400ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Single plane, 16bpp, strides are specified in pixels, not in bytes 7410ab416269a866c8afa8f65d9351afa2407abee4cZhijun He LOG_ALWAYS_FATAL_IF(idx != 0, "Wrong index: %d", idx); 7420ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 7430ab416269a866c8afa8f65d9351afa2407abee4cZhijun He pData = buffer->data; 7440ab416269a866c8afa8f65d9351afa2407abee4cZhijun He dataSize = buffer->stride * buffer->height * bytesPerPixel; 7450ab416269a866c8afa8f65d9351afa2407abee4cZhijun He pStride = bytesPerPixel; 7460ab416269a866c8afa8f65d9351afa2407abee4cZhijun He rStride = buffer->stride * 2; 7470ab416269a866c8afa8f65d9351afa2407abee4cZhijun He break; 7480ab416269a866c8afa8f65d9351afa2407abee4cZhijun He case HAL_PIXEL_FORMAT_BLOB: 7490ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Used for JPEG data, height must be 1, width == size, single plane. 7500ab416269a866c8afa8f65d9351afa2407abee4cZhijun He LOG_ALWAYS_FATAL_IF(idx != 0, "Wrong index: %d", idx); 7517b7909025276dc9c78afb68c84a77f2ee5456b4dYin-Chia Yeh // When RGBA override is being used, buffer height will be equal to width 7527b7909025276dc9c78afb68c84a77f2ee5456b4dYin-Chia Yeh if (usingRGBAOverride) { 7537b7909025276dc9c78afb68c84a77f2ee5456b4dYin-Chia Yeh LOG_ALWAYS_FATAL_IF(buffer->height != buffer->width, 7547b7909025276dc9c78afb68c84a77f2ee5456b4dYin-Chia Yeh "RGBA override BLOB format buffer should have height == width"); 7557b7909025276dc9c78afb68c84a77f2ee5456b4dYin-Chia Yeh } else { 7567b7909025276dc9c78afb68c84a77f2ee5456b4dYin-Chia Yeh LOG_ALWAYS_FATAL_IF(buffer->height != 1, 7577b7909025276dc9c78afb68c84a77f2ee5456b4dYin-Chia Yeh "BLOB format buffer should have height value 1"); 7587b7909025276dc9c78afb68c84a77f2ee5456b4dYin-Chia Yeh } 7597b7909025276dc9c78afb68c84a77f2ee5456b4dYin-Chia Yeh 7600ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 7610ab416269a866c8afa8f65d9351afa2407abee4cZhijun He pData = buffer->data; 7620ab416269a866c8afa8f65d9351afa2407abee4cZhijun He dataSize = Image_getJpegSize(buffer, usingRGBAOverride); 7630ab416269a866c8afa8f65d9351afa2407abee4cZhijun He pStride = 0; 7640ab416269a866c8afa8f65d9351afa2407abee4cZhijun He rStride = 0; 7650ab416269a866c8afa8f65d9351afa2407abee4cZhijun He break; 7660ab416269a866c8afa8f65d9351afa2407abee4cZhijun He case HAL_PIXEL_FORMAT_RAW16: 7670ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Single plane 16bpp bayer data. 7680ab416269a866c8afa8f65d9351afa2407abee4cZhijun He bytesPerPixel = 2; 7690ab416269a866c8afa8f65d9351afa2407abee4cZhijun He LOG_ALWAYS_FATAL_IF(idx != 0, "Wrong index: %d", idx); 7700ab416269a866c8afa8f65d9351afa2407abee4cZhijun He pData = buffer->data; 7710ab416269a866c8afa8f65d9351afa2407abee4cZhijun He dataSize = buffer->stride * buffer->height * bytesPerPixel; 7720ab416269a866c8afa8f65d9351afa2407abee4cZhijun He pStride = bytesPerPixel; 7730ab416269a866c8afa8f65d9351afa2407abee4cZhijun He rStride = buffer->stride * 2; 7740ab416269a866c8afa8f65d9351afa2407abee4cZhijun He break; 7750ab416269a866c8afa8f65d9351afa2407abee4cZhijun He case HAL_PIXEL_FORMAT_RAW_OPAQUE: 7760ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Used for RAW_OPAQUE data, height must be 1, width == size, single plane. 7770ab416269a866c8afa8f65d9351afa2407abee4cZhijun He LOG_ALWAYS_FATAL_IF(idx != 0, "Wrong index: %d", idx); 7780ab416269a866c8afa8f65d9351afa2407abee4cZhijun He LOG_ALWAYS_FATAL_IF(buffer->height != 1, 7790ab416269a866c8afa8f65d9351afa2407abee4cZhijun He "RAW_PRIVATE should has height value one but got %d", buffer->height); 7800ab416269a866c8afa8f65d9351afa2407abee4cZhijun He pData = buffer->data; 7810ab416269a866c8afa8f65d9351afa2407abee4cZhijun He dataSize = buffer->width; 7820ab416269a866c8afa8f65d9351afa2407abee4cZhijun He pStride = 0; // RAW OPAQUE doesn't have pixel stride 7830ab416269a866c8afa8f65d9351afa2407abee4cZhijun He rStride = 0; // RAW OPAQUE doesn't have row stride 7840ab416269a866c8afa8f65d9351afa2407abee4cZhijun He break; 7850ab416269a866c8afa8f65d9351afa2407abee4cZhijun He case HAL_PIXEL_FORMAT_RAW10: 7860ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Single plane 10bpp bayer data. 7870ab416269a866c8afa8f65d9351afa2407abee4cZhijun He LOG_ALWAYS_FATAL_IF(idx != 0, "Wrong index: %d", idx); 7880ab416269a866c8afa8f65d9351afa2407abee4cZhijun He LOG_ALWAYS_FATAL_IF(buffer->width % 4, 7890ab416269a866c8afa8f65d9351afa2407abee4cZhijun He "Width is not multiple of 4 %d", buffer->width); 7900ab416269a866c8afa8f65d9351afa2407abee4cZhijun He LOG_ALWAYS_FATAL_IF(buffer->height % 2, 7910ab416269a866c8afa8f65d9351afa2407abee4cZhijun He "Height is not even %d", buffer->height); 7920ab416269a866c8afa8f65d9351afa2407abee4cZhijun He LOG_ALWAYS_FATAL_IF(buffer->stride < (buffer->width * 10 / 8), 7930ab416269a866c8afa8f65d9351afa2407abee4cZhijun He "stride (%d) should be at least %d", 7940ab416269a866c8afa8f65d9351afa2407abee4cZhijun He buffer->stride, buffer->width * 10 / 8); 7950ab416269a866c8afa8f65d9351afa2407abee4cZhijun He pData = buffer->data; 7960ab416269a866c8afa8f65d9351afa2407abee4cZhijun He dataSize = buffer->stride * buffer->height; 7970ab416269a866c8afa8f65d9351afa2407abee4cZhijun He pStride = 0; 7980ab416269a866c8afa8f65d9351afa2407abee4cZhijun He rStride = buffer->stride; 7990ab416269a866c8afa8f65d9351afa2407abee4cZhijun He break; 8000ab416269a866c8afa8f65d9351afa2407abee4cZhijun He case HAL_PIXEL_FORMAT_RAW12: 8010ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Single plane 10bpp bayer data. 8020ab416269a866c8afa8f65d9351afa2407abee4cZhijun He LOG_ALWAYS_FATAL_IF(idx != 0, "Wrong index: %d", idx); 8030ab416269a866c8afa8f65d9351afa2407abee4cZhijun He LOG_ALWAYS_FATAL_IF(buffer->width % 4, 8040ab416269a866c8afa8f65d9351afa2407abee4cZhijun He "Width is not multiple of 4 %d", buffer->width); 8050ab416269a866c8afa8f65d9351afa2407abee4cZhijun He LOG_ALWAYS_FATAL_IF(buffer->height % 2, 8060ab416269a866c8afa8f65d9351afa2407abee4cZhijun He "Height is not even %d", buffer->height); 8070ab416269a866c8afa8f65d9351afa2407abee4cZhijun He LOG_ALWAYS_FATAL_IF(buffer->stride < (buffer->width * 12 / 8), 8080ab416269a866c8afa8f65d9351afa2407abee4cZhijun He "stride (%d) should be at least %d", 8090ab416269a866c8afa8f65d9351afa2407abee4cZhijun He buffer->stride, buffer->width * 12 / 8); 8100ab416269a866c8afa8f65d9351afa2407abee4cZhijun He pData = buffer->data; 8110ab416269a866c8afa8f65d9351afa2407abee4cZhijun He dataSize = buffer->stride * buffer->height; 8120ab416269a866c8afa8f65d9351afa2407abee4cZhijun He pStride = 0; 8130ab416269a866c8afa8f65d9351afa2407abee4cZhijun He rStride = buffer->stride; 8140ab416269a866c8afa8f65d9351afa2407abee4cZhijun He break; 8150ab416269a866c8afa8f65d9351afa2407abee4cZhijun He case HAL_PIXEL_FORMAT_RGBA_8888: 8160ab416269a866c8afa8f65d9351afa2407abee4cZhijun He case HAL_PIXEL_FORMAT_RGBX_8888: 8170ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Single plane, 32bpp. 8180ab416269a866c8afa8f65d9351afa2407abee4cZhijun He bytesPerPixel = 4; 8190ab416269a866c8afa8f65d9351afa2407abee4cZhijun He LOG_ALWAYS_FATAL_IF(idx != 0, "Wrong index: %d", idx); 8200ab416269a866c8afa8f65d9351afa2407abee4cZhijun He pData = buffer->data; 8210ab416269a866c8afa8f65d9351afa2407abee4cZhijun He dataSize = buffer->stride * buffer->height * bytesPerPixel; 8220ab416269a866c8afa8f65d9351afa2407abee4cZhijun He pStride = bytesPerPixel; 8230ab416269a866c8afa8f65d9351afa2407abee4cZhijun He rStride = buffer->stride * 4; 8240ab416269a866c8afa8f65d9351afa2407abee4cZhijun He break; 8250ab416269a866c8afa8f65d9351afa2407abee4cZhijun He case HAL_PIXEL_FORMAT_RGB_565: 8260ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Single plane, 16bpp. 8270ab416269a866c8afa8f65d9351afa2407abee4cZhijun He bytesPerPixel = 2; 8280ab416269a866c8afa8f65d9351afa2407abee4cZhijun He LOG_ALWAYS_FATAL_IF(idx != 0, "Wrong index: %d", idx); 8290ab416269a866c8afa8f65d9351afa2407abee4cZhijun He pData = buffer->data; 8300ab416269a866c8afa8f65d9351afa2407abee4cZhijun He dataSize = buffer->stride * buffer->height * bytesPerPixel; 8310ab416269a866c8afa8f65d9351afa2407abee4cZhijun He pStride = bytesPerPixel; 8320ab416269a866c8afa8f65d9351afa2407abee4cZhijun He rStride = buffer->stride * 2; 8330ab416269a866c8afa8f65d9351afa2407abee4cZhijun He break; 8340ab416269a866c8afa8f65d9351afa2407abee4cZhijun He case HAL_PIXEL_FORMAT_RGB_888: 8350ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Single plane, 24bpp. 8360ab416269a866c8afa8f65d9351afa2407abee4cZhijun He bytesPerPixel = 3; 8370ab416269a866c8afa8f65d9351afa2407abee4cZhijun He LOG_ALWAYS_FATAL_IF(idx != 0, "Wrong index: %d", idx); 8380ab416269a866c8afa8f65d9351afa2407abee4cZhijun He pData = buffer->data; 8390ab416269a866c8afa8f65d9351afa2407abee4cZhijun He dataSize = buffer->stride * buffer->height * bytesPerPixel; 8400ab416269a866c8afa8f65d9351afa2407abee4cZhijun He pStride = bytesPerPixel; 8410ab416269a866c8afa8f65d9351afa2407abee4cZhijun He rStride = buffer->stride * 3; 8420ab416269a866c8afa8f65d9351afa2407abee4cZhijun He break; 8430ab416269a866c8afa8f65d9351afa2407abee4cZhijun He default: 8440ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return BAD_VALUE; 8450ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 8460ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 8470ab416269a866c8afa8f65d9351afa2407abee4cZhijun He *base = pData; 8480ab416269a866c8afa8f65d9351afa2407abee4cZhijun He *size = dataSize; 8490ab416269a866c8afa8f65d9351afa2407abee4cZhijun He *pixelStride = pStride; 8500ab416269a866c8afa8f65d9351afa2407abee4cZhijun He *rowStride = rStride; 8510ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 8520ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return OK; 8530ab416269a866c8afa8f65d9351afa2407abee4cZhijun He} 8540ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 8550ab416269a866c8afa8f65d9351afa2407abee4cZhijun Hestatus_t lockImageFromBuffer(sp<GraphicBuffer> buffer, uint32_t inUsage, 8560ab416269a866c8afa8f65d9351afa2407abee4cZhijun He const Rect& rect, int fenceFd, LockedImage* outputImage) { 8570ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGV("%s: Try to lock the GraphicBuffer", __FUNCTION__); 8580ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 8590ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (buffer == nullptr || outputImage == nullptr) { 8600ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGE("Input BufferItem or output LockedImage is NULL!"); 8610ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return BAD_VALUE; 8620ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 8630ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (isFormatOpaque(buffer->getPixelFormat())) { 8640ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGE("Opaque format buffer is not lockable!"); 8650ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return BAD_VALUE; 8660ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 8670ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 8680ab416269a866c8afa8f65d9351afa2407abee4cZhijun He void* pData = NULL; 8690ab416269a866c8afa8f65d9351afa2407abee4cZhijun He android_ycbcr ycbcr = android_ycbcr(); 8700ab416269a866c8afa8f65d9351afa2407abee4cZhijun He status_t res; 8710ab416269a866c8afa8f65d9351afa2407abee4cZhijun He int format = buffer->getPixelFormat(); 8720ab416269a866c8afa8f65d9351afa2407abee4cZhijun He int flexFormat = format; 8730ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (isPossiblyYUV(format)) { 8740ab416269a866c8afa8f65d9351afa2407abee4cZhijun He res = buffer->lockAsyncYCbCr(inUsage, rect, &ycbcr, fenceFd); 8750ab416269a866c8afa8f65d9351afa2407abee4cZhijun He pData = ycbcr.y; 8760ab416269a866c8afa8f65d9351afa2407abee4cZhijun He flexFormat = HAL_PIXEL_FORMAT_YCbCr_420_888; 8770ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 8780ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 8790ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // lockAsyncYCbCr for YUV is unsuccessful. 8800ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (pData == NULL) { 8810ab416269a866c8afa8f65d9351afa2407abee4cZhijun He res = buffer->lockAsync(inUsage, rect, &pData, fenceFd); 8820ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (res != OK) { 8830ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGE("Lock buffer failed!"); 8840ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return res; 8850ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 8860ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 8870ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 8880ab416269a866c8afa8f65d9351afa2407abee4cZhijun He outputImage->data = reinterpret_cast<uint8_t*>(pData); 8890ab416269a866c8afa8f65d9351afa2407abee4cZhijun He outputImage->width = buffer->getWidth(); 8900ab416269a866c8afa8f65d9351afa2407abee4cZhijun He outputImage->height = buffer->getHeight(); 8910ab416269a866c8afa8f65d9351afa2407abee4cZhijun He outputImage->format = format; 8920ab416269a866c8afa8f65d9351afa2407abee4cZhijun He outputImage->flexFormat = flexFormat; 8930ab416269a866c8afa8f65d9351afa2407abee4cZhijun He outputImage->stride = 8940ab416269a866c8afa8f65d9351afa2407abee4cZhijun He (ycbcr.y != NULL) ? static_cast<uint32_t>(ycbcr.ystride) : buffer->getStride(); 8950ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 8960ab416269a866c8afa8f65d9351afa2407abee4cZhijun He outputImage->dataCb = reinterpret_cast<uint8_t*>(ycbcr.cb); 8970ab416269a866c8afa8f65d9351afa2407abee4cZhijun He outputImage->dataCr = reinterpret_cast<uint8_t*>(ycbcr.cr); 8980ab416269a866c8afa8f65d9351afa2407abee4cZhijun He outputImage->chromaStride = static_cast<uint32_t>(ycbcr.cstride); 8990ab416269a866c8afa8f65d9351afa2407abee4cZhijun He outputImage->chromaStep = static_cast<uint32_t>(ycbcr.chroma_step); 9000ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGV("%s: Successfully locked the image from the GraphicBuffer", __FUNCTION__); 9010ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // Crop, transform, scalingMode, timestamp, and frameNumber should be set by caller, 9020ab416269a866c8afa8f65d9351afa2407abee4cZhijun He // and cann't be set them here. 9030ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return OK; 9040ab416269a866c8afa8f65d9351afa2407abee4cZhijun He} 9050ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 9060ab416269a866c8afa8f65d9351afa2407abee4cZhijun Hestatus_t lockImageFromBuffer(BufferItem* bufferItem, uint32_t inUsage, 9070ab416269a866c8afa8f65d9351afa2407abee4cZhijun He int fenceFd, LockedImage* outputImage) { 9080ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGV("%s: Try to lock the BufferItem", __FUNCTION__); 9090ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (bufferItem == nullptr || outputImage == nullptr) { 9100ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGE("Input BufferItem or output LockedImage is NULL!"); 9110ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return BAD_VALUE; 9120ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 9130ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 9140ab416269a866c8afa8f65d9351afa2407abee4cZhijun He status_t res = lockImageFromBuffer(bufferItem->mGraphicBuffer, inUsage, bufferItem->mCrop, 9150ab416269a866c8afa8f65d9351afa2407abee4cZhijun He fenceFd, outputImage); 9160ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (res != OK) { 9170ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGE("%s: lock graphic buffer failed", __FUNCTION__); 9180ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return res; 9190ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 9200ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 9210ab416269a866c8afa8f65d9351afa2407abee4cZhijun He outputImage->crop = bufferItem->mCrop; 9220ab416269a866c8afa8f65d9351afa2407abee4cZhijun He outputImage->transform = bufferItem->mTransform; 9230ab416269a866c8afa8f65d9351afa2407abee4cZhijun He outputImage->scalingMode = bufferItem->mScalingMode; 9240ab416269a866c8afa8f65d9351afa2407abee4cZhijun He outputImage->timestamp = bufferItem->mTimestamp; 9250ab416269a866c8afa8f65d9351afa2407abee4cZhijun He outputImage->dataSpace = bufferItem->mDataSpace; 9260ab416269a866c8afa8f65d9351afa2407abee4cZhijun He outputImage->frameNumber = bufferItem->mFrameNumber; 9270ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGV("%s: Successfully locked the image from the BufferItem", __FUNCTION__); 9280ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return OK; 9290ab416269a866c8afa8f65d9351afa2407abee4cZhijun He} 9300ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 9310ab416269a866c8afa8f65d9351afa2407abee4cZhijun Heint getBufferWidth(BufferItem* buffer) { 9320ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (buffer == NULL) return -1; 9330ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 9340ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (!buffer->mCrop.isEmpty()) { 9350ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return buffer->mCrop.getWidth(); 9360ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 9370ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 9380ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGV("%s: buffer->mGraphicBuffer: %p", __FUNCTION__, buffer->mGraphicBuffer.get()); 9390ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return buffer->mGraphicBuffer->getWidth(); 9400ab416269a866c8afa8f65d9351afa2407abee4cZhijun He} 9410ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 9420ab416269a866c8afa8f65d9351afa2407abee4cZhijun Heint getBufferHeight(BufferItem* buffer) { 9430ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (buffer == NULL) return -1; 9440ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 9450ab416269a866c8afa8f65d9351afa2407abee4cZhijun He if (!buffer->mCrop.isEmpty()) { 9460ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return buffer->mCrop.getHeight(); 9470ab416269a866c8afa8f65d9351afa2407abee4cZhijun He } 9480ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 9490ab416269a866c8afa8f65d9351afa2407abee4cZhijun He ALOGV("%s: buffer->mGraphicBuffer: %p", __FUNCTION__, buffer->mGraphicBuffer.get()); 9500ab416269a866c8afa8f65d9351afa2407abee4cZhijun He return buffer->mGraphicBuffer->getHeight(); 9510ab416269a866c8afa8f65d9351afa2407abee4cZhijun He} 9520ab416269a866c8afa8f65d9351afa2407abee4cZhijun He 95379f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong} // namespace android 95479f407cc6c5ae34fc6f04d52fd034b49d1f002c4James Dong 955