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