PreviewRenderer.cpp revision 9969866cfe5b17c6e481b90d81b011a0cece78a0
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
249969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang#include <binder/MemoryHeapBase.h>
259969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang#include <binder/MemoryHeapPmem.h>
269969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang#include <media/stagefright/MediaDebug.h>
279969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang#include <surfaceflinger/Surface.h>
289969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
299969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Changnamespace android {
309969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
319969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung ChangPreviewRenderer* PreviewRenderer::CreatePreviewRenderer (OMX_COLOR_FORMATTYPE colorFormat,
329969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        const sp<Surface> &surface,
339969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        size_t displayWidth, size_t displayHeight,
349969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        size_t decodedWidth, size_t decodedHeight,
359969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        int32_t rotationDegrees) {
369969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
379969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        PreviewRenderer* returnCtx =
389969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang            new PreviewRenderer(colorFormat,
399969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang            surface,
409969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang            displayWidth, displayHeight,
419969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang            decodedWidth, decodedHeight,
429969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang            rotationDegrees);
439969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
449969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        int result = 0;
459969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
469969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        int halFormat;
479969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        switch (returnCtx->mColorFormat) {
489969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang            case OMX_COLOR_FormatYUV420Planar:
499969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang            {
509969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang                halFormat = HAL_PIXEL_FORMAT_YV12;
519969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang                returnCtx->mYUVMode = None;
529969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang                break;
539969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang            }
549969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang            default:
559969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang                halFormat = HAL_PIXEL_FORMAT_RGB_565;
569969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
579969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang                returnCtx->mConverter = new ColorConverter(
589969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang                        returnCtx->mColorFormat, OMX_COLOR_Format16bitRGB565);
599969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang                CHECK(returnCtx->mConverter->isValid());
609969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang                break;
619969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        }
629969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
639969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        CHECK(returnCtx->mSurface.get() != NULL);
649969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        CHECK(returnCtx->mDecodedWidth > 0);
659969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        CHECK(returnCtx->mDecodedHeight > 0);
669969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        CHECK(returnCtx->mConverter == NULL || returnCtx->mConverter->isValid());
679969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
689969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        result = native_window_set_usage(
699969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang                    returnCtx->mSurface.get(),
709969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang                    GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_OFTEN
719969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang                    | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP);
729969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
739969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        if ( result == 0 ) {
749969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang            result = native_window_set_buffer_count(returnCtx->mSurface.get(), 3);
759969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
769969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang            if (result == 0) {
779969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang                result = native_window_set_buffers_geometry(
789969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang                    returnCtx->mSurface.get(), returnCtx->mDecodedWidth, returnCtx->mDecodedHeight,
799969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang                    halFormat);
809969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang                if ( result == 0) {
819969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang                    uint32_t transform;
829969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang                    switch (rotationDegrees) {
839969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang                        case 0: transform = 0; break;
849969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang                        case 90: transform = HAL_TRANSFORM_ROT_90; break;
859969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang                        case 180: transform = HAL_TRANSFORM_ROT_180; break;
869969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang                        case 270: transform = HAL_TRANSFORM_ROT_270; break;
879969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang                        default: transform = 0; break;
889969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang                    }
899969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang                    if (transform) {
909969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang                        result = native_window_set_buffers_transform(
919969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang                                    returnCtx->mSurface.get(), transform);
929969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
939969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang                    }
949969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang                }
959969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang            }
969969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        }
979969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
989969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        if ( result != 0 )
999969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        {
1009969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang            /* free the ctx */
1019969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang            returnCtx->~PreviewRenderer();
1029969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang            return NULL;
1039969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        }
1049969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
1059969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        return returnCtx;
1069969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang}
1079969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
1089969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung ChangPreviewRenderer::PreviewRenderer(
1099969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        OMX_COLOR_FORMATTYPE colorFormat,
1109969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        const sp<Surface> &surface,
1119969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        size_t displayWidth, size_t displayHeight,
1129969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        size_t decodedWidth, size_t decodedHeight,
1139969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        int32_t rotationDegrees)
1149969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    : mColorFormat(colorFormat),
1159969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang      mConverter(NULL),
1169969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang      mYUVMode(None),
1179969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang      mSurface(surface),
1189969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang      mDisplayWidth(displayWidth),
1199969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang      mDisplayHeight(displayHeight),
1209969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang      mDecodedWidth(decodedWidth),
1219969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang      mDecodedHeight(decodedHeight) {
1229969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
1239969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    LOGV("input format = %d", mColorFormat);
1249969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    LOGV("display = %d x %d, decoded = %d x %d",
1259969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang            mDisplayWidth, mDisplayHeight, mDecodedWidth, mDecodedHeight);
1269969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
1279969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    mDecodedWidth = mDisplayWidth;
1289969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    mDecodedHeight = mDisplayHeight;
1299969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang}
1309969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
1319969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung ChangPreviewRenderer::~PreviewRenderer() {
1329969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    delete mConverter;
1339969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    mConverter = NULL;
1349969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang}
1359969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
1369969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
1379969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang//
1389969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang// Provides a buffer and associated stride
1399969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang// This buffer is allocated by the SurfaceFlinger
1409969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang//
1419969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang// For optimal display performances, you should :
1429969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang// 1) call getBufferYV12()
1439969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang// 2) fill the buffer with your data
1449969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang// 3) call renderYV12() to take these changes into account
1459969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang//
1469969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang// For each call to getBufferYV12(), you must also call renderYV12()
1479969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang// Expected format in the buffer is YV12 formats (similar to YUV420 planar fromat)
1489969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang// for more details on this YV12 cf hardware/libhardware/include/hardware/hardware.h
1499969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang//
1509969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Changvoid PreviewRenderer::getBufferYV12(uint8_t **data, size_t *stride) {
1519969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    int err = OK;
1529969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    LOGV("getBuffer START");
1539969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
1549969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    if ((err = mSurface->dequeueBuffer(mSurface.get(), &mBuf)) != 0) {
1559969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        LOGW("Surface::dequeueBuffer returned error %d", err);
1569969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        return;
1579969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    }
1589969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
1599969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    CHECK_EQ(0, mSurface->lockBuffer(mSurface.get(), mBuf));
1609969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
1619969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    GraphicBufferMapper &mapper = GraphicBufferMapper::get();
1629969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
1639969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    Rect bounds(mDecodedWidth, mDecodedHeight);
1649969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
1659969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    void *dst;
1669969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    CHECK_EQ(0, mapper.lock(
1679969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang                mBuf->handle, GRALLOC_USAGE_SW_WRITE_OFTEN, bounds, &dst));
1689969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    LOGV("Buffer locked");
1699969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
1709969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    *data   = (uint8_t*)dst;
1719969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    *stride = mBuf->stride;
1729969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
1739969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    LOGV("getBuffer END %p %d", dst, mBuf->stride);
1749969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang}
1759969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
1769969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
1779969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang//
1789969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang// Display the content of the buffer provided by last call to getBufferYV12()
1799969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang//
1809969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang// See getBufferYV12() for details.
1819969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang//
1829969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Changvoid PreviewRenderer::renderYV12() {
1839969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    LOGV("renderYV12() START");
1849969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    int err = OK;
1859969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
1869969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    GraphicBufferMapper &mapper = GraphicBufferMapper::get();
1879969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
1889969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    if (mBuf!= NULL) {
1899969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        CHECK_EQ(0, mapper.unlock(mBuf->handle));
1909969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
1919969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        if ((err = mSurface->queueBuffer(mSurface.get(), mBuf)) != 0) {
1929969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang            LOGW("Surface::queueBuffer returned error %d", err);
1939969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        }
1949969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    }
1959969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    mBuf = NULL;
1969969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    LOGV("renderYV12() END");
1979969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang}
1989969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
1999969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
2009969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
2019969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang//
2029969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang// Display the given data buffer
2039969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang// platformPrivate is not used (kept for backwrad compatibility)
2049969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang// Please rather use getbuffer() and the other render()functions (with no params)
2059969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang// for optimal display
2069969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang//
2079969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Changvoid PreviewRenderer::render(
2089969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        const void *data, size_t size, void *platformPrivate) {
2099969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    ANativeWindowBuffer *buf;
2109969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    int err;
2119969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
2129969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    if ((err = mSurface->dequeueBuffer(mSurface.get(), &buf)) != 0) {
2139969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        LOGW("Surface::dequeueBuffer returned error %d", err);
2149969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        return;
2159969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    }
2169969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
2179969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    CHECK_EQ(0, mSurface->lockBuffer(mSurface.get(), buf));
2189969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
2199969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    GraphicBufferMapper &mapper = GraphicBufferMapper::get();
2209969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
2219969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    Rect bounds(mDecodedWidth, mDecodedHeight);
2229969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
2239969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    void *dst;
2249969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    CHECK_EQ(0, mapper.lock(
2259969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang                buf->handle, GRALLOC_USAGE_SW_WRITE_OFTEN, bounds, &dst));
2269969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    LOGV("Buffer locked");
2279969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
2289969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    if (mConverter) {
2299969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        LOGV("Convert to RGB565");
2309969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        mConverter->convert(data,
2319969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang                mDecodedWidth, mDecodedHeight,
2329969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang                0,0,mDecodedWidth, mDecodedHeight,
2339969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang                dst, mDecodedWidth, mDecodedHeight,
2349969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang                0,0,mDecodedWidth, mDecodedHeight);
2359969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    } else if (mYUVMode == None) {
2369969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        // Input and output are both YUV420sp, but the alignment requirements
2379969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        // are different.
2389969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        LOGV("mYUVMode == None %d x %d", mDecodedWidth, mDecodedHeight);
2399969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        size_t srcYStride = mDecodedWidth;
2409969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        const uint8_t *srcY = (const uint8_t *)data;
2419969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        uint8_t *dstY = (uint8_t *)dst;
2429969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        LOGV("srcY =       %p   dstY =       %p", srcY, dstY);
2439969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        LOGV("srcYStride = %d   dstYstride = %d", srcYStride, buf->stride);
2449969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        for (size_t i = 0; i < mDecodedHeight; ++i) {
2459969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang            memcpy(dstY, srcY, mDecodedWidth);
2469969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang            srcY += srcYStride;
2479969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang            dstY += buf->stride;
2489969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        }
2499969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
2509969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        size_t srcUVStride = (mDecodedWidth + 1) / 2;
2519969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        size_t dstUVStride = ALIGN(mDecodedWidth / 2, 32);
2529969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        LOGV("srcUVStride = %d   dstUVStride = %d", srcUVStride, dstUVStride);
2539969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
2549969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        // Copy V
2559969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        // Source buffer is YUV, skip U
2569969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        const uint8_t *srcV = (const uint8_t *)data
2579969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang                + mDecodedHeight * mDecodedWidth + (mDecodedHeight * mDecodedWidth)/4;
2589969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        // Destination buffer is YVU
2599969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        uint8_t *dstUV = (uint8_t *)dst
2609969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang                + buf->stride*mDecodedHeight;
2619969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        LOGV("srcV =       %p   dstUV =       %p", srcV, dstUV);
2629969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        for (size_t i = 0; i < (mDecodedHeight+1)/2; ++i) {
2639969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang            memcpy(dstUV, srcV, mDecodedWidth/2);
2649969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang            srcV += srcUVStride;
2659969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang            dstUV += dstUVStride;
2669969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        }
2679969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
2689969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
2699969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        // Copy V
2709969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        // Source buffer is YUV, go back to end of Y
2719969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        const uint8_t *srcU = (const uint8_t *)data
2729969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang            + mDecodedHeight * mDecodedWidth ;
2739969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        // Destination buffer is YVU
2749969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        // Keep writing after V buffer has been filled, U follows immediately
2759969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        LOGV("srcU =       %p   dstUV =       %p", srcU, dstUV);
2769969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        for (size_t i = 0; i < (mDecodedHeight+1)/2; ++i) {
2779969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang            memcpy(dstUV, srcU, mDecodedWidth/2);
2789969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang            srcU += srcUVStride;
2799969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang            dstUV += dstUVStride;
2809969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        }
2819969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    } else {
2829969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        memcpy(dst, data, size);
2839969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    }
2849969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
2859969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    CHECK_EQ(0, mapper.unlock(buf->handle));
2869969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
2879969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    if ((err = mSurface->queueBuffer(mSurface.get(), buf)) != 0) {
2889969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang        LOGW("Surface::queueBuffer returned error %d", err);
2899969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    }
2909969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang    buf = NULL;
2919969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang}
2929969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang
2939969866cfe5b17c6e481b90d81b011a0cece78a0Chih-Chung Chang}  // namespace android
294