Home | History | Annotate | Download | only in jni
      1 /*
      2  * Copyright 2011, The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *     http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 // #define LOG_NDEBUG 0
     18 #define LOG_TAG "AndroidMediaUtils"
     19 
     20 #include <hardware/camera3.h>
     21 #include <utils/Log.h>
     22 #include "android_media_Utils.h"
     23 
     24 #include <media/stagefright/foundation/ADebug.h>
     25 #include <media/stagefright/foundation/ABuffer.h>
     26 #include <media/stagefright/foundation/AMessage.h>
     27 
     28 #include <nativehelper/ScopedLocalRef.h>
     29 
     30 #define ALIGN(x, mask) ( ((x) + (mask) - 1) & ~((mask) - 1) )
     31 
     32 namespace android {
     33 
     34 AssetStream::AssetStream(SkStream* stream)
     35     : mStream(stream), mPosition(0) {
     36 }
     37 
     38 AssetStream::~AssetStream() {
     39 }
     40 
     41 piex::Error AssetStream::GetData(
     42         const size_t offset, const size_t length, std::uint8_t* data) {
     43     // Seek first.
     44     if (mPosition != offset) {
     45         if (!mStream->seek(offset)) {
     46             return piex::Error::kFail;
     47         }
     48     }
     49 
     50     // Read bytes.
     51     size_t size = mStream->read((void*)data, length);
     52     mPosition = offset + size;
     53 
     54     return size == length ? piex::Error::kOk : piex::Error::kFail;
     55 }
     56 
     57 BufferedStream::BufferedStream(SkStream* stream)
     58     : mStream(stream) {
     59 }
     60 
     61 BufferedStream::~BufferedStream() {
     62 }
     63 
     64 piex::Error BufferedStream::GetData(
     65         const size_t offset, const size_t length, std::uint8_t* data) {
     66     // Seek first.
     67     if (offset + length > mStreamBuffer.bytesWritten()) {
     68         size_t sizeToRead = offset + length - mStreamBuffer.bytesWritten();
     69         if (sizeToRead <= kMinSizeToRead) {
     70             sizeToRead = kMinSizeToRead;
     71         }
     72 
     73         void* tempBuffer = malloc(sizeToRead);
     74         if (tempBuffer == NULL) {
     75           return piex::Error::kFail;
     76         }
     77 
     78         size_t bytesRead = mStream->read(tempBuffer, sizeToRead);
     79         if (bytesRead != sizeToRead) {
     80             free(tempBuffer);
     81             return piex::Error::kFail;
     82         }
     83         mStreamBuffer.write(tempBuffer, bytesRead);
     84         free(tempBuffer);
     85     }
     86 
     87     // Read bytes.
     88     if (mStreamBuffer.read((void*)data, offset, length)) {
     89         return piex::Error::kOk;
     90     } else {
     91         return piex::Error::kFail;
     92     }
     93 }
     94 
     95 FileStream::FileStream(const int fd)
     96     : mPosition(0) {
     97     mFile = fdopen(fd, "r");
     98     if (mFile == NULL) {
     99         return;
    100     }
    101 }
    102 
    103 FileStream::FileStream(const String8 filename)
    104     : mPosition(0) {
    105     mFile = fopen(filename.string(), "r");
    106     if (mFile == NULL) {
    107         return;
    108     }
    109 }
    110 
    111 FileStream::~FileStream() {
    112     if (mFile != NULL) {
    113         fclose(mFile);
    114         mFile = NULL;
    115     }
    116 }
    117 
    118 piex::Error FileStream::GetData(
    119         const size_t offset, const size_t length, std::uint8_t* data) {
    120     if (mFile == NULL) {
    121         return piex::Error::kFail;
    122     }
    123 
    124     // Seek first.
    125     if (mPosition != offset) {
    126         fseek(mFile, offset, SEEK_SET);
    127     }
    128 
    129     // Read bytes.
    130     size_t size = fread((void*)data, sizeof(std::uint8_t), length, mFile);
    131     mPosition += size;
    132 
    133     // Handle errors and verify the size.
    134     if (ferror(mFile) || size != length) {
    135         ALOGV("GetData read failed: (offset: %zu, length: %zu)", offset, length);
    136         return piex::Error::kFail;
    137     }
    138     return piex::Error::kOk;
    139 }
    140 
    141 bool FileStream::exists() const {
    142     return mFile != NULL;
    143 }
    144 
    145 bool GetExifFromRawImage(
    146         piex::StreamInterface* stream, const String8& filename,
    147         piex::PreviewImageData& image_data) {
    148     // Reset the PreviewImageData to its default.
    149     image_data = piex::PreviewImageData();
    150 
    151     if (!piex::IsRaw(stream)) {
    152         // Format not supported.
    153         ALOGV("Format not supported: %s", filename.string());
    154         return false;
    155     }
    156 
    157     piex::Error err = piex::GetPreviewImageData(stream, &image_data);
    158 
    159     if (err != piex::Error::kOk) {
    160         // The input data seems to be broken.
    161         ALOGV("Raw image not detected: %s (piex error code: %d)", filename.string(), (int32_t)err);
    162         return false;
    163     }
    164 
    165     return true;
    166 }
    167 
    168 bool ConvertKeyValueArraysToKeyedVector(
    169         JNIEnv *env, jobjectArray keys, jobjectArray values,
    170         KeyedVector<String8, String8>* keyedVector) {
    171 
    172     int nKeyValuePairs = 0;
    173     bool failed = false;
    174     if (keys != NULL && values != NULL) {
    175         nKeyValuePairs = env->GetArrayLength(keys);
    176         failed = (nKeyValuePairs != env->GetArrayLength(values));
    177     }
    178 
    179     if (!failed) {
    180         failed = ((keys != NULL && values == NULL) ||
    181                   (keys == NULL && values != NULL));
    182     }
    183 
    184     if (failed) {
    185         ALOGE("keys and values arrays have different length");
    186         jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
    187         return false;
    188     }
    189 
    190     for (int i = 0; i < nKeyValuePairs; ++i) {
    191         // No need to check on the ArrayIndexOutOfBoundsException, since
    192         // it won't happen here.
    193         jstring key = (jstring) env->GetObjectArrayElement(keys, i);
    194         jstring value = (jstring) env->GetObjectArrayElement(values, i);
    195 
    196         const char* keyStr = env->GetStringUTFChars(key, NULL);
    197         if (!keyStr) {  // OutOfMemoryError
    198             return false;
    199         }
    200 
    201         const char* valueStr = env->GetStringUTFChars(value, NULL);
    202         if (!valueStr) {  // OutOfMemoryError
    203             env->ReleaseStringUTFChars(key, keyStr);
    204             return false;
    205         }
    206 
    207         keyedVector->add(String8(keyStr), String8(valueStr));
    208 
    209         env->ReleaseStringUTFChars(key, keyStr);
    210         env->ReleaseStringUTFChars(value, valueStr);
    211         env->DeleteLocalRef(key);
    212         env->DeleteLocalRef(value);
    213     }
    214     return true;
    215 }
    216 
    217 static jobject makeIntegerObject(JNIEnv *env, int32_t value) {
    218     ScopedLocalRef<jclass> clazz(env, env->FindClass("java/lang/Integer"));
    219     CHECK(clazz.get() != NULL);
    220 
    221     jmethodID integerConstructID =
    222         env->GetMethodID(clazz.get(), "<init>", "(I)V");
    223     CHECK(integerConstructID != NULL);
    224 
    225     return env->NewObject(clazz.get(), integerConstructID, value);
    226 }
    227 
    228 static jobject makeLongObject(JNIEnv *env, int64_t value) {
    229     ScopedLocalRef<jclass> clazz(env, env->FindClass("java/lang/Long"));
    230     CHECK(clazz.get() != NULL);
    231 
    232     jmethodID longConstructID = env->GetMethodID(clazz.get(), "<init>", "(J)V");
    233     CHECK(longConstructID != NULL);
    234 
    235     return env->NewObject(clazz.get(), longConstructID, value);
    236 }
    237 
    238 static jobject makeFloatObject(JNIEnv *env, float value) {
    239     ScopedLocalRef<jclass> clazz(env, env->FindClass("java/lang/Float"));
    240     CHECK(clazz.get() != NULL);
    241 
    242     jmethodID floatConstructID =
    243         env->GetMethodID(clazz.get(), "<init>", "(F)V");
    244     CHECK(floatConstructID != NULL);
    245 
    246     return env->NewObject(clazz.get(), floatConstructID, value);
    247 }
    248 
    249 static jobject makeByteBufferObject(
    250         JNIEnv *env, const void *data, size_t size) {
    251     jbyteArray byteArrayObj = env->NewByteArray(size);
    252     env->SetByteArrayRegion(byteArrayObj, 0, size, (const jbyte *)data);
    253 
    254     ScopedLocalRef<jclass> clazz(env, env->FindClass("java/nio/ByteBuffer"));
    255     CHECK(clazz.get() != NULL);
    256 
    257     jmethodID byteBufWrapID =
    258         env->GetStaticMethodID(
    259                 clazz.get(), "wrap", "([B)Ljava/nio/ByteBuffer;");
    260     CHECK(byteBufWrapID != NULL);
    261 
    262     jobject byteBufObj = env->CallStaticObjectMethod(
    263             clazz.get(), byteBufWrapID, byteArrayObj);
    264 
    265     env->DeleteLocalRef(byteArrayObj); byteArrayObj = NULL;
    266 
    267     return byteBufObj;
    268 }
    269 
    270 static void SetMapInt32(
    271         JNIEnv *env, jobject hashMapObj, jmethodID hashMapPutID,
    272         const char *key, int32_t value) {
    273     jstring keyObj = env->NewStringUTF(key);
    274     jobject valueObj = makeIntegerObject(env, value);
    275 
    276     env->CallObjectMethod(hashMapObj, hashMapPutID, keyObj, valueObj);
    277 
    278     env->DeleteLocalRef(valueObj); valueObj = NULL;
    279     env->DeleteLocalRef(keyObj); keyObj = NULL;
    280 }
    281 
    282 status_t ConvertMessageToMap(
    283         JNIEnv *env, const sp<AMessage> &msg, jobject *map) {
    284     ScopedLocalRef<jclass> hashMapClazz(
    285             env, env->FindClass("java/util/HashMap"));
    286 
    287     if (hashMapClazz.get() == NULL) {
    288         return -EINVAL;
    289     }
    290 
    291     jmethodID hashMapConstructID =
    292         env->GetMethodID(hashMapClazz.get(), "<init>", "()V");
    293 
    294     if (hashMapConstructID == NULL) {
    295         return -EINVAL;
    296     }
    297 
    298     jmethodID hashMapPutID =
    299         env->GetMethodID(
    300                 hashMapClazz.get(),
    301                 "put",
    302                 "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
    303 
    304     if (hashMapPutID == NULL) {
    305         return -EINVAL;
    306     }
    307 
    308     jobject hashMap = env->NewObject(hashMapClazz.get(), hashMapConstructID);
    309 
    310     for (size_t i = 0; i < msg->countEntries(); ++i) {
    311         AMessage::Type valueType;
    312         const char *key = msg->getEntryNameAt(i, &valueType);
    313 
    314         if (!strncmp(key, "android._", 9)) {
    315             // don't expose private keys (starting with android._)
    316             continue;
    317         }
    318 
    319         jobject valueObj = NULL;
    320 
    321         switch (valueType) {
    322             case AMessage::kTypeInt32:
    323             {
    324                 int32_t val;
    325                 CHECK(msg->findInt32(key, &val));
    326 
    327                 valueObj = makeIntegerObject(env, val);
    328                 break;
    329             }
    330 
    331             case AMessage::kTypeInt64:
    332             {
    333                 int64_t val;
    334                 CHECK(msg->findInt64(key, &val));
    335 
    336                 valueObj = makeLongObject(env, val);
    337                 break;
    338             }
    339 
    340             case AMessage::kTypeFloat:
    341             {
    342                 float val;
    343                 CHECK(msg->findFloat(key, &val));
    344 
    345                 valueObj = makeFloatObject(env, val);
    346                 break;
    347             }
    348 
    349             case AMessage::kTypeString:
    350             {
    351                 AString val;
    352                 CHECK(msg->findString(key, &val));
    353 
    354                 valueObj = env->NewStringUTF(val.c_str());
    355                 break;
    356             }
    357 
    358             case AMessage::kTypeBuffer:
    359             {
    360                 sp<ABuffer> buffer;
    361                 CHECK(msg->findBuffer(key, &buffer));
    362 
    363                 valueObj = makeByteBufferObject(
    364                         env, buffer->data(), buffer->size());
    365                 break;
    366             }
    367 
    368             case AMessage::kTypeRect:
    369             {
    370                 int32_t left, top, right, bottom;
    371                 CHECK(msg->findRect(key, &left, &top, &right, &bottom));
    372 
    373                 SetMapInt32(
    374                         env,
    375                         hashMap,
    376                         hashMapPutID,
    377                         AStringPrintf("%s-left", key).c_str(),
    378                         left);
    379 
    380                 SetMapInt32(
    381                         env,
    382                         hashMap,
    383                         hashMapPutID,
    384                         AStringPrintf("%s-top", key).c_str(),
    385                         top);
    386 
    387                 SetMapInt32(
    388                         env,
    389                         hashMap,
    390                         hashMapPutID,
    391                         AStringPrintf("%s-right", key).c_str(),
    392                         right);
    393 
    394                 SetMapInt32(
    395                         env,
    396                         hashMap,
    397                         hashMapPutID,
    398                         AStringPrintf("%s-bottom", key).c_str(),
    399                         bottom);
    400                 break;
    401             }
    402 
    403             default:
    404                 break;
    405         }
    406 
    407         if (valueObj != NULL) {
    408             jstring keyObj = env->NewStringUTF(key);
    409 
    410             env->CallObjectMethod(hashMap, hashMapPutID, keyObj, valueObj);
    411 
    412             env->DeleteLocalRef(keyObj); keyObj = NULL;
    413             env->DeleteLocalRef(valueObj); valueObj = NULL;
    414         }
    415     }
    416 
    417     *map = hashMap;
    418 
    419     return OK;
    420 }
    421 
    422 status_t ConvertKeyValueArraysToMessage(
    423         JNIEnv *env, jobjectArray keys, jobjectArray values,
    424         sp<AMessage> *out) {
    425     ScopedLocalRef<jclass> stringClass(env, env->FindClass("java/lang/String"));
    426     CHECK(stringClass.get() != NULL);
    427     ScopedLocalRef<jclass> integerClass(env, env->FindClass("java/lang/Integer"));
    428     CHECK(integerClass.get() != NULL);
    429     ScopedLocalRef<jclass> longClass(env, env->FindClass("java/lang/Long"));
    430     CHECK(longClass.get() != NULL);
    431     ScopedLocalRef<jclass> floatClass(env, env->FindClass("java/lang/Float"));
    432     CHECK(floatClass.get() != NULL);
    433     ScopedLocalRef<jclass> byteBufClass(env, env->FindClass("java/nio/ByteBuffer"));
    434     CHECK(byteBufClass.get() != NULL);
    435 
    436     sp<AMessage> msg = new AMessage;
    437 
    438     jsize numEntries = 0;
    439 
    440     if (keys != NULL) {
    441         if (values == NULL) {
    442             return -EINVAL;
    443         }
    444 
    445         numEntries = env->GetArrayLength(keys);
    446 
    447         if (numEntries != env->GetArrayLength(values)) {
    448             return -EINVAL;
    449         }
    450     } else if (values != NULL) {
    451         return -EINVAL;
    452     }
    453 
    454     for (jsize i = 0; i < numEntries; ++i) {
    455         jobject keyObj = env->GetObjectArrayElement(keys, i);
    456 
    457         if (!env->IsInstanceOf(keyObj, stringClass.get())) {
    458             return -EINVAL;
    459         }
    460 
    461         const char *tmp = env->GetStringUTFChars((jstring)keyObj, NULL);
    462 
    463         if (tmp == NULL) {
    464             return -ENOMEM;
    465         }
    466 
    467         AString key = tmp;
    468 
    469         env->ReleaseStringUTFChars((jstring)keyObj, tmp);
    470         tmp = NULL;
    471 
    472         if (key.startsWith("android._")) {
    473             // don't propagate private keys (starting with android._)
    474             continue;
    475         }
    476 
    477         jobject valueObj = env->GetObjectArrayElement(values, i);
    478 
    479         if (env->IsInstanceOf(valueObj, stringClass.get())) {
    480             const char *value = env->GetStringUTFChars((jstring)valueObj, NULL);
    481 
    482             if (value == NULL) {
    483                 return -ENOMEM;
    484             }
    485 
    486             msg->setString(key.c_str(), value);
    487 
    488             env->ReleaseStringUTFChars((jstring)valueObj, value);
    489             value = NULL;
    490         } else if (env->IsInstanceOf(valueObj, integerClass.get())) {
    491             jmethodID intValueID =
    492                 env->GetMethodID(integerClass.get(), "intValue", "()I");
    493             CHECK(intValueID != NULL);
    494 
    495             jint value = env->CallIntMethod(valueObj, intValueID);
    496 
    497             msg->setInt32(key.c_str(), value);
    498         } else if (env->IsInstanceOf(valueObj, longClass.get())) {
    499             jmethodID longValueID =
    500                 env->GetMethodID(longClass.get(), "longValue", "()J");
    501             CHECK(longValueID != NULL);
    502 
    503             jlong value = env->CallLongMethod(valueObj, longValueID);
    504 
    505             msg->setInt64(key.c_str(), value);
    506         } else if (env->IsInstanceOf(valueObj, floatClass.get())) {
    507             jmethodID floatValueID =
    508                 env->GetMethodID(floatClass.get(), "floatValue", "()F");
    509             CHECK(floatValueID != NULL);
    510 
    511             jfloat value = env->CallFloatMethod(valueObj, floatValueID);
    512 
    513             msg->setFloat(key.c_str(), value);
    514         } else if (env->IsInstanceOf(valueObj, byteBufClass.get())) {
    515             jmethodID positionID =
    516                 env->GetMethodID(byteBufClass.get(), "position", "()I");
    517             CHECK(positionID != NULL);
    518 
    519             jmethodID limitID =
    520                 env->GetMethodID(byteBufClass.get(), "limit", "()I");
    521             CHECK(limitID != NULL);
    522 
    523             jint position = env->CallIntMethod(valueObj, positionID);
    524             jint limit = env->CallIntMethod(valueObj, limitID);
    525 
    526             sp<ABuffer> buffer = new ABuffer(limit - position);
    527 
    528             void *data = env->GetDirectBufferAddress(valueObj);
    529 
    530             if (data != NULL) {
    531                 memcpy(buffer->data(),
    532                        (const uint8_t *)data + position,
    533                        buffer->size());
    534             } else {
    535                 jmethodID arrayID =
    536                     env->GetMethodID(byteBufClass.get(), "array", "()[B");
    537                 CHECK(arrayID != NULL);
    538 
    539                 jbyteArray byteArray =
    540                     (jbyteArray)env->CallObjectMethod(valueObj, arrayID);
    541                 CHECK(byteArray != NULL);
    542 
    543                 env->GetByteArrayRegion(
    544                         byteArray,
    545                         position,
    546                         buffer->size(),
    547                         (jbyte *)buffer->data());
    548 
    549                 env->DeleteLocalRef(byteArray); byteArray = NULL;
    550             }
    551 
    552             msg->setBuffer(key.c_str(), buffer);
    553         }
    554     }
    555 
    556     *out = msg;
    557 
    558     return OK;
    559 }
    560 
    561 // -----------Utility functions used by ImageReader/Writer JNI-----------------
    562 
    563 enum {
    564     IMAGE_MAX_NUM_PLANES = 3,
    565 };
    566 
    567 bool usingRGBAToJpegOverride(int32_t imageFormat,
    568         int32_t containerFormat) {
    569     return containerFormat == HAL_PIXEL_FORMAT_BLOB && imageFormat == HAL_PIXEL_FORMAT_RGBA_8888;
    570 }
    571 
    572 int32_t applyFormatOverrides(int32_t imageFormat, int32_t containerFormat) {
    573     // Using HAL_PIXEL_FORMAT_RGBA_8888 gralloc buffers containing JPEGs to get around SW
    574     // write limitations for some platforms (b/17379185).
    575     if (usingRGBAToJpegOverride(imageFormat, containerFormat)) {
    576         return HAL_PIXEL_FORMAT_BLOB;
    577     }
    578     return containerFormat;
    579 }
    580 
    581 bool isFormatOpaque(int format) {
    582     // This is the only opaque format exposed in the ImageFormat public API.
    583     // Note that we do support CPU access for HAL_PIXEL_FORMAT_RAW_OPAQUE
    584     // (ImageFormat#RAW_PRIVATE) so it doesn't count as opaque here.
    585     return format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
    586 }
    587 
    588 bool isPossiblyYUV(PixelFormat format) {
    589     switch (static_cast<int>(format)) {
    590         case HAL_PIXEL_FORMAT_RGBA_8888:
    591         case HAL_PIXEL_FORMAT_RGBX_8888:
    592         case HAL_PIXEL_FORMAT_RGB_888:
    593         case HAL_PIXEL_FORMAT_RGB_565:
    594         case HAL_PIXEL_FORMAT_BGRA_8888:
    595         case HAL_PIXEL_FORMAT_Y8:
    596         case HAL_PIXEL_FORMAT_Y16:
    597         case HAL_PIXEL_FORMAT_RAW16:
    598         case HAL_PIXEL_FORMAT_RAW10:
    599         case HAL_PIXEL_FORMAT_RAW_OPAQUE:
    600         case HAL_PIXEL_FORMAT_BLOB:
    601         case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
    602             return false;
    603 
    604         case HAL_PIXEL_FORMAT_YV12:
    605         case HAL_PIXEL_FORMAT_YCbCr_420_888:
    606         case HAL_PIXEL_FORMAT_YCrCb_420_SP:
    607         default:
    608             return true;
    609     }
    610 }
    611 
    612 uint32_t Image_getJpegSize(LockedImage* buffer, bool usingRGBAOverride) {
    613     ALOGV("%s", __FUNCTION__);
    614     LOG_ALWAYS_FATAL_IF(buffer == NULL, "Input buffer is NULL!!!");
    615     uint32_t size = 0;
    616     uint32_t width = buffer->width;
    617     uint8_t* jpegBuffer = buffer->data;
    618 
    619     if (usingRGBAOverride) {
    620         width = (buffer->width + buffer->stride * (buffer->height - 1)) * 4;
    621     }
    622 
    623     // First check for JPEG transport header at the end of the buffer
    624     uint8_t* header = jpegBuffer + (width - sizeof(struct camera3_jpeg_blob));
    625     struct camera3_jpeg_blob *blob = (struct camera3_jpeg_blob*)(header);
    626     if (blob->jpeg_blob_id == CAMERA3_JPEG_BLOB_ID) {
    627         size = blob->jpeg_size;
    628         ALOGV("%s: Jpeg size = %d", __FUNCTION__, size);
    629     }
    630 
    631     // failed to find size, default to whole buffer
    632     if (size == 0) {
    633         /*
    634          * This is a problem because not including the JPEG header
    635          * means that in certain rare situations a regular JPEG blob
    636          * will be mis-identified as having a header, in which case
    637          * we will get a garbage size value.
    638          */
    639         ALOGW("%s: No JPEG header detected, defaulting to size=width=%d",
    640                 __FUNCTION__, width);
    641         size = width;
    642     }
    643 
    644     return size;
    645 }
    646 
    647 status_t getLockedImageInfo(LockedImage* buffer, int idx,
    648         int32_t containerFormat, uint8_t **base, uint32_t *size, int *pixelStride, int *rowStride) {
    649     ALOGV("%s", __FUNCTION__);
    650     LOG_ALWAYS_FATAL_IF(buffer == NULL, "Input buffer is NULL!!!");
    651     LOG_ALWAYS_FATAL_IF(base == NULL, "base is NULL!!!");
    652     LOG_ALWAYS_FATAL_IF(size == NULL, "size is NULL!!!");
    653     LOG_ALWAYS_FATAL_IF(pixelStride == NULL, "pixelStride is NULL!!!");
    654     LOG_ALWAYS_FATAL_IF(rowStride == NULL, "rowStride is NULL!!!");
    655     LOG_ALWAYS_FATAL_IF((idx >= IMAGE_MAX_NUM_PLANES) || (idx < 0), "idx (%d) is illegal", idx);
    656 
    657     ALOGV("%s: buffer: %p", __FUNCTION__, buffer);
    658 
    659     uint32_t dataSize, ySize, cSize, cStride;
    660     uint32_t pStride = 0, rStride = 0;
    661     uint8_t *cb, *cr;
    662     uint8_t *pData = NULL;
    663     int bytesPerPixel = 0;
    664 
    665     dataSize = ySize = cSize = cStride = 0;
    666     int32_t fmt = buffer->flexFormat;
    667 
    668     bool usingRGBAOverride = usingRGBAToJpegOverride(fmt, containerFormat);
    669     fmt = applyFormatOverrides(fmt, containerFormat);
    670     switch (fmt) {
    671         case HAL_PIXEL_FORMAT_YCbCr_420_888:
    672             pData =
    673                 (idx == 0) ?
    674                     buffer->data :
    675                 (idx == 1) ?
    676                     buffer->dataCb :
    677                 buffer->dataCr;
    678             // only map until last pixel
    679             if (idx == 0) {
    680                 pStride = 1;
    681                 rStride = buffer->stride;
    682                 dataSize = buffer->stride * (buffer->height - 1) + buffer->width;
    683             } else {
    684                 pStride = buffer->chromaStep;
    685                 rStride = buffer->chromaStride;
    686                 dataSize = buffer->chromaStride * (buffer->height / 2 - 1) +
    687                         buffer->chromaStep * (buffer->width / 2 - 1) + 1;
    688             }
    689             break;
    690         // NV21
    691         case HAL_PIXEL_FORMAT_YCrCb_420_SP:
    692             cr = buffer->data + (buffer->stride * buffer->height);
    693             cb = cr + 1;
    694             // only map until last pixel
    695             ySize = buffer->width * (buffer->height - 1) + buffer->width;
    696             cSize = buffer->width * (buffer->height / 2 - 1) + buffer->width - 1;
    697 
    698             pData =
    699                 (idx == 0) ?
    700                     buffer->data :
    701                 (idx == 1) ?
    702                     cb:
    703                 cr;
    704 
    705             dataSize = (idx == 0) ? ySize : cSize;
    706             pStride = (idx == 0) ? 1 : 2;
    707             rStride = buffer->width;
    708             break;
    709         case HAL_PIXEL_FORMAT_YV12:
    710             // Y and C stride need to be 16 pixel aligned.
    711             LOG_ALWAYS_FATAL_IF(buffer->stride % 16,
    712                                 "Stride is not 16 pixel aligned %d", buffer->stride);
    713 
    714             ySize = buffer->stride * buffer->height;
    715             cStride = ALIGN(buffer->stride / 2, 16);
    716             cr = buffer->data + ySize;
    717             cSize = cStride * buffer->height / 2;
    718             cb = cr + cSize;
    719 
    720             pData =
    721                 (idx == 0) ?
    722                     buffer->data :
    723                 (idx == 1) ?
    724                     cb :
    725                 cr;
    726             dataSize = (idx == 0) ? ySize : cSize;
    727             pStride = 1;
    728             rStride = (idx == 0) ? buffer->stride : ALIGN(buffer->stride / 2, 16);
    729             break;
    730         case HAL_PIXEL_FORMAT_Y8:
    731             // Single plane, 8bpp.
    732             LOG_ALWAYS_FATAL_IF(idx != 0, "Wrong index: %d", idx);
    733 
    734             pData = buffer->data;
    735             dataSize = buffer->stride * buffer->height;
    736             pStride = 1;
    737             rStride = buffer->stride;
    738             break;
    739         case HAL_PIXEL_FORMAT_Y16:
    740             bytesPerPixel = 2;
    741             // Single plane, 16bpp, strides are specified in pixels, not in bytes
    742             LOG_ALWAYS_FATAL_IF(idx != 0, "Wrong index: %d", idx);
    743 
    744             pData = buffer->data;
    745             dataSize = buffer->stride * buffer->height * bytesPerPixel;
    746             pStride = bytesPerPixel;
    747             rStride = buffer->stride * 2;
    748             break;
    749         case HAL_PIXEL_FORMAT_BLOB:
    750             // Used for JPEG data, height must be 1, width == size, single plane.
    751             LOG_ALWAYS_FATAL_IF(idx != 0, "Wrong index: %d", idx);
    752             // When RGBA override is being used, buffer height will be equal to width
    753             if (usingRGBAOverride) {
    754                 LOG_ALWAYS_FATAL_IF(buffer->height != buffer->width,
    755                         "RGBA override BLOB format buffer should have height == width");
    756             } else {
    757                 LOG_ALWAYS_FATAL_IF(buffer->height != 1,
    758                         "BLOB format buffer should have height value 1");
    759             }
    760 
    761 
    762             pData = buffer->data;
    763             dataSize = Image_getJpegSize(buffer, usingRGBAOverride);
    764             pStride = 0;
    765             rStride = 0;
    766             break;
    767         case HAL_PIXEL_FORMAT_RAW16:
    768             // Single plane 16bpp bayer data.
    769             bytesPerPixel = 2;
    770             LOG_ALWAYS_FATAL_IF(idx != 0, "Wrong index: %d", idx);
    771             pData = buffer->data;
    772             dataSize = buffer->stride * buffer->height * bytesPerPixel;
    773             pStride = bytesPerPixel;
    774             rStride = buffer->stride * 2;
    775             break;
    776         case HAL_PIXEL_FORMAT_RAW_OPAQUE:
    777             // Used for RAW_OPAQUE data, height must be 1, width == size, single plane.
    778             LOG_ALWAYS_FATAL_IF(idx != 0, "Wrong index: %d", idx);
    779             LOG_ALWAYS_FATAL_IF(buffer->height != 1,
    780                     "RAW_PRIVATE should has height value one but got %d", buffer->height);
    781             pData = buffer->data;
    782             dataSize = buffer->width;
    783             pStride = 0; // RAW OPAQUE doesn't have pixel stride
    784             rStride = 0; // RAW OPAQUE doesn't have row stride
    785             break;
    786         case HAL_PIXEL_FORMAT_RAW10:
    787             // Single plane 10bpp bayer data.
    788             LOG_ALWAYS_FATAL_IF(idx != 0, "Wrong index: %d", idx);
    789             LOG_ALWAYS_FATAL_IF(buffer->width % 4,
    790                                 "Width is not multiple of 4 %d", buffer->width);
    791             LOG_ALWAYS_FATAL_IF(buffer->height % 2,
    792                                 "Height is not even %d", buffer->height);
    793             LOG_ALWAYS_FATAL_IF(buffer->stride < (buffer->width * 10 / 8),
    794                                 "stride (%d) should be at least %d",
    795                                 buffer->stride, buffer->width * 10 / 8);
    796             pData = buffer->data;
    797             dataSize = buffer->stride * buffer->height;
    798             pStride = 0;
    799             rStride = buffer->stride;
    800             break;
    801         case HAL_PIXEL_FORMAT_RAW12:
    802             // Single plane 10bpp bayer data.
    803             LOG_ALWAYS_FATAL_IF(idx != 0, "Wrong index: %d", idx);
    804             LOG_ALWAYS_FATAL_IF(buffer->width % 4,
    805                                 "Width is not multiple of 4 %d", buffer->width);
    806             LOG_ALWAYS_FATAL_IF(buffer->height % 2,
    807                                 "Height is not even %d", buffer->height);
    808             LOG_ALWAYS_FATAL_IF(buffer->stride < (buffer->width * 12 / 8),
    809                                 "stride (%d) should be at least %d",
    810                                 buffer->stride, buffer->width * 12 / 8);
    811             pData = buffer->data;
    812             dataSize = buffer->stride * buffer->height;
    813             pStride = 0;
    814             rStride = buffer->stride;
    815             break;
    816         case HAL_PIXEL_FORMAT_RGBA_8888:
    817         case HAL_PIXEL_FORMAT_RGBX_8888:
    818             // Single plane, 32bpp.
    819             bytesPerPixel = 4;
    820             LOG_ALWAYS_FATAL_IF(idx != 0, "Wrong index: %d", idx);
    821             pData = buffer->data;
    822             dataSize = buffer->stride * buffer->height * bytesPerPixel;
    823             pStride = bytesPerPixel;
    824             rStride = buffer->stride * 4;
    825             break;
    826         case HAL_PIXEL_FORMAT_RGB_565:
    827             // Single plane, 16bpp.
    828             bytesPerPixel = 2;
    829             LOG_ALWAYS_FATAL_IF(idx != 0, "Wrong index: %d", idx);
    830             pData = buffer->data;
    831             dataSize = buffer->stride * buffer->height * bytesPerPixel;
    832             pStride = bytesPerPixel;
    833             rStride = buffer->stride * 2;
    834             break;
    835         case HAL_PIXEL_FORMAT_RGB_888:
    836             // Single plane, 24bpp.
    837             bytesPerPixel = 3;
    838             LOG_ALWAYS_FATAL_IF(idx != 0, "Wrong index: %d", idx);
    839             pData = buffer->data;
    840             dataSize = buffer->stride * buffer->height * bytesPerPixel;
    841             pStride = bytesPerPixel;
    842             rStride = buffer->stride * 3;
    843             break;
    844         default:
    845             return BAD_VALUE;
    846     }
    847 
    848     *base = pData;
    849     *size = dataSize;
    850     *pixelStride = pStride;
    851     *rowStride = rStride;
    852 
    853     return OK;
    854 }
    855 
    856 status_t lockImageFromBuffer(sp<GraphicBuffer> buffer, uint32_t inUsage,
    857         const Rect& rect, int fenceFd, LockedImage* outputImage) {
    858     ALOGV("%s: Try to lock the GraphicBuffer", __FUNCTION__);
    859 
    860     if (buffer == nullptr || outputImage == nullptr) {
    861         ALOGE("Input BufferItem or output LockedImage is NULL!");
    862         return BAD_VALUE;
    863     }
    864     if (isFormatOpaque(buffer->getPixelFormat())) {
    865         ALOGE("Opaque format buffer is not lockable!");
    866         return BAD_VALUE;
    867     }
    868 
    869     void* pData = NULL;
    870     android_ycbcr ycbcr = android_ycbcr();
    871     status_t res;
    872     int format = buffer->getPixelFormat();
    873     int flexFormat = format;
    874     if (isPossiblyYUV(format)) {
    875         res = buffer->lockAsyncYCbCr(inUsage, rect, &ycbcr, fenceFd);
    876         pData = ycbcr.y;
    877         flexFormat = HAL_PIXEL_FORMAT_YCbCr_420_888;
    878     }
    879 
    880     // lockAsyncYCbCr for YUV is unsuccessful.
    881     if (pData == NULL) {
    882         res = buffer->lockAsync(inUsage, rect, &pData, fenceFd);
    883         if (res != OK) {
    884             ALOGE("Lock buffer failed!");
    885             return res;
    886         }
    887     }
    888 
    889     outputImage->data = reinterpret_cast<uint8_t*>(pData);
    890     outputImage->width = buffer->getWidth();
    891     outputImage->height = buffer->getHeight();
    892     outputImage->format = format;
    893     outputImage->flexFormat = flexFormat;
    894     outputImage->stride =
    895             (ycbcr.y != NULL) ? static_cast<uint32_t>(ycbcr.ystride) : buffer->getStride();
    896 
    897     outputImage->dataCb = reinterpret_cast<uint8_t*>(ycbcr.cb);
    898     outputImage->dataCr = reinterpret_cast<uint8_t*>(ycbcr.cr);
    899     outputImage->chromaStride = static_cast<uint32_t>(ycbcr.cstride);
    900     outputImage->chromaStep = static_cast<uint32_t>(ycbcr.chroma_step);
    901     ALOGV("%s: Successfully locked the image from the GraphicBuffer", __FUNCTION__);
    902     // Crop, transform, scalingMode, timestamp, and frameNumber should be set by caller,
    903     // and cann't be set them here.
    904     return OK;
    905 }
    906 
    907 status_t lockImageFromBuffer(BufferItem* bufferItem, uint32_t inUsage,
    908         int fenceFd, LockedImage* outputImage) {
    909     ALOGV("%s: Try to lock the BufferItem", __FUNCTION__);
    910     if (bufferItem == nullptr || outputImage == nullptr) {
    911         ALOGE("Input BufferItem or output LockedImage is NULL!");
    912         return BAD_VALUE;
    913     }
    914 
    915     status_t res = lockImageFromBuffer(bufferItem->mGraphicBuffer, inUsage, bufferItem->mCrop,
    916             fenceFd, outputImage);
    917     if (res != OK) {
    918         ALOGE("%s: lock graphic buffer failed", __FUNCTION__);
    919         return res;
    920     }
    921 
    922     outputImage->crop        = bufferItem->mCrop;
    923     outputImage->transform   = bufferItem->mTransform;
    924     outputImage->scalingMode = bufferItem->mScalingMode;
    925     outputImage->timestamp   = bufferItem->mTimestamp;
    926     outputImage->dataSpace   = bufferItem->mDataSpace;
    927     outputImage->frameNumber = bufferItem->mFrameNumber;
    928     ALOGV("%s: Successfully locked the image from the BufferItem", __FUNCTION__);
    929     return OK;
    930 }
    931 
    932 int getBufferWidth(BufferItem* buffer) {
    933     if (buffer == NULL) return -1;
    934 
    935     if (!buffer->mCrop.isEmpty()) {
    936         return buffer->mCrop.getWidth();
    937     }
    938 
    939     ALOGV("%s: buffer->mGraphicBuffer: %p", __FUNCTION__, buffer->mGraphicBuffer.get());
    940     return buffer->mGraphicBuffer->getWidth();
    941 }
    942 
    943 int getBufferHeight(BufferItem* buffer) {
    944     if (buffer == NULL) return -1;
    945 
    946     if (!buffer->mCrop.isEmpty()) {
    947         return buffer->mCrop.getHeight();
    948     }
    949 
    950     ALOGV("%s: buffer->mGraphicBuffer: %p", __FUNCTION__, buffer->mGraphicBuffer.get());
    951     return buffer->mGraphicBuffer->getHeight();
    952 }
    953 
    954 }  // namespace android
    955 
    956