| /* |
| * Copyright (C) 2011 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| |
| #define LOG_NDEBUG 1 |
| #define LOG_TAG "PreviewRenderer" |
| #include <utils/Log.h> |
| |
| #include "PreviewRenderer.h" |
| |
| #include <media/stagefright/foundation/ADebug.h> |
| #include <gui/Surface.h> |
| |
| namespace android { |
| |
| PreviewRenderer* PreviewRenderer::CreatePreviewRenderer ( |
| const sp<Surface> &surface, size_t width, size_t height) { |
| |
| PreviewRenderer* renderer = new PreviewRenderer(surface, width, height); |
| |
| if (renderer->init() != 0) { |
| delete renderer; |
| return NULL; |
| } |
| |
| return renderer; |
| } |
| |
| PreviewRenderer::PreviewRenderer( |
| const sp<Surface> &surface, |
| size_t width, size_t height) |
| : mSurface(surface), |
| mWidth(width), |
| mHeight(height) { |
| } |
| |
| int PreviewRenderer::init() { |
| int err = 0; |
| ANativeWindow* anw = mSurface.get(); |
| |
| err = native_window_api_connect(anw, NATIVE_WINDOW_API_CPU); |
| if (err) goto fail; |
| |
| err = native_window_set_usage( |
| anw, GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_OFTEN); |
| if (err) goto fail; |
| |
| err = native_window_set_buffer_count(anw, 3); |
| if (err) goto fail; |
| |
| err = native_window_set_scaling_mode( |
| anw, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW); |
| if (err) goto fail; |
| |
| err = native_window_set_buffers_geometry( |
| anw, mWidth, mHeight, HAL_PIXEL_FORMAT_YV12); |
| if (err) goto fail; |
| |
| err = native_window_set_buffers_transform(anw, 0); |
| if (err) goto fail; |
| |
| fail: |
| return err; |
| } |
| |
| PreviewRenderer::~PreviewRenderer() { |
| native_window_api_disconnect(mSurface.get(), NATIVE_WINDOW_API_CPU); |
| } |
| |
| |
| // |
| // Provides a buffer and associated stride |
| // This buffer is allocated by the SurfaceFlinger |
| // |
| // For optimal display performances, you should : |
| // 1) call getBufferYV12() |
| // 2) fill the buffer with your data |
| // 3) call renderYV12() to take these changes into account |
| // |
| // For each call to getBufferYV12(), you must also call renderYV12() |
| // Expected format in the buffer is YV12 formats (similar to YUV420 planar fromat) |
| // for more details on this YV12 cf hardware/libhardware/include/hardware/hardware.h |
| // |
| void PreviewRenderer::getBufferYV12(uint8_t **data, size_t *stride) { |
| int err = OK; |
| |
| if ((err = native_window_dequeue_buffer_and_wait(mSurface.get(), |
| &mBuf)) != 0) { |
| ALOGW("native_window_dequeue_buffer_and_wait returned error %d", err); |
| return; |
| } |
| |
| GraphicBufferMapper &mapper = GraphicBufferMapper::get(); |
| |
| Rect bounds(mWidth, mHeight); |
| |
| void *dst; |
| CHECK_EQ(0, mapper.lock(mBuf->handle, |
| GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_OFTEN, |
| bounds, &dst)); |
| |
| *data = (uint8_t*)dst; |
| *stride = mBuf->stride; |
| } |
| |
| |
| // |
| // Display the content of the buffer provided by last call to getBufferYV12() |
| // |
| // See getBufferYV12() for details. |
| // |
| void PreviewRenderer::renderYV12() { |
| int err = OK; |
| |
| GraphicBufferMapper &mapper = GraphicBufferMapper::get(); |
| |
| if (mBuf!= NULL) { |
| CHECK_EQ(0, mapper.unlock(mBuf->handle)); |
| |
| if ((err = mSurface->ANativeWindow::queueBuffer(mSurface.get(), mBuf, -1)) != 0) { |
| ALOGW("Surface::queueBuffer returned error %d", err); |
| } |
| } |
| mBuf = NULL; |
| } |
| |
| } // namespace android |