static void Image_unlockIfLocked(JNIEnv* env, jobject thiz) {
    ALOGV("%s", __FUNCTION__);
    GraphicBuffer* buffer;
    Image_getNativeContext(env, thiz, &buffer, NULL);
    if (buffer == NULL) {
        jniThrowException(env, "java/lang/IllegalStateException",
                "Image is not initialized");
        return;
    }

    // Is locked?
    bool isLocked = false;
    jobject planes = NULL;
    if (!isFormatOpaque(buffer->getPixelFormat())) {
        planes = env->GetObjectField(thiz, gSurfaceImageClassInfo.mPlanes);
    }
    isLocked = (planes != NULL);
    if (isLocked) {
        // no need to use fence here, as we it will be consumed by either cancel or queue buffer.
        status_t res = buffer->unlock();
        if (res != OK) {
            jniThrowRuntimeException(env, "unlock buffer failed");
        }
        ALOGV("Successfully unlocked the image");
    }
}
static jint Image_getFormat(JNIEnv* env, jobject thiz) {
    ALOGV("%s", __FUNCTION__);
    GraphicBuffer* buffer;
    Image_getNativeContext(env, thiz, &buffer, NULL);
    if (buffer == NULL) {
        jniThrowException(env, "java/lang/IllegalStateException",
                "Image is not initialized");
        return 0;
    }

    return Image_getPixelFormat(env, buffer->getPixelFormat());
}
sp<CameraBuffer>
allocateGraphicBuffer(int w, int h, int gfxFmt, int cameraId, int usage)
{
    LOG1("@%s", __FUNCTION__);
    UNUSED(usage);
    status_t status = OK;

    void * mapperPointer = NULL;

    int lockMode = GRALLOC_USAGE_SW_READ_OFTEN |
                GRALLOC_USAGE_SW_WRITE_NEVER |
                GRALLOC_USAGE_HW_CAMERA_READ |
                GRALLOC_USAGE_HW_CAMERA_WRITE |
                GRALLOC_USAGE_HW_COMPOSER;

    LOG1("%s with these properties: (%dx%d) gfx format %d", __FUNCTION__,
            w, h, gfxFmt);

    GraphicBuffer *gfxBuffer = new GraphicBuffer
        (w, h, gfxFmt,
        GraphicBuffer::USAGE_HW_RENDER | GraphicBuffer::USAGE_SW_WRITE_OFTEN | \
        GraphicBuffer::USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_CAMERA_WRITE);

    if (!gfxBuffer) {
        LOGE("No memory to allocate graphic buffer");
        return NULL;
    }

    ANativeWindowBuffer *nativeWinBuffer = gfxBuffer->getNativeBuffer();

    status = gfxBuffer->lock(lockMode, &mapperPointer);
    if (status != NO_ERROR) {
        LOGE("@%s: Failed to lock GraphicBuffer! %d", __FUNCTION__, status);
        return NULL;
    }

    if (w != nativeWinBuffer->stride) {
        LOG1("%s: potential bpl problem requested %d, Gfx requries %d",
            __FUNCTION__, w, nativeWinBuffer->stride);
    } else {
        LOG1("%s bpl from Gfx is %d", __FUNCTION__, nativeWinBuffer->stride);
    }

    CameraBuffer * buf =
        new CameraBuffer(w, h, nativeWinBuffer->stride, gfxFmt, gfxBuffer, mapperPointer, cameraId);
    gfxBuffer->incStrong(buf);

    return buf;
}
static void Image_setNativeContext(JNIEnv* env, jobject thiz,
        sp<GraphicBuffer> buffer, int fenceFd) {
    ALOGV("%s:", __FUNCTION__);
    GraphicBuffer* p = NULL;
    Image_getNativeContext(env, thiz, &p, /*fenceFd*/NULL);
    if (buffer != 0) {
        buffer->incStrong((void*)Image_setNativeContext);
    }
    if (p) {
        p->decStrong((void*)Image_setNativeContext);
    }
    env->SetLongField(thiz, gSurfaceImageClassInfo.mNativeBuffer,
            reinterpret_cast<jlong>(buffer.get()));

    env->SetIntField(thiz, gSurfaceImageClassInfo.mNativeFenceFd, reinterpret_cast<jint>(fenceFd));
}
static void Image_getLockedImage(JNIEnv* env, jobject thiz, LockedImage *image) {
    ALOGV("%s", __FUNCTION__);
    GraphicBuffer* buffer;
    int fenceFd = -1;
    Image_getNativeContext(env, thiz, &buffer, &fenceFd);
    if (buffer == NULL) {
        jniThrowException(env, "java/lang/IllegalStateException",
                "Image is not initialized");
        return;
    }

    void* pData = NULL;
    android_ycbcr ycbcr = android_ycbcr();
    status_t res;
    int format = Image_getFormat(env, thiz);
    int flexFormat = format;
    if (isPossiblyYUV(format)) {
        // ImageWriter doesn't use crop by itself, app sets it, use the no crop version.
        res = buffer->lockAsyncYCbCr(GRALLOC_USAGE_SW_WRITE_OFTEN, &ycbcr, fenceFd);
        // Clear the fenceFd as it is already consumed by lock call.
        Image_setFenceFd(env, thiz, /*fenceFd*/-1);
        if (res != OK) {
            jniThrowRuntimeException(env, "lockAsyncYCbCr failed for YUV buffer");
            return;
        }
        pData = ycbcr.y;
        flexFormat = HAL_PIXEL_FORMAT_YCbCr_420_888;
    }

    // lockAsyncYCbCr for YUV is unsuccessful.
    if (pData == NULL) {
        res = buffer->lockAsync(GRALLOC_USAGE_SW_WRITE_OFTEN, &pData, fenceFd);
        if (res != OK) {
            jniThrowRuntimeException(env, "lockAsync failed");
            return;
        }
    }

    image->data = reinterpret_cast<uint8_t*>(pData);
    image->width = buffer->getWidth();
    image->height = buffer->getHeight();
    image->format = format;
    image->flexFormat = flexFormat;
    image->stride = (ycbcr.y != NULL) ? static_cast<uint32_t>(ycbcr.ystride) : buffer->getStride();

    image->dataCb = reinterpret_cast<uint8_t*>(ycbcr.cb);
    image->dataCr = reinterpret_cast<uint8_t*>(ycbcr.cr);
    image->chromaStride = static_cast<uint32_t>(ycbcr.cstride);
    image->chromaStep = static_cast<uint32_t>(ycbcr.chroma_step);
    ALOGV("Successfully locked the image");
    // crop, transform, scalingMode, timestamp, and frameNumber should be set by producer,
    // and we don't set them here.
}
Example #6
0
static GraphicBuffer*
create_composible_buffer(int width, int height) {
    uint32_t bufferFlags = GraphicBuffer::USAGE_SW_WRITE_RARELY | GraphicBuffer::USAGE_HW_COMPOSER;
    GraphicBuffer* buffer = new GraphicBuffer(width, height, PIXEL_FORMAT_RGBA_8888, bufferFlags);

    status_t err = buffer->initCheck();
    if (err) {
        LOGE("error creating GraphicBuffer: %s", strerror(-err));
        return NULL;
    }

    Rect rect = buffer->getBounds();
    LOGE("GraphicBuffer information");
    LOGE("width : %d", buffer->getWidth());
    LOGE("height: %d", buffer->getHeight());
    LOGE("stride: %d", buffer->getStride());
    LOGE("usage : 0x%08x", buffer->getUsage());
    LOGE("format: %d", buffer->getPixelFormat());
    LOGE("bounds: (%d,%d) - (%d,%d)", rect.left, rect.top, rect.right, rect.bottom);

    return buffer;
}
static jlong android_hardware_HardwareBuffer_getUsage(JNIEnv* env,
    jobject clazz, jlong nativeObject) {
    GraphicBuffer* buffer = GraphicBufferWrapper_to_GraphicBuffer(nativeObject);
    return AHardwareBuffer_convertFromGrallocUsageBits(buffer->getUsage());
}
static jint android_hardware_HardwareBuffer_getLayers(JNIEnv* env,
    jobject clazz, jlong nativeObject) {
    GraphicBuffer* buffer = GraphicBufferWrapper_to_GraphicBuffer(nativeObject);
    return static_cast<jint>(buffer->getLayerCount());
}
static jint android_hardware_HardwareBuffer_getFormat(JNIEnv* env,
    jobject clazz, jlong nativeObject) {
    GraphicBuffer* buffer = GraphicBufferWrapper_to_GraphicBuffer(nativeObject);
    return static_cast<jint>(android_hardware_HardwareBuffer_convertFromPixelFormat(
            buffer->getPixelFormat()));
}