1e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/*
2e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard * Copyright (C) 2011 The Android Open Source Project
3e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard *
4e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard * Licensed under the Apache License, Version 2.0 (the "License");
5e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard * you may not use this file except in compliance with the License.
6e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard * You may obtain a copy of the License at
7e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard *
8e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard *      http://www.apache.org/licenses/LICENSE-2.0
9e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard *
10e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard * Unless required by applicable law or agreed to in writing, software
11e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard * distributed under the License is distributed on an "AS IS" BASIS,
12e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard * See the License for the specific language governing permissions and
14e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard * limitations under the License.
15e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard */
16e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
17e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
18e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#define LOG_NDEBUG 1
19e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#define LOG_TAG "PreviewRenderer"
20e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include <utils/Log.h>
21e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
22e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "PreviewRenderer.h"
23e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
24e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include <media/stagefright/foundation/ADebug.h>
25e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include <gui/Surface.h>
26e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
27e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardnamespace android {
28e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
29e2e838afcf03e603a41a0455846eaf9614537c16Mans RullgardPreviewRenderer* PreviewRenderer::CreatePreviewRenderer (
30e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard        const sp<Surface> &surface, size_t width, size_t height) {
31e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
32e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard    PreviewRenderer* renderer = new PreviewRenderer(surface, width, height);
33e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
34e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard    if (renderer->init() != 0) {
35e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard        delete renderer;
36e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard        return NULL;
37e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard    }
38b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
39e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard    return renderer;
40e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard}
41e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
42e2e838afcf03e603a41a0455846eaf9614537c16Mans RullgardPreviewRenderer::PreviewRenderer(
43e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard        const sp<Surface> &surface,
44b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard        size_t width, size_t height)
45e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard    : mSurface(surface),
46e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard      mWidth(width),
47e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard      mHeight(height) {
48e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard}
49b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
50e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardint PreviewRenderer::init() {
51b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard    int err = 0;
52e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard    ANativeWindow* anw = mSurface.get();
53e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
54e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard    err = native_window_api_connect(anw, NATIVE_WINDOW_API_CPU);
55e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard    if (err) goto fail;
56e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
57e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard    err = native_window_set_usage(
58e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard            anw, GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_OFTEN);
59e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard    if (err) goto fail;
60e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
61e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard    err = native_window_set_buffer_count(anw, 3);
62e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard    if (err) goto fail;
63e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
64e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard    err = native_window_set_scaling_mode(
65e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard            anw, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
66e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard    if (err) goto fail;
67b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
68e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard    err = native_window_set_buffers_geometry(
69e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard            anw, mWidth, mHeight, HAL_PIXEL_FORMAT_YV12);
70e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard    if (err) goto fail;
71e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
72e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard    err = native_window_set_buffers_transform(anw, 0);
73e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard    if (err) goto fail;
74b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
75e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardfail:
76e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard    return err;
77e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard}
78e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
79e2e838afcf03e603a41a0455846eaf9614537c16Mans RullgardPreviewRenderer::~PreviewRenderer() {
80b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard    native_window_api_disconnect(mSurface.get(), NATIVE_WINDOW_API_CPU);
81e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard}
82b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
83e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
84e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard//
85e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard// Provides a buffer and associated stride
86e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard// This buffer is allocated by the SurfaceFlinger
87e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard//
88e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard// For optimal display performances, you should :
89// 1) call getBufferYV12()
90// 2) fill the buffer with your data
91// 3) call renderYV12() to take these changes into account
92//
93// For each call to getBufferYV12(), you must also call renderYV12()
94// Expected format in the buffer is YV12 formats (similar to YUV420 planar fromat)
95// for more details on this YV12 cf hardware/libhardware/include/hardware/hardware.h
96//
97void PreviewRenderer::getBufferYV12(uint8_t **data, size_t *stride) {
98    int err = OK;
99
100    if ((err = native_window_dequeue_buffer_and_wait(mSurface.get(),
101            &mBuf)) != 0) {
102        ALOGW("native_window_dequeue_buffer_and_wait returned error %d", err);
103        return;
104    }
105
106    GraphicBufferMapper &mapper = GraphicBufferMapper::get();
107
108    Rect bounds(mWidth, mHeight);
109
110    void *dst;
111    CHECK_EQ(0, mapper.lock(mBuf->handle,
112            GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_OFTEN,
113            bounds, &dst));
114
115    *data   = (uint8_t*)dst;
116    *stride = mBuf->stride;
117}
118
119
120//
121// Display the content of the buffer provided by last call to getBufferYV12()
122//
123// See getBufferYV12() for details.
124//
125void PreviewRenderer::renderYV12() {
126    int err = OK;
127
128    GraphicBufferMapper &mapper = GraphicBufferMapper::get();
129
130    if (mBuf!= NULL) {
131        CHECK_EQ(0, mapper.unlock(mBuf->handle));
132
133        if ((err = mSurface->ANativeWindow::queueBuffer(mSurface.get(), mBuf, -1)) != 0) {
134            ALOGW("Surface::queueBuffer returned error %d", err);
135        }
136    }
137    mBuf = NULL;
138}
139
140}  // namespace android
141