SoftwareRenderer.cpp revision 9bc7af17974f448291a44912566ec7472a0d798b
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
969bc7af17974f448291a44912566ec7472a0d798bMathias Agopian    CHECK_EQ(0,
979bc7af17974f448291a44912566ec7472a0d798bMathias Agopian            native_window_set_scaling_mode(
989bc7af17974f448291a44912566ec7472a0d798bMathias Agopian            mNativeWindow.get(),
999bc7af17974f448291a44912566ec7472a0d798bMathias Agopian            NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW));
1009bc7af17974f448291a44912566ec7472a0d798bMathias Agopian
1015daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    // Width must be multiple of 32???
1025daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    CHECK_EQ(0, native_window_set_buffers_geometry(
1031173118eace0e9e347cb007f0da817cee87579edGlenn Kasten                mNativeWindow.get(),
1045e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber                bufWidth,
1055e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber                bufHeight,
1065daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber                halFormat));
107ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
108ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    uint32_t transform;
109ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    switch (rotationDegrees) {
110ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        case 0: transform = 0; break;
111ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        case 90: transform = HAL_TRANSFORM_ROT_90; break;
112ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        case 180: transform = HAL_TRANSFORM_ROT_180; break;
113ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        case 270: transform = HAL_TRANSFORM_ROT_270; break;
114ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        default: transform = 0; break;
115ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    }
116ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
117ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    if (transform) {
118ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        CHECK_EQ(0, native_window_set_buffers_transform(
1191173118eace0e9e347cb007f0da817cee87579edGlenn Kasten                    mNativeWindow.get(), transform));
120ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    }
12120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
12220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
12320111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberSoftwareRenderer::~SoftwareRenderer() {
1245daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    delete mConverter;
1255daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    mConverter = NULL;
1265daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber}
1275daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber
1285e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huberstatic int ALIGN(int x, int y) {
1295e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber    // y must be a power of 2.
1305e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber    return (x + y - 1) & ~(y - 1);
1315e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber}
1325e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber
13320111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubervoid SoftwareRenderer::render(
13420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        const void *data, size_t size, void *platformPrivate) {
1358ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev    ANativeWindowBuffer *buf;
1365de4999e6dd8a3f2740d20e30e8a3fccdcb76362Andreas Huber    int err;
1371173118eace0e9e347cb007f0da817cee87579edGlenn Kasten    if ((err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf)) != 0) {
1385de4999e6dd8a3f2740d20e30e8a3fccdcb76362Andreas Huber        LOGW("Surface::dequeueBuffer returned error %d", err);
1395de4999e6dd8a3f2740d20e30e8a3fccdcb76362Andreas Huber        return;
1405de4999e6dd8a3f2740d20e30e8a3fccdcb76362Andreas Huber    }
1415de4999e6dd8a3f2740d20e30e8a3fccdcb76362Andreas Huber
1421173118eace0e9e347cb007f0da817cee87579edGlenn Kasten    CHECK_EQ(0, mNativeWindow->lockBuffer(mNativeWindow.get(), buf));
1435daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber
1445daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    GraphicBufferMapper &mapper = GraphicBufferMapper::get();
1455daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber
1463571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber    Rect bounds(mCropWidth, mCropHeight);
1475daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber
1485daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    void *dst;
1495daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    CHECK_EQ(0, mapper.lock(
1505daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber                buf->handle, GRALLOC_USAGE_SW_WRITE_OFTEN, bounds, &dst));
1515daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber
1525daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    if (mConverter) {
1535daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber        mConverter->convert(
154f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber                data,
155f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber                mWidth, mHeight,
1563571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber                mCropLeft, mCropTop, mCropRight, mCropBottom,
157f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber                dst,
158f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber                buf->stride, buf->height,
1593571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber                0, 0, mCropWidth - 1, mCropHeight - 1);
1603571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber    } else if (mColorFormat == OMX_COLOR_FormatYUV420Planar) {
1615e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        const uint8_t *src_y = (const uint8_t *)data;
1625e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        const uint8_t *src_u = (const uint8_t *)data + mWidth * mHeight;
1635e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        const uint8_t *src_v = src_u + (mWidth / 2 * mHeight / 2);
1645e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber
1655e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        uint8_t *dst_y = (uint8_t *)dst;
1665e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        size_t dst_y_size = buf->stride * buf->height;
1675e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        size_t dst_c_stride = ALIGN(buf->stride / 2, 16);
1685e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        size_t dst_c_size = dst_c_stride * buf->height / 2;
1695e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        uint8_t *dst_v = dst_y + dst_y_size;
1705e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        uint8_t *dst_u = dst_v + dst_c_size;
1715e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber
1723571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        for (int y = 0; y < mCropHeight; ++y) {
1733571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            memcpy(dst_y, src_y, mCropWidth);
1745e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber
1755e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber            src_y += mWidth;
1765e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber            dst_y += buf->stride;
1775e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        }
1785e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber
1793571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        for (int y = 0; y < (mCropHeight + 1) / 2; ++y) {
1803571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            memcpy(dst_u, src_u, (mCropWidth + 1) / 2);
1813571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            memcpy(dst_v, src_v, (mCropWidth + 1) / 2);
1825e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber
1835e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber            src_u += mWidth / 2;
1845e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber            src_v += mWidth / 2;
1855e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber            dst_u += dst_c_stride;
1865e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber            dst_v += dst_c_stride;
1875e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        }
1883571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber    } else {
1893571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        CHECK_EQ(mColorFormat, OMX_TI_COLOR_FormatYUV420PackedSemiPlanar);
1903571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber
1913571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        const uint8_t *src_y =
1923571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            (const uint8_t *)data;
1933571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber
1943571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        const uint8_t *src_uv =
1953571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            (const uint8_t *)data + mWidth * (mHeight - mCropTop / 2);
1963571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber
1973571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        uint8_t *dst_y = (uint8_t *)dst;
1983571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber
1993571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        size_t dst_y_size = buf->stride * buf->height;
2003571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        size_t dst_c_stride = ALIGN(buf->stride / 2, 16);
2013571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        size_t dst_c_size = dst_c_stride * buf->height / 2;
2023571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        uint8_t *dst_v = dst_y + dst_y_size;
2033571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        uint8_t *dst_u = dst_v + dst_c_size;
2043571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber
2053571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        for (int y = 0; y < mCropHeight; ++y) {
2063571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            memcpy(dst_y, src_y, mCropWidth);
2073571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber
2083571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            src_y += mWidth;
2093571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            dst_y += buf->stride;
2103571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        }
2113571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber
2123571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        for (int y = 0; y < (mCropHeight + 1) / 2; ++y) {
2133571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            size_t tmp = (mCropWidth + 1) / 2;
2143571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            for (size_t x = 0; x < tmp; ++x) {
2153571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber                dst_u[x] = src_uv[2 * x];
2163571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber                dst_v[x] = src_uv[2 * x + 1];
2173571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            }
2183571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber
2193571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            src_uv += mWidth;
2203571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            dst_u += dst_c_stride;
2213571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            dst_v += dst_c_stride;
2223571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        }
2235daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    }
2244265a834394bfe14a008a2ac58fbbe388566ad07Andreas Huber
2255daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    CHECK_EQ(0, mapper.unlock(buf->handle));
2264265a834394bfe14a008a2ac58fbbe388566ad07Andreas Huber
2271173118eace0e9e347cb007f0da817cee87579edGlenn Kasten    if ((err = mNativeWindow->queueBuffer(mNativeWindow.get(), buf)) != 0) {
2285de4999e6dd8a3f2740d20e30e8a3fccdcb76362Andreas Huber        LOGW("Surface::queueBuffer returned error %d", err);
2295de4999e6dd8a3f2740d20e30e8a3fccdcb76362Andreas Huber    }
2305daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    buf = NULL;
2314265a834394bfe14a008a2ac58fbbe388566ad07Andreas Huber}
2324265a834394bfe14a008a2ac58fbbe388566ad07Andreas Huber
23320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}  // namespace android
234