SoftwareRenderer.cpp revision 3571d50a2582bc9c63f09cd81b4f490ea3522bd9
120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber/*
220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Copyright (C) 2009 The Android Open Source Project
320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *
420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * you may not use this file except in compliance with the License.
620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * You may obtain a copy of the License at
720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *
820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *
1020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Unless required by applicable law or agreed to in writing, software
1120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
1220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * See the License for the specific language governing permissions and
1420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * limitations under the License.
1520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber */
1620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#define LOG_TAG "SoftwareRenderer"
1820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <utils/Log.h>
1920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
2089e69da4d86348409994c9dafbbb2634ccd7c196Andreas Huber#include "../include/SoftwareRenderer.h"
2189e69da4d86348409994c9dafbbb2634ccd7c196Andreas Huber
2220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <binder/MemoryHeapBase.h>
2389e7fff6a5d7410815f42b4a55958a59d4463180Andreas Huber#include <binder/MemoryHeapPmem.h>
24f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber#include <media/stagefright/foundation/ADebug.h>
25f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber#include <media/stagefright/MetaData.h>
265daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber#include <surfaceflinger/Surface.h>
275daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber#include <ui/android_native_buffer.h>
285daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber#include <ui/GraphicBufferMapper.h>
291173118eace0e9e347cb007f0da817cee87579edGlenn Kasten#include <gui/ISurfaceTexture.h>
3020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
3120111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubernamespace android {
3220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
3320111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberSoftwareRenderer::SoftwareRenderer(
341173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        const sp<ANativeWindow> &nativeWindow, const sp<MetaData> &meta)
35f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    : mConverter(NULL),
365daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber      mYUVMode(None),
371173118eace0e9e347cb007f0da817cee87579edGlenn Kasten      mNativeWindow(nativeWindow) {
38f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    int32_t tmp;
39f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    CHECK(meta->findInt32(kKeyColorFormat, &tmp));
40f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    mColorFormat = (OMX_COLOR_FORMATTYPE)tmp;
41f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber
42f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    CHECK(meta->findInt32(kKeyWidth, &mWidth));
43f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    CHECK(meta->findInt32(kKeyHeight, &mHeight));
44f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber
45f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    if (!meta->findRect(
46f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber                kKeyCropRect,
47f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber                &mCropLeft, &mCropTop, &mCropRight, &mCropBottom)) {
48f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber        mCropLeft = mCropTop = 0;
49f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber        mCropRight = mWidth - 1;
50f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber        mCropBottom = mHeight - 1;
51f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    }
52f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber
533571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber    mCropWidth = mCropRight - mCropLeft + 1;
543571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber    mCropHeight = mCropBottom - mCropTop + 1;
553571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber
56f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    int32_t rotationDegrees;
57f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    if (!meta->findInt32(kKeyRotation, &rotationDegrees)) {
58f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber        rotationDegrees = 0;
59f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    }
60a240812f10335fe4c8677da824293b7e04aad7e9Andreas Huber
615daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    int halFormat;
625e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber    size_t bufWidth, bufHeight;
635e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber
645daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    switch (mColorFormat) {
655e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        case OMX_COLOR_FormatYUV420Planar:
663571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        case OMX_TI_COLOR_FormatYUV420PackedSemiPlanar:
675e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        {
685e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber            halFormat = HAL_PIXEL_FORMAT_YV12;
693571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            bufWidth = (mCropWidth + 1) & ~1;
703571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            bufHeight = (mCropHeight + 1) & ~1;
715e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber            break;
725e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        }
735e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber
745daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber        default:
755daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber            halFormat = HAL_PIXEL_FORMAT_RGB_565;
763571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            bufWidth = mCropWidth;
773571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            bufHeight = mCropHeight;
785daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber
795daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber            mConverter = new ColorConverter(
805daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber                    mColorFormat, OMX_COLOR_Format16bitRGB565);
815daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber            CHECK(mConverter->isValid());
825daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber            break;
8389e7fff6a5d7410815f42b4a55958a59d4463180Andreas Huber    }
8489e7fff6a5d7410815f42b4a55958a59d4463180Andreas Huber
851173118eace0e9e347cb007f0da817cee87579edGlenn Kasten    CHECK(mNativeWindow != NULL);
863571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber    CHECK(mCropWidth > 0);
873571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber    CHECK(mCropHeight > 0);
885daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    CHECK(mConverter == NULL || mConverter->isValid());
895daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber
905daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    CHECK_EQ(0,
915daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber            native_window_set_usage(
921173118eace0e9e347cb007f0da817cee87579edGlenn Kasten            mNativeWindow.get(),
935daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber            GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_OFTEN
94103487c0cb5c06f47225484486a98bc84745a059Andreas Huber            | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP));
9520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
965daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    // Width must be multiple of 32???
975daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    CHECK_EQ(0, native_window_set_buffers_geometry(
981173118eace0e9e347cb007f0da817cee87579edGlenn Kasten                mNativeWindow.get(),
995e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber                bufWidth,
1005e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber                bufHeight,
1015daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber                halFormat));
102ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
103ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    uint32_t transform;
104ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    switch (rotationDegrees) {
105ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        case 0: transform = 0; break;
106ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        case 90: transform = HAL_TRANSFORM_ROT_90; break;
107ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        case 180: transform = HAL_TRANSFORM_ROT_180; break;
108ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        case 270: transform = HAL_TRANSFORM_ROT_270; break;
109ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        default: transform = 0; break;
110ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    }
111ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
112ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    if (transform) {
113ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        CHECK_EQ(0, native_window_set_buffers_transform(
1141173118eace0e9e347cb007f0da817cee87579edGlenn Kasten                    mNativeWindow.get(), transform));
115ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    }
11620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
11720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
11820111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberSoftwareRenderer::~SoftwareRenderer() {
1195daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    delete mConverter;
1205daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    mConverter = NULL;
1215daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber}
1225daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber
1235e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huberstatic int ALIGN(int x, int y) {
1245e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber    // y must be a power of 2.
1255e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber    return (x + y - 1) & ~(y - 1);
1265e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber}
1275e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber
12820111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubervoid SoftwareRenderer::render(
12920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        const void *data, size_t size, void *platformPrivate) {
1308ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev    ANativeWindowBuffer *buf;
1315de4999e6dd8a3f2740d20e30e8a3fccdcb76362Andreas Huber    int err;
1321173118eace0e9e347cb007f0da817cee87579edGlenn Kasten    if ((err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf)) != 0) {
1335de4999e6dd8a3f2740d20e30e8a3fccdcb76362Andreas Huber        LOGW("Surface::dequeueBuffer returned error %d", err);
1345de4999e6dd8a3f2740d20e30e8a3fccdcb76362Andreas Huber        return;
1355de4999e6dd8a3f2740d20e30e8a3fccdcb76362Andreas Huber    }
1365de4999e6dd8a3f2740d20e30e8a3fccdcb76362Andreas Huber
1371173118eace0e9e347cb007f0da817cee87579edGlenn Kasten    CHECK_EQ(0, mNativeWindow->lockBuffer(mNativeWindow.get(), buf));
1385daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber
1395daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    GraphicBufferMapper &mapper = GraphicBufferMapper::get();
1405daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber
1413571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber    Rect bounds(mCropWidth, mCropHeight);
1425daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber
1435daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    void *dst;
1445daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    CHECK_EQ(0, mapper.lock(
1455daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber                buf->handle, GRALLOC_USAGE_SW_WRITE_OFTEN, bounds, &dst));
1465daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber
1475daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    if (mConverter) {
1485daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber        mConverter->convert(
149f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber                data,
150f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber                mWidth, mHeight,
1513571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber                mCropLeft, mCropTop, mCropRight, mCropBottom,
152f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber                dst,
153f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber                buf->stride, buf->height,
1543571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber                0, 0, mCropWidth - 1, mCropHeight - 1);
1553571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber    } else if (mColorFormat == OMX_COLOR_FormatYUV420Planar) {
1565e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        const uint8_t *src_y = (const uint8_t *)data;
1575e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        const uint8_t *src_u = (const uint8_t *)data + mWidth * mHeight;
1585e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        const uint8_t *src_v = src_u + (mWidth / 2 * mHeight / 2);
1595e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber
1605e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        uint8_t *dst_y = (uint8_t *)dst;
1615e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        size_t dst_y_size = buf->stride * buf->height;
1625e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        size_t dst_c_stride = ALIGN(buf->stride / 2, 16);
1635e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        size_t dst_c_size = dst_c_stride * buf->height / 2;
1645e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        uint8_t *dst_v = dst_y + dst_y_size;
1655e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        uint8_t *dst_u = dst_v + dst_c_size;
1665e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber
1673571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        for (int y = 0; y < mCropHeight; ++y) {
1683571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            memcpy(dst_y, src_y, mCropWidth);
1695e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber
1705e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber            src_y += mWidth;
1715e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber            dst_y += buf->stride;
1725e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        }
1735e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber
1743571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        for (int y = 0; y < (mCropHeight + 1) / 2; ++y) {
1753571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            memcpy(dst_u, src_u, (mCropWidth + 1) / 2);
1763571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            memcpy(dst_v, src_v, (mCropWidth + 1) / 2);
1775e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber
1785e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber            src_u += mWidth / 2;
1795e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber            src_v += mWidth / 2;
1805e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber            dst_u += dst_c_stride;
1815e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber            dst_v += dst_c_stride;
1825e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        }
1833571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber    } else {
1843571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        CHECK_EQ(mColorFormat, OMX_TI_COLOR_FormatYUV420PackedSemiPlanar);
1853571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber
1863571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        const uint8_t *src_y =
1873571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            (const uint8_t *)data;
1883571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber
1893571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        const uint8_t *src_uv =
1903571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            (const uint8_t *)data + mWidth * (mHeight - mCropTop / 2);
1913571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber
1923571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        uint8_t *dst_y = (uint8_t *)dst;
1933571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber
1943571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        size_t dst_y_size = buf->stride * buf->height;
1953571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        size_t dst_c_stride = ALIGN(buf->stride / 2, 16);
1963571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        size_t dst_c_size = dst_c_stride * buf->height / 2;
1973571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        uint8_t *dst_v = dst_y + dst_y_size;
1983571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        uint8_t *dst_u = dst_v + dst_c_size;
1993571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber
2003571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        for (int y = 0; y < mCropHeight; ++y) {
2013571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            memcpy(dst_y, src_y, mCropWidth);
2023571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber
2033571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            src_y += mWidth;
2043571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            dst_y += buf->stride;
2053571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        }
2063571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber
2073571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        for (int y = 0; y < (mCropHeight + 1) / 2; ++y) {
2083571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            size_t tmp = (mCropWidth + 1) / 2;
2093571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            for (size_t x = 0; x < tmp; ++x) {
2103571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber                dst_u[x] = src_uv[2 * x];
2113571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber                dst_v[x] = src_uv[2 * x + 1];
2123571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            }
2133571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber
2143571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            src_uv += mWidth;
2153571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            dst_u += dst_c_stride;
2163571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            dst_v += dst_c_stride;
2173571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        }
2185daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    }
2194265a834394bfe14a008a2ac58fbbe388566ad07Andreas Huber
2205daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    CHECK_EQ(0, mapper.unlock(buf->handle));
2214265a834394bfe14a008a2ac58fbbe388566ad07Andreas Huber
2221173118eace0e9e347cb007f0da817cee87579edGlenn Kasten    if ((err = mNativeWindow->queueBuffer(mNativeWindow.get(), buf)) != 0) {
2235de4999e6dd8a3f2740d20e30e8a3fccdcb76362Andreas Huber        LOGW("Surface::queueBuffer returned error %d", err);
2245de4999e6dd8a3f2740d20e30e8a3fccdcb76362Andreas Huber    }
2255daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    buf = NULL;
2264265a834394bfe14a008a2ac58fbbe388566ad07Andreas Huber}
2274265a834394bfe14a008a2ac58fbbe388566ad07Andreas Huber
22820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}  // namespace android
229