SoftwareRenderer.cpp revision 475da7ef08c05a482ced8d318832cf5aa1141aff
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
229dc4c66f36ca0158b470c78b0929cd9dd929a375Andreas Huber#include <cutils/properties.h> // for property_get
23f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber#include <media/stagefright/foundation/ADebug.h>
24475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu#include <media/stagefright/foundation/AMessage.h>
259eeafeb52fecf90882e9b44eeefcb7c3e16aa915Mathias Agopian#include <system/window.h>
265daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber#include <ui/GraphicBufferMapper.h>
278ba01021b573889802e67e029225a96f0dfa471aAndy McFadden#include <gui/IGraphicBufferProducer.h>
2820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
2920111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubernamespace android {
3020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
319dc4c66f36ca0158b470c78b0929cd9dd929a375Andreas Huberstatic bool runningInEmulator() {
329dc4c66f36ca0158b470c78b0929cd9dd929a375Andreas Huber    char prop[PROPERTY_VALUE_MAX];
339dc4c66f36ca0158b470c78b0929cd9dd929a375Andreas Huber    return (property_get("ro.kernel.qemu", prop, NULL) > 0);
349dc4c66f36ca0158b470c78b0929cd9dd929a375Andreas Huber}
359dc4c66f36ca0158b470c78b0929cd9dd929a375Andreas Huber
36475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wustatic int ALIGN(int x, int y) {
37475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    // y must be a power of 2.
38475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    return (x + y - 1) & ~(y - 1);
39475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu}
40475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu
41475da7ef08c05a482ced8d318832cf5aa1141affRonghua WuSoftwareRenderer::SoftwareRenderer(const sp<ANativeWindow> &nativeWindow)
42475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    : mColorFormat(OMX_COLOR_FormatUnused),
43475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu      mConverter(NULL),
445daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber      mYUVMode(None),
45475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu      mNativeWindow(nativeWindow),
46475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu      mWidth(0),
47475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu      mHeight(0),
48475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu      mCropLeft(0),
49475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu      mCropTop(0),
50475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu      mCropRight(0),
51475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu      mCropBottom(0),
52475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu      mCropWidth(0),
53475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu      mCropHeight(0) {
54475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu}
55475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu
56475da7ef08c05a482ced8d318832cf5aa1141affRonghua WuSoftwareRenderer::~SoftwareRenderer() {
57475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    delete mConverter;
58475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    mConverter = NULL;
59475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu}
60475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu
61475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wuvoid SoftwareRenderer::resetFormatIfChanged(const sp<AMessage> &format) {
62475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    CHECK(format != NULL);
63475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu
64475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    int32_t colorFormatNew;
65475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    CHECK(format->findInt32("color-format", &colorFormatNew));
66475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu
67475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    int32_t widthNew, heightNew;
68475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    CHECK(format->findInt32("width", &widthNew));
69475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    CHECK(format->findInt32("height", &heightNew));
70475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu
71475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    int32_t cropLeftNew, cropTopNew, cropRightNew, cropBottomNew;
72475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    if (!format->findRect(
73475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu            "crop", &cropLeftNew, &cropTopNew, &cropRightNew, &cropBottomNew)) {
74475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        cropLeftNew = cropTopNew = 0;
75475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        cropRightNew = widthNew - 1;
76475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        cropBottomNew = heightNew - 1;
77f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    }
78f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber
79475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    if (static_cast<int32_t>(mColorFormat) == colorFormatNew &&
80475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        mWidth == widthNew &&
81475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        mHeight == heightNew &&
82475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        mCropLeft == cropLeftNew &&
83475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        mCropTop == cropTopNew &&
84475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        mCropRight == cropRightNew &&
85475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        mCropBottom == cropBottomNew) {
86475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        // Nothing changed, no need to reset renderer.
87475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        return;
88475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    }
89475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu
90475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    mColorFormat = static_cast<OMX_COLOR_FORMATTYPE>(colorFormatNew);
91475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    mWidth = widthNew;
92475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    mHeight = heightNew;
93475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    mCropLeft = cropLeftNew;
94475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    mCropTop = cropTopNew;
95475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    mCropRight = cropRightNew;
96475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    mCropBottom = cropBottomNew;
97475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu
983571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber    mCropWidth = mCropRight - mCropLeft + 1;
993571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber    mCropHeight = mCropBottom - mCropTop + 1;
1003571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber
1015daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    int halFormat;
1025e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber    size_t bufWidth, bufHeight;
1035e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber
1045daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    switch (mColorFormat) {
1055e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        case OMX_COLOR_FormatYUV420Planar:
1063571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        case OMX_TI_COLOR_FormatYUV420PackedSemiPlanar:
1075e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        {
1089dc4c66f36ca0158b470c78b0929cd9dd929a375Andreas Huber            if (!runningInEmulator()) {
1099dc4c66f36ca0158b470c78b0929cd9dd929a375Andreas Huber                halFormat = HAL_PIXEL_FORMAT_YV12;
1109dc4c66f36ca0158b470c78b0929cd9dd929a375Andreas Huber                bufWidth = (mCropWidth + 1) & ~1;
1119dc4c66f36ca0158b470c78b0929cd9dd929a375Andreas Huber                bufHeight = (mCropHeight + 1) & ~1;
1129dc4c66f36ca0158b470c78b0929cd9dd929a375Andreas Huber                break;
1139dc4c66f36ca0158b470c78b0929cd9dd929a375Andreas Huber            }
1149dc4c66f36ca0158b470c78b0929cd9dd929a375Andreas Huber
1159dc4c66f36ca0158b470c78b0929cd9dd929a375Andreas Huber            // fall through.
1165e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        }
1175e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber
1185daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber        default:
1195daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber            halFormat = HAL_PIXEL_FORMAT_RGB_565;
1203571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            bufWidth = mCropWidth;
1213571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            bufHeight = mCropHeight;
1225daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber
1235daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber            mConverter = new ColorConverter(
1245daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber                    mColorFormat, OMX_COLOR_Format16bitRGB565);
1255daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber            CHECK(mConverter->isValid());
1265daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber            break;
12789e7fff6a5d7410815f42b4a55958a59d4463180Andreas Huber    }
12889e7fff6a5d7410815f42b4a55958a59d4463180Andreas Huber
1291173118eace0e9e347cb007f0da817cee87579edGlenn Kasten    CHECK(mNativeWindow != NULL);
1303571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber    CHECK(mCropWidth > 0);
1313571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber    CHECK(mCropHeight > 0);
1325daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    CHECK(mConverter == NULL || mConverter->isValid());
1335daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber
1345daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    CHECK_EQ(0,
1355daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber            native_window_set_usage(
1361173118eace0e9e347cb007f0da817cee87579edGlenn Kasten            mNativeWindow.get(),
1375daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber            GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_OFTEN
138103487c0cb5c06f47225484486a98bc84745a059Andreas Huber            | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP));
13920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1409bc7af17974f448291a44912566ec7472a0d798bMathias Agopian    CHECK_EQ(0,
1419bc7af17974f448291a44912566ec7472a0d798bMathias Agopian            native_window_set_scaling_mode(
1429bc7af17974f448291a44912566ec7472a0d798bMathias Agopian            mNativeWindow.get(),
1439bc7af17974f448291a44912566ec7472a0d798bMathias Agopian            NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW));
1449bc7af17974f448291a44912566ec7472a0d798bMathias Agopian
1455daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    // Width must be multiple of 32???
146475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    CHECK_EQ(0, native_window_set_buffers_dimensions(
1471173118eace0e9e347cb007f0da817cee87579edGlenn Kasten                mNativeWindow.get(),
1485e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber                bufWidth,
149475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                bufHeight));
150475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    CHECK_EQ(0, native_window_set_buffers_format(
151475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                mNativeWindow.get(),
1525daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber                halFormat));
153ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
15425a147aaad0ce30da8db763054d963ceaedb4065Lajos Molnar    // NOTE: native window uses extended right-bottom coordinate
15525a147aaad0ce30da8db763054d963ceaedb4065Lajos Molnar    android_native_rect_t crop;
15625a147aaad0ce30da8db763054d963ceaedb4065Lajos Molnar    crop.left = mCropLeft;
15725a147aaad0ce30da8db763054d963ceaedb4065Lajos Molnar    crop.top = mCropTop;
15825a147aaad0ce30da8db763054d963ceaedb4065Lajos Molnar    crop.right = mCropRight + 1;
15925a147aaad0ce30da8db763054d963ceaedb4065Lajos Molnar    crop.bottom = mCropBottom + 1;
16025a147aaad0ce30da8db763054d963ceaedb4065Lajos Molnar    ALOGV("setting crop: [%d, %d, %d, %d] for size [%zu, %zu]",
16125a147aaad0ce30da8db763054d963ceaedb4065Lajos Molnar          crop.left, crop.top, crop.right, crop.bottom, bufWidth, bufHeight);
16225a147aaad0ce30da8db763054d963ceaedb4065Lajos Molnar
16325a147aaad0ce30da8db763054d963ceaedb4065Lajos Molnar    CHECK_EQ(0, native_window_set_crop(mNativeWindow.get(), &crop));
16425a147aaad0ce30da8db763054d963ceaedb4065Lajos Molnar
165475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    int32_t rotationDegrees;
166475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    if (!format->findInt32("rotation-degrees", &rotationDegrees)) {
167475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        rotationDegrees = 0;
168475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    }
169ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    uint32_t transform;
170ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    switch (rotationDegrees) {
171ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        case 0: transform = 0; break;
172ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        case 90: transform = HAL_TRANSFORM_ROT_90; break;
173ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        case 180: transform = HAL_TRANSFORM_ROT_180; break;
174ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        case 270: transform = HAL_TRANSFORM_ROT_270; break;
175ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        default: transform = 0; break;
176ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    }
177ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
178475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    CHECK_EQ(0, native_window_set_buffers_transform(
179475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                mNativeWindow.get(), transform));
1805e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber}
1815e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber
18220111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubervoid SoftwareRenderer::render(
183475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        const void *data, size_t /*size*/, int64_t timestampNs,
184475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        void* /*platformPrivate*/, const sp<AMessage>& format) {
185475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    resetFormatIfChanged(format);
186475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu
1878ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev    ANativeWindowBuffer *buf;
1885de4999e6dd8a3f2740d20e30e8a3fccdcb76362Andreas Huber    int err;
1891e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    if ((err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(),
1901e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis            &buf)) != 0) {
1915ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("Surface::dequeueBuffer returned error %d", err);
1925de4999e6dd8a3f2740d20e30e8a3fccdcb76362Andreas Huber        return;
1935de4999e6dd8a3f2740d20e30e8a3fccdcb76362Andreas Huber    }
1945de4999e6dd8a3f2740d20e30e8a3fccdcb76362Andreas Huber
1955daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    GraphicBufferMapper &mapper = GraphicBufferMapper::get();
1965daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber
1973571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber    Rect bounds(mCropWidth, mCropHeight);
1985daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber
1995daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    void *dst;
2005daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    CHECK_EQ(0, mapper.lock(
2015daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber                buf->handle, GRALLOC_USAGE_SW_WRITE_OFTEN, bounds, &dst));
2025daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber
2035daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    if (mConverter) {
2045daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber        mConverter->convert(
205f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber                data,
206f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber                mWidth, mHeight,
2073571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber                mCropLeft, mCropTop, mCropRight, mCropBottom,
208f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber                dst,
209f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber                buf->stride, buf->height,
2103571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber                0, 0, mCropWidth - 1, mCropHeight - 1);
2113571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber    } else if (mColorFormat == OMX_COLOR_FormatYUV420Planar) {
2125e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        const uint8_t *src_y = (const uint8_t *)data;
2135e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        const uint8_t *src_u = (const uint8_t *)data + mWidth * mHeight;
2145e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        const uint8_t *src_v = src_u + (mWidth / 2 * mHeight / 2);
2155e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber
2165e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        uint8_t *dst_y = (uint8_t *)dst;
2175e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        size_t dst_y_size = buf->stride * buf->height;
2185e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        size_t dst_c_stride = ALIGN(buf->stride / 2, 16);
2195e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        size_t dst_c_size = dst_c_stride * buf->height / 2;
2205e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        uint8_t *dst_v = dst_y + dst_y_size;
2215e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        uint8_t *dst_u = dst_v + dst_c_size;
2225e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber
2233571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        for (int y = 0; y < mCropHeight; ++y) {
2243571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            memcpy(dst_y, src_y, mCropWidth);
2255e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber
2265e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber            src_y += mWidth;
2275e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber            dst_y += buf->stride;
2285e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        }
2295e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber
2303571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        for (int y = 0; y < (mCropHeight + 1) / 2; ++y) {
2313571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            memcpy(dst_u, src_u, (mCropWidth + 1) / 2);
2323571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            memcpy(dst_v, src_v, (mCropWidth + 1) / 2);
2335e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber
2345e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber            src_u += mWidth / 2;
2355e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber            src_v += mWidth / 2;
2365e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber            dst_u += dst_c_stride;
2375e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber            dst_v += dst_c_stride;
2385e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        }
2393571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber    } else {
2403571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        CHECK_EQ(mColorFormat, OMX_TI_COLOR_FormatYUV420PackedSemiPlanar);
2413571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber
2423571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        const uint8_t *src_y =
2433571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            (const uint8_t *)data;
2443571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber
2453571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        const uint8_t *src_uv =
2463571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            (const uint8_t *)data + mWidth * (mHeight - mCropTop / 2);
2473571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber
2483571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        uint8_t *dst_y = (uint8_t *)dst;
2493571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber
2503571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        size_t dst_y_size = buf->stride * buf->height;
2513571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        size_t dst_c_stride = ALIGN(buf->stride / 2, 16);
2523571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        size_t dst_c_size = dst_c_stride * buf->height / 2;
2533571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        uint8_t *dst_v = dst_y + dst_y_size;
2543571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        uint8_t *dst_u = dst_v + dst_c_size;
2553571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber
2563571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        for (int y = 0; y < mCropHeight; ++y) {
2573571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            memcpy(dst_y, src_y, mCropWidth);
2583571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber
2593571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            src_y += mWidth;
2603571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            dst_y += buf->stride;
2613571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        }
2623571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber
2633571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        for (int y = 0; y < (mCropHeight + 1) / 2; ++y) {
2643571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            size_t tmp = (mCropWidth + 1) / 2;
2653571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            for (size_t x = 0; x < tmp; ++x) {
2663571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber                dst_u[x] = src_uv[2 * x];
2673571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber                dst_v[x] = src_uv[2 * x + 1];
2683571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            }
2693571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber
2703571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            src_uv += mWidth;
2713571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            dst_u += dst_c_stride;
2723571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            dst_v += dst_c_stride;
2733571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        }
2745daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    }
2754265a834394bfe14a008a2ac58fbbe388566ad07Andreas Huber
2765daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    CHECK_EQ(0, mapper.unlock(buf->handle));
2774265a834394bfe14a008a2ac58fbbe388566ad07Andreas Huber
278908ea6603c64e29e40277a74c9fb0e776c097830Lajos Molnar    if ((err = native_window_set_buffers_timestamp(mNativeWindow.get(),
279908ea6603c64e29e40277a74c9fb0e776c097830Lajos Molnar            timestampNs)) != 0) {
280908ea6603c64e29e40277a74c9fb0e776c097830Lajos Molnar        ALOGW("Surface::set_buffers_timestamp returned error %d", err);
281908ea6603c64e29e40277a74c9fb0e776c097830Lajos Molnar    }
282908ea6603c64e29e40277a74c9fb0e776c097830Lajos Molnar
2831e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    if ((err = mNativeWindow->queueBuffer(mNativeWindow.get(), buf,
2841e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis            -1)) != 0) {
2855ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("Surface::queueBuffer returned error %d", err);
2865de4999e6dd8a3f2740d20e30e8a3fccdcb76362Andreas Huber    }
2875daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    buf = NULL;
2884265a834394bfe14a008a2ac58fbbe388566ad07Andreas Huber}
2894265a834394bfe14a008a2ac58fbbe388566ad07Andreas Huber
29020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}  // namespace android
291