bool PreviewWindow::onNextFrameAvailableHW(const void* frame, nsecs_t timestamp, V4L2Camera* camera_dev) { int res; V4L2BUF_t * pv4l2_buf = (V4L2BUF_t *)frame; Mutex::Autolock locker(&mObjectLock); if (!isPreviewEnabled() || mPreviewWindow == NULL) { return true; } /* Make sure that preview window dimensions are OK with the camera device */ if (adjustPreviewDimensions(camera_dev) || mShouldAdjustDimensions) { ALOGD("%s: Adjusting preview windows %p geometry to %dx%d", __FUNCTION__, mPreviewWindow, mPreviewFrameWidth, mPreviewFrameHeight); res = mPreviewWindow->set_buffers_geometryex(mPreviewWindow, mPreviewFrameWidth, mPreviewFrameHeight, HWC_FORMAT_DEFAULT, mScreenID); if (res != NO_ERROR) { ALOGE("%s: Error in set_buffers_geometry %d -> %s", __FUNCTION__, -res, strerror(-res)); mShouldAdjustDimensions = true; return false; } mPreviewWindow->perform(mPreviewWindow, NATIVE_WINDOW_SETPARAMETER, HWC_LAYER_SETFORMAT, mLayerFormat); mShouldAdjustDimensions = false; mPreviewWindow->set_crop(mPreviewWindow, mRectCrop.left, mRectCrop.top, mRectCrop.right, mRectCrop.bottom); mNewCrop = false; ALOGV("first hw: [%d, %d, %d, %d]", mRectCrop.left, mRectCrop.top, mRectCrop.right, mRectCrop.bottom); } libhwclayerpara_t overlay_para; overlay_para.bProgressiveSrc = 1; overlay_para.bTopFieldFirst = 1; overlay_para.pVideoInfo.frame_rate = 25000; overlay_para.top_y = (unsigned int)pv4l2_buf->addrPhyY; overlay_para.top_c = (unsigned int)pv4l2_buf->addrPhyY + mPreviewFrameWidth * mPreviewFrameHeight; overlay_para.bottom_y = 0; overlay_para.bottom_c = 0; overlay_para.number = 0; if (mOverlayFirstFrame) { ALOGV("first frame true"); overlay_para.first_frame_flg = 1; mOverlayFirstFrame = false; } else { overlay_para.first_frame_flg = 0; } // ALOGV("addrY: %x, addrC: %x, WXH: %dx%d", overlay_para.top_y, overlay_para.top_c, mPreviewFrameWidth, mPreviewFrameHeight); if (mNewCrop) { mPreviewWindow->set_crop(mPreviewWindow, mRectCrop.left, mRectCrop.top, mRectCrop.right, mRectCrop.bottom); mNewCrop = false; } res = mPreviewWindow->perform(mPreviewWindow, NATIVE_WINDOW_SETPARAMETER, HWC_LAYER_SETFRAMEPARA, (uint32_t)&overlay_para); if (res != OK) { ALOGE("NATIVE_WINDOW_SETPARAMETER failed"); return false; } if (mLayerShowHW == 0) { showLayer(true); } return true; }
bool PreviewWindow::onNextFrameAvailableSW(const void* frame, nsecs_t timestamp, V4L2Camera* camera_dev) { int res; Mutex::Autolock locker(&mObjectLock); // ALOGD("%s, timestamp: %lld", __FUNCTION__, timestamp); if (!isPreviewEnabled() || mPreviewWindow == NULL) { return true; } /* Make sure that preview window dimensions are OK with the camera device */ if (adjustPreviewDimensions(camera_dev) || mShouldAdjustDimensions) { /* Need to set / adjust buffer geometry for the preview window. * Note that in the emulator preview window uses only RGB for pixel * formats. */ ALOGD("%s: Adjusting preview windows %p geometry to %dx%d", __FUNCTION__, mPreviewWindow, mPreviewFrameWidth, mPreviewFrameHeight); #if PREVIEW_FMT_RGBA32 int format = HAL_PIXEL_FORMAT_RGBA_8888; ALOGV("preview format: HAL_PIXEL_FORMAT_RGBA_8888"); #else int format = HAL_PIXEL_FORMAT_YCrCb_420_SP; ALOGV("preview format: HAL_PIXEL_FORMAT_YCrCb_420_SP"); #endif res = mPreviewWindow->set_buffers_geometry(mPreviewWindow, mPreviewFrameWidth, mPreviewFrameHeight, format); if (res != NO_ERROR) { ALOGE("%s: Error in set_buffers_geometry %d -> %s", __FUNCTION__, -res, strerror(-res)); // return false; } mShouldAdjustDimensions = false; res = mPreviewWindow->set_buffer_count(mPreviewWindow, 3); if (res != 0) { ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-res), -res); if ( ENODEV == res ) { ALOGE("Preview surface abandoned!"); mPreviewWindow = NULL; } return false; } mPreviewWindow->set_crop(mPreviewWindow, mRectCrop.left, mRectCrop.top, mRectCrop.right, mRectCrop.bottom); mNewCrop = false; ALOGV("first sw: [%d, %d, %d, %d]", mRectCrop.left, mRectCrop.top, mRectCrop.right, mRectCrop.bottom); } /* * Push new frame to the preview window. */ /* Dequeue preview window buffer for the frame. */ buffer_handle_t* buffer = NULL; int stride = 0; res = mPreviewWindow->dequeue_buffer(mPreviewWindow, &buffer, &stride); if (res != NO_ERROR || buffer == NULL) { ALOGE("%s: Unable to dequeue preview window buffer: %d -> %s", __FUNCTION__, -res, strerror(-res)); int undequeued = 0; mPreviewWindow->get_min_undequeued_buffer_count(mPreviewWindow, &undequeued); ALOGW("now undequeued: %d", undequeued); return false; } /* Let the preview window to lock the buffer. */ res = mPreviewWindow->lock_buffer(mPreviewWindow, buffer); if (res != NO_ERROR) { ALOGE("%s: Unable to lock preview window buffer: %d -> %s", __FUNCTION__, -res, strerror(-res)); mPreviewWindow->cancel_buffer(mPreviewWindow, buffer); return false; } /* Now let the graphics framework to lock the buffer, and provide * us with the framebuffer data address. */ void* img = NULL; const Rect rect(mPreviewFrameWidth, mPreviewFrameHeight); GraphicBufferMapper& grbuffer_mapper(GraphicBufferMapper::get()); res = grbuffer_mapper.lock(*buffer, GRALLOC_USAGE_SW_WRITE_OFTEN, rect, &img); if (res != NO_ERROR) { ALOGE("%s: grbuffer_mapper.lock failure: %d -> %s", __FUNCTION__, res, strerror(res)); mPreviewWindow->cancel_buffer(mPreviewWindow, buffer); return false; } if (mNewCrop) { mPreviewWindow->set_crop(mPreviewWindow, mRectCrop.left, mRectCrop.top, mRectCrop.right, mRectCrop.bottom); mNewCrop = false; } /* Frames come in in YV12/NV12/NV21 format. Since preview window doesn't * supports those formats, we need to obtain the frame in RGB565. */ res = camera_dev->getCurrentPreviewFrame(img); if (res == NO_ERROR) { /* Show it. */ mPreviewWindow->enqueue_buffer(mPreviewWindow, buffer); } else { ALOGE("%s: Unable to obtain preview frame: %d", __FUNCTION__, res); mPreviewWindow->cancel_buffer(mPreviewWindow, buffer); } grbuffer_mapper.unlock(*buffer); return true; }
bool PreviewWindow::onNextFrameAvailableSW(const void* frame, int video_fmt, nsecs_t timestamp, V4L2Camera* camera_dev) { int res; Mutex::Autolock locker(&mObjectLock); V4L2BUF_t * pv4l2_buf = (V4L2BUF_t *)frame; // LOGD("%s, timestamp: %lld", __FUNCTION__, timestamp); if (!isPreviewEnabled() || mPreviewWindow == NULL) { return true; } /* Make sure that preview window dimensions are OK with the camera device */ if (adjustPreviewDimensions(camera_dev) || mShouldAdjustDimensions) { /* Need to set / adjust buffer geometry for the preview window. * Note that in the emulator preview window uses only RGB for pixel * formats. */ LOGD("%s: Adjusting preview windows %p geometry to %dx%d", __FUNCTION__, mPreviewWindow, mPreviewFrameWidth, mPreviewFrameHeight); int format = HAL_PIXEL_FORMAT_YCrCb_420_SP; LOGV("preview format: HAL_PIXEL_FORMAT_YCrCb_420_SP"); res = mPreviewWindow->set_buffers_geometry(mPreviewWindow, mPreviewFrameWidth, mPreviewFrameHeight, format); if (res != NO_ERROR) { LOGE("%s: Error in set_buffers_geometry %d -> %s", __FUNCTION__, -res, strerror(-res)); // return false; } mShouldAdjustDimensions = false; res = mPreviewWindow->set_buffer_count(mPreviewWindow, 3); if (res != 0) { LOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-res), -res); if ( ENODEV == res ) { LOGE("Preview surface abandoned!"); mPreviewWindow = NULL; } return false; } mPreviewWindow->set_crop(mPreviewWindow, mRectCrop.left, mRectCrop.top, mRectCrop.right, mRectCrop.bottom); mNewCrop = false; LOGV("first sw: [%d, %d, %d, %d]", mRectCrop.left, mRectCrop.top, mRectCrop.right, mRectCrop.bottom); } /* * Push new frame to the preview window. */ /* Dequeue preview window buffer for the frame. */ buffer_handle_t* buffer = NULL; int stride = 0; res = mPreviewWindow->dequeue_buffer(mPreviewWindow, &buffer, &stride); if (res != NO_ERROR || buffer == NULL) { LOGE("%s: Unable to dequeue preview window buffer: %d -> %s", __FUNCTION__, -res, strerror(-res)); int undequeued = 0; mPreviewWindow->get_min_undequeued_buffer_count(mPreviewWindow, &undequeued); LOGW("now undequeued: %d", undequeued); return false; } /* Let the preview window to lock the buffer. */ res = mPreviewWindow->lock_buffer(mPreviewWindow, buffer); if (res != NO_ERROR) { LOGE("%s: Unable to lock preview window buffer: %d -> %s", __FUNCTION__, -res, strerror(-res)); mPreviewWindow->cancel_buffer(mPreviewWindow, buffer); return false; } /* Now let the graphics framework to lock the buffer, and provide * us with the framebuffer data address. */ void* img = NULL; const Rect rect(mPreviewFrameWidth, mPreviewFrameHeight); GraphicBufferMapper& grbuffer_mapper(GraphicBufferMapper::get()); res = grbuffer_mapper.lock(*buffer, GRALLOC_USAGE_SW_WRITE_OFTEN, rect, &img); if (res != NO_ERROR) { LOGE("%s: grbuffer_mapper.lock failure: %d -> %s", __FUNCTION__, res, strerror(res)); mPreviewWindow->cancel_buffer(mPreviewWindow, buffer); return false; } if (mNewCrop) { mPreviewWindow->set_crop(mPreviewWindow, mRectCrop.left, mRectCrop.top, mRectCrop.right, mRectCrop.bottom); mNewCrop = false; } if (pv4l2_buf->format == V4L2_PIX_FMT_NV21) { memcpy(img, (void*)pv4l2_buf->addrVirY, mPreviewFrameWidth * mPreviewFrameHeight * 3/2); } else { NV12ToNV21_shift((void*)pv4l2_buf->addrVirY, img, mPreviewFrameWidth, mPreviewFrameHeight); } mPreviewWindow->enqueue_buffer(mPreviewWindow, buffer); grbuffer_mapper.unlock(*buffer); return true; }