diff options
author | Eino-Ville Talvala <etalvala@google.com> | 2013-05-09 17:13:33 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2013-05-09 17:13:33 +0000 |
commit | 7cb87e43550cae1e051530994a2c30e89a268862 (patch) | |
tree | 70ff436d6b93b594d9fa87c966efc899e53dbaf1 | |
parent | 4a0a02bebf7c3b0b79df6635b8129d7a54b38da2 (diff) | |
parent | ec38324c23d4865ec4b6f368f12814328771b4af (diff) | |
download | device_generic_goldfish-7cb87e43550cae1e051530994a2c30e89a268862.tar.gz device_generic_goldfish-7cb87e43550cae1e051530994a2c30e89a268862.tar.bz2 device_generic_goldfish-7cb87e43550cae1e051530994a2c30e89a268862.zip |
Merge "Gralloc/Camera3: Support new HAL_PIXEL_FORMAT_YCbCr_420_888 format" into jb-mr2-dev
-rw-r--r-- | camera/EmulatedFakeCamera3.cpp | 51 | ||||
-rw-r--r-- | camera/EmulatedFakeCamera3.h | 2 | ||||
-rw-r--r-- | opengl/system/OpenglSystemCommon/gralloc_cb.h | 6 | ||||
-rw-r--r-- | opengl/system/gralloc/gralloc.cpp | 141 |
4 files changed, 183 insertions, 17 deletions
diff --git a/camera/EmulatedFakeCamera3.cpp b/camera/EmulatedFakeCamera3.cpp index adcde88c..a321218a 100644 --- a/camera/EmulatedFakeCamera3.cpp +++ b/camera/EmulatedFakeCamera3.cpp @@ -51,12 +51,15 @@ const int64_t USEC = 1000LL; const int64_t MSEC = USEC * 1000LL; const int64_t SEC = MSEC * 1000LL; -const uint32_t EmulatedFakeCamera3::kAvailableFormats[4] = { +const int32_t EmulatedFakeCamera3::kAvailableFormats[5] = { HAL_PIXEL_FORMAT_RAW_SENSOR, HAL_PIXEL_FORMAT_BLOB, HAL_PIXEL_FORMAT_RGBA_8888, + HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, + // These are handled by YCbCr_420_888 // HAL_PIXEL_FORMAT_YV12, - HAL_PIXEL_FORMAT_YCrCb_420_SP + // HAL_PIXEL_FORMAT_YCrCb_420_SP, + HAL_PIXEL_FORMAT_YCbCr_420_888 }; const uint32_t EmulatedFakeCamera3::kAvailableRawSizes[2] = { @@ -294,6 +297,21 @@ status_t EmulatedFakeCamera3::configureStreams( } inputStream = newStream; } + + bool validFormat = false; + for (size_t f = 0; + f < sizeof(kAvailableFormats)/sizeof(kAvailableFormats[0]); + f++) { + if (newStream->format == kAvailableFormats[f]) { + validFormat = true; + break; + } + } + if (!validFormat) { + ALOGE("%s: Unsupported stream format 0x%x requested", + __FUNCTION__, newStream->format); + return BAD_VALUE; + } } mInputStream = inputStream; @@ -877,8 +895,26 @@ status_t EmulatedFakeCamera3::processCaptureRequest( if (res == OK) { // Lock buffer for writing const Rect rect(destBuf.width, destBuf.height); - res = GraphicBufferMapper::get().lock(*(destBuf.buffer), - GRALLOC_USAGE_HW_CAMERA_WRITE, rect, (void**)&(destBuf.img)); + if (srcBuf.stream->format == HAL_PIXEL_FORMAT_YCbCr_420_888) { + if (privBuffer->format == HAL_PIXEL_FORMAT_YCrCb_420_SP) { + android_ycbcr ycbcr = android_ycbcr(); + res = GraphicBufferMapper::get().lockYCbCr( + *(destBuf.buffer), + GRALLOC_USAGE_HW_CAMERA_WRITE, rect, + &ycbcr); + // This is only valid because we know that emulator's + // YCbCr_420_888 is really contiguous NV21 under the hood + destBuf.img = static_cast<uint8_t*>(ycbcr.y); + } else { + ALOGE("Unexpected private format for flexible YUV: 0x%x", + privBuffer->format); + res = INVALID_OPERATION; + } + } else { + res = GraphicBufferMapper::get().lock(*(destBuf.buffer), + GRALLOC_USAGE_HW_CAMERA_WRITE, rect, + (void**)&(destBuf.img)); + } if (res != OK) { ALOGE("%s: Request %d: Buffer %d: Unable to lock buffer", __FUNCTION__, frameNumber, i); @@ -886,7 +922,8 @@ status_t EmulatedFakeCamera3::processCaptureRequest( } if (res != OK) { - // Either waiting or locking failed. Unlock locked buffers and bail out. + // Either waiting or locking failed. Unlock locked buffers and bail + // out. for (size_t j = 0; j < i; j++) { GraphicBufferMapper::get().unlock( *(request->output_buffers[i].buffer)); @@ -1111,8 +1148,8 @@ status_t EmulatedFakeCamera3::constructStaticInfo() { // android.scaler info.update(ANDROID_SCALER_AVAILABLE_FORMATS, - (int32_t*)kAvailableFormats, - sizeof(kAvailableFormats)/sizeof(uint32_t)); + kAvailableFormats, + sizeof(kAvailableFormats)/sizeof(int32_t)); info.update(ANDROID_SCALER_AVAILABLE_RAW_SIZES, (int32_t*)kAvailableRawSizes, diff --git a/camera/EmulatedFakeCamera3.h b/camera/EmulatedFakeCamera3.h index 0b3e2db5..e9ef1848 100644 --- a/camera/EmulatedFakeCamera3.h +++ b/camera/EmulatedFakeCamera3.h @@ -135,7 +135,7 @@ private: // sensor-generated buffers which use a nonpositive ID. Otherwise, HAL3 has // no concept of a stream id. static const uint32_t kGenericStreamId = 1; - static const uint32_t kAvailableFormats[]; + static const int32_t kAvailableFormats[]; static const uint32_t kAvailableRawSizes[]; static const uint64_t kAvailableRawMinDurations[]; static const uint32_t kAvailableProcessedSizesBack[]; diff --git a/opengl/system/OpenglSystemCommon/gralloc_cb.h b/opengl/system/OpenglSystemCommon/gralloc_cb.h index a2074011..fd35473d 100644 --- a/opengl/system/OpenglSystemCommon/gralloc_cb.h +++ b/opengl/system/OpenglSystemCommon/gralloc_cb.h @@ -30,13 +30,14 @@ struct cb_handle_t : public native_handle { cb_handle_t(int p_fd, int p_ashmemSize, int p_usage, - int p_width, int p_height, int p_format, - int p_glFormat, int p_glType) : + int p_width, int p_height, int p_frameworkFormat, + int p_format, int p_glFormat, int p_glType) : fd(p_fd), magic(BUFFER_HANDLE_MAGIC), usage(p_usage), width(p_width), height(p_height), + frameworkFormat(p_frameworkFormat), format(p_format), glFormat(p_glFormat), glType(p_glType), @@ -89,6 +90,7 @@ struct cb_handle_t : public native_handle { int usage; // usage bits the buffer was created with int width; // buffer width int height; // buffer height + int frameworkFormat; // format requested by the Android framework int format; // real internal pixel format format int glFormat; // OpenGL format enum used for host h/w color buffer int glType; // OpenGL type enum used when uploading to host diff --git a/opengl/system/gralloc/gralloc.cpp b/opengl/system/gralloc/gralloc.cpp index 311146ff..ed5d05f4 100644 --- a/opengl/system/gralloc/gralloc.cpp +++ b/opengl/system/gralloc/gralloc.cpp @@ -154,6 +154,8 @@ static int gralloc_alloc(alloc_device_t* dev, bool hw_cam_read = usage & GRALLOC_USAGE_HW_CAMERA_READ; bool hw_vid_enc_read = usage & GRALLOC_USAGE_HW_VIDEO_ENCODER; + // Keep around original requested format for later validation + int frameworkFormat = format; // Pick the right concrete pixel format given the endpoints as encoded in // the usage bits. Every end-point pair needs explicit listing here. if (format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) { @@ -178,8 +180,17 @@ static int gralloc_alloc(alloc_device_t* dev, w, h, usage); return -EINVAL; } + } else if (format == HAL_PIXEL_FORMAT_YCbCr_420_888) { + // Flexible framework-accessible YUV format; map to NV21 for now + if (usage & GRALLOC_USAGE_HW_CAMERA_WRITE) { + format = HAL_PIXEL_FORMAT_YCrCb_420_SP; + } + if (format == HAL_PIXEL_FORMAT_YCbCr_420_888) { + ALOGE("gralloc_alloc: Requested YCbCr_420_888, but no known " + "specific format for this usage: %d x %d, usage %x", + w, h, usage); + } } - bool yuv_format = false; int ashmem_size = 0; @@ -297,7 +308,8 @@ static int gralloc_alloc(alloc_device_t* dev, } cb_handle_t *cb = new cb_handle_t(fd, ashmem_size, usage, - w, h, format, glFormat, glType); + w, h, frameworkFormat, format, + glFormat, glType); if (ashmem_size > 0) { // @@ -350,7 +362,11 @@ static int gralloc_alloc(alloc_device_t* dev, pthread_mutex_unlock(&grdev->lock); *pHandle = cb; - *pStride = stride; + if (frameworkFormat == HAL_PIXEL_FORMAT_YCbCr_420_888) { + *pStride = 0; + } else { + *pStride = stride; + } return 0; } @@ -580,7 +596,7 @@ static int gralloc_unregister_buffer(gralloc_module_t const* module, ERR("gralloc_unregister_buffer(%p): unmap failed", cb); return -EINVAL; } - cb->ashmemBase = NULL; + cb->ashmemBase = 0; cb->mappedPid = 0; } @@ -605,6 +621,12 @@ static int gralloc_lock(gralloc_module_t const* module, return -EINVAL; } + // validate format + if (cb->frameworkFormat == HAL_PIXEL_FORMAT_YCbCr_420_888) { + ALOGE("gralloc_lock can't be used with YCbCr_420_888 format"); + return -EINVAL; + } + // Validate usage, // 1. cannot be locked for hw access // 2. lock for either sw read or write. @@ -759,6 +781,109 @@ static int gralloc_unlock(gralloc_module_t const* module, return 0; } +static int gralloc_lock_ycbcr(gralloc_module_t const* module, + buffer_handle_t handle, int usage, + int l, int t, int w, int h, + android_ycbcr *ycbcr) +{ + // Not supporting fallback module for YCbCr + if (sFallback != NULL) { + return -EINVAL; + } + + if (!ycbcr) { + ALOGE("gralloc_lock_ycbcr got NULL ycbcr struct"); + return -EINVAL; + } + + private_module_t *gr = (private_module_t *)module; + cb_handle_t *cb = (cb_handle_t *)handle; + if (!gr || !cb_handle_t::validate(cb)) { + ALOGE("gralloc_lock_ycbcr bad handle\n"); + return -EINVAL; + } + + if (cb->frameworkFormat != HAL_PIXEL_FORMAT_YCbCr_420_888) { + ALOGE("gralloc_lock_ycbcr can only be used with " + "HAL_PIXEL_FORMAT_YCbCr_420_888, got %x instead", + cb->frameworkFormat); + return -EINVAL; + } + + // Validate usage + // For now, only allow camera write, software read. + bool sw_read = (0 != (usage & GRALLOC_USAGE_SW_READ_MASK)); + bool hw_cam_write = (usage & GRALLOC_USAGE_HW_CAMERA_WRITE); + bool sw_read_allowed = (0 != (cb->usage & GRALLOC_USAGE_SW_READ_MASK)); + + if ( (!hw_cam_write && !sw_read) || + (sw_read && !sw_read_allowed) ) { + ALOGE("gralloc_lock_ycbcr usage mismatch usage:0x%x cb->usage:0x%x\n", + usage, cb->usage); + return -EINVAL; + } + + // Make sure memory is mapped, get address + if (cb->ashmemBasePid != getpid() || !cb->ashmemBase) { + return -EACCES; + } + + uint8_t *cpu_addr = NULL; + + if (cb->canBePosted()) { + cpu_addr = (uint8_t *)(cb->ashmemBase + sizeof(int)); + } + else { + cpu_addr = (uint8_t *)(cb->ashmemBase); + } + + // Calculate offsets to underlying YUV data + size_t yStride; + size_t cStride; + size_t yOffset; + size_t uOffset; + size_t vOffset; + size_t cStep; + switch (cb->format) { + case HAL_PIXEL_FORMAT_YCrCb_420_SP: + yStride = cb->width; + cStride = cb->width; + yOffset = 0; + vOffset = yStride * cb->height; + uOffset = vOffset + 1; + cStep = 2; + break; + default: + ALOGE("gralloc_lock_ycbcr unexpected internal format %x", + cb->format); + return -EINVAL; + } + + ycbcr->y = cpu_addr + yOffset; + ycbcr->cb = cpu_addr + uOffset; + ycbcr->cr = cpu_addr + vOffset; + ycbcr->ystride = yStride; + ycbcr->cstride = cStride; + ycbcr->chroma_step = cStep; + + // Zero out reserved fields + memset(ycbcr->reserved, 0, sizeof(ycbcr->reserved)); + + // + // Keep locked region if locked for s/w write access. + // + cb->lockedLeft = l; + cb->lockedTop = t; + cb->lockedWidth = w; + cb->lockedHeight = h; + + DD("gralloc_lock_ycbcr success. usage: %x, ycbcr.y: %p, .cb: %p, .cr: %p, " + ".ystride: %d , .cstride: %d, .chroma_step: %d", usage, + ycbcr->y, ycbcr->cb, ycbcr->cr, ycbcr->ystride, ycbcr->cstride, + ycbcr->chroma_step); + + return 0; +} static int gralloc_device_open(const hw_module_t* module, const char* name, @@ -881,8 +1006,8 @@ struct private_module_t HAL_MODULE_INFO_SYM = { base: { common: { tag: HARDWARE_MODULE_TAG, - version_major: 1, - version_minor: 0, + module_api_version: GRALLOC_MODULE_API_VERSION_0_2, + hal_api_version: 0, id: GRALLOC_HARDWARE_MODULE_ID, name: "Graphics Memory Allocator Module", author: "The Android Open Source Project", @@ -894,7 +1019,9 @@ struct private_module_t HAL_MODULE_INFO_SYM = { unregisterBuffer: gralloc_unregister_buffer, lock: gralloc_lock, unlock: gralloc_unlock, - perform: NULL + perform: NULL, + lock_ycbcr: gralloc_lock_ycbcr, + reserved_proc: {0, } } }; |