19969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang/*
29969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang * Copyright (C) 2011 The Android Open Source Project
39969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang *
49969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang * Licensed under the Apache License, Version 2.0 (the "License");
59969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang * you may not use this file except in compliance with the License.
69969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang * You may obtain a copy of the License at
79969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang *
89969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang *      http://www.apache.org/licenses/LICENSE-2.0
99969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang *
109969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang * Unless required by applicable law or agreed to in writing, software
119969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang * distributed under the License is distributed on an "AS IS" BASIS,
129969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang * See the License for the specific language governing permissions and
149969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang * limitations under the License.
159969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang */
169969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
179969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
189969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang#define LOG_NDEBUG 1
199969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang#define LOG_TAG "PreviewRenderer"
209969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang#include <utils/Log.h>
219969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
229969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang#include "PreviewRenderer.h"
239969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
24c4689fae1bdb8d1c94eb28af1b2a1f30d2b1a3daJames Dong#include <media/stagefright/foundation/ADebug.h>
2590b6191067990a7a3ee947d7ce08c64f780f0de7Mathias Agopian#include <gui/Surface.h>
269969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
279969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Changnamespace android {
289969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
2908b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung ChangPreviewRenderer* PreviewRenderer::CreatePreviewRenderer (
3008b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Chang        const sp<Surface> &surface, size_t width, size_t height) {
319969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
3208b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Chang    PreviewRenderer* renderer = new PreviewRenderer(surface, width, height);
339969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
3408b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Chang    if (renderer->init() != 0) {
3508b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Chang        delete renderer;
3608b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Chang        return NULL;
3708b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Chang    }
389969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
3908b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Chang    return renderer;
409969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang}
419969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
429969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung ChangPreviewRenderer::PreviewRenderer(
439969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        const sp<Surface> &surface,
4408b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Chang        size_t width, size_t height)
4508b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Chang    : mSurface(surface),
4608b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Chang      mWidth(width),
4708b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Chang      mHeight(height) {
4808b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Chang}
4908b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Chang
5008b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Changint PreviewRenderer::init() {
5108b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Chang    int err = 0;
52aef59c544429aae73429a1325d43e830600e3b67Chih-Chung Chang    ANativeWindow* anw = mSurface.get();
5308b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Chang
54aef59c544429aae73429a1325d43e830600e3b67Chih-Chung Chang    err = native_window_api_connect(anw, NATIVE_WINDOW_API_CPU);
5508b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Chang    if (err) goto fail;
5608b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Chang
57aef59c544429aae73429a1325d43e830600e3b67Chih-Chung Chang    err = native_window_set_usage(
58aef59c544429aae73429a1325d43e830600e3b67Chih-Chung Chang            anw, GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_OFTEN);
5908b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Chang    if (err) goto fail;
6008b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Chang
61aef59c544429aae73429a1325d43e830600e3b67Chih-Chung Chang    err = native_window_set_buffer_count(anw, 3);
6208b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Chang    if (err) goto fail;
6308b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Chang
6408b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Chang    err = native_window_set_scaling_mode(
65aef59c544429aae73429a1325d43e830600e3b67Chih-Chung Chang            anw, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
6608b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Chang    if (err) goto fail;
6708b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Chang
6808b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Chang    err = native_window_set_buffers_geometry(
69aef59c544429aae73429a1325d43e830600e3b67Chih-Chung Chang            anw, mWidth, mHeight, HAL_PIXEL_FORMAT_YV12);
70aef59c544429aae73429a1325d43e830600e3b67Chih-Chung Chang    if (err) goto fail;
71aef59c544429aae73429a1325d43e830600e3b67Chih-Chung Chang
72aef59c544429aae73429a1325d43e830600e3b67Chih-Chung Chang    err = native_window_set_buffers_transform(anw, 0);
7308b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Chang    if (err) goto fail;
7408b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Chang
7508b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Changfail:
7608b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Chang    return err;
779969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang}
789969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
799969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung ChangPreviewRenderer::~PreviewRenderer() {
8008b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Chang    native_window_api_disconnect(mSurface.get(), NATIVE_WINDOW_API_CPU);
819969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang}
829969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
839969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
849969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang//
859969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang// Provides a buffer and associated stride
869969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang// This buffer is allocated by the SurfaceFlinger
879969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang//
889969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang// For optimal display performances, you should :
899969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang// 1) call getBufferYV12()
909969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang// 2) fill the buffer with your data
919969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang// 3) call renderYV12() to take these changes into account
929969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang//
939969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang// For each call to getBufferYV12(), you must also call renderYV12()
949969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang// Expected format in the buffer is YV12 formats (similar to YUV420 planar fromat)
959969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang// for more details on this YV12 cf hardware/libhardware/include/hardware/hardware.h
969969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang//
979969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Changvoid PreviewRenderer::getBufferYV12(uint8_t **data, size_t *stride) {
989969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    int err = OK;
999969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
1001e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    if ((err = native_window_dequeue_buffer_and_wait(mSurface.get(),
1011e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis            &mBuf)) != 0) {
1021e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        ALOGW("native_window_dequeue_buffer_and_wait returned error %d", err);
1039969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        return;
1049969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    }
1059969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
1069969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    GraphicBufferMapper &mapper = GraphicBufferMapper::get();
1079969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
10808b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Chang    Rect bounds(mWidth, mHeight);
1099969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
1109969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    void *dst;
11108b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Chang    CHECK_EQ(0, mapper.lock(mBuf->handle,
11208b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Chang            GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_OFTEN,
11308b82bddf54757ad6bd243181f1b68a79bb70e6dChih-Chung Chang            bounds, &dst));
1149969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
1159969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    *data   = (uint8_t*)dst;
1169969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    *stride = mBuf->stride;
1179969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang}
1189969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
1199969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
1209969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang//
1219969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang// Display the content of the buffer provided by last call to getBufferYV12()
1229969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang//
1239969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang// See getBufferYV12() for details.
1249969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang//
1259969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Changvoid PreviewRenderer::renderYV12() {
1269969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    int err = OK;
1279969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
1289969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    GraphicBufferMapper &mapper = GraphicBufferMapper::get();
1299969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
1309969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    if (mBuf!= NULL) {
1319969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        CHECK_EQ(0, mapper.unlock(mBuf->handle));
1329969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
1331e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        if ((err = mSurface->ANativeWindow::queueBuffer(mSurface.get(), mBuf, -1)) != 0) {
134e70ff37034fdb93f65d34704aec400ec9123e55cSteve Block            ALOGW("Surface::queueBuffer returned error %d", err);
1359969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        }
1369969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    }
1379969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    mBuf = NULL;
1389969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang}
1399969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
1409969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang}  // namespace android
141