SoftwareRenderer.cpp revision 25a147aaad0ce30da8db763054d963ceaedb4065
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>
24f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber#include <media/stagefright/MetaData.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
3620111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberSoftwareRenderer::SoftwareRenderer(
371173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        const sp<ANativeWindow> &nativeWindow, const sp<MetaData> &meta)
38f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    : mConverter(NULL),
395daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber      mYUVMode(None),
401173118eace0e9e347cb007f0da817cee87579edGlenn Kasten      mNativeWindow(nativeWindow) {
41f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    int32_t tmp;
42f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    CHECK(meta->findInt32(kKeyColorFormat, &tmp));
43f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    mColorFormat = (OMX_COLOR_FORMATTYPE)tmp;
44f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber
45f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    CHECK(meta->findInt32(kKeyWidth, &mWidth));
46f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    CHECK(meta->findInt32(kKeyHeight, &mHeight));
47f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber
48f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    if (!meta->findRect(
49f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber                kKeyCropRect,
50f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber                &mCropLeft, &mCropTop, &mCropRight, &mCropBottom)) {
51f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber        mCropLeft = mCropTop = 0;
52f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber        mCropRight = mWidth - 1;
53f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber        mCropBottom = mHeight - 1;
54f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    }
55f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber
563571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber    mCropWidth = mCropRight - mCropLeft + 1;
573571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber    mCropHeight = mCropBottom - mCropTop + 1;
583571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber
59f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    int32_t rotationDegrees;
60f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    if (!meta->findInt32(kKeyRotation, &rotationDegrees)) {
61f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber        rotationDegrees = 0;
62f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    }
63a240812f10335fe4c8677da824293b7e04aad7e9Andreas Huber
645daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    int halFormat;
655e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber    size_t bufWidth, bufHeight;
665e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber
675daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    switch (mColorFormat) {
685e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        case OMX_COLOR_FormatYUV420Planar:
693571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        case OMX_TI_COLOR_FormatYUV420PackedSemiPlanar:
705e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        {
719dc4c66f36ca0158b470c78b0929cd9dd929a375Andreas Huber            if (!runningInEmulator()) {
729dc4c66f36ca0158b470c78b0929cd9dd929a375Andreas Huber                halFormat = HAL_PIXEL_FORMAT_YV12;
739dc4c66f36ca0158b470c78b0929cd9dd929a375Andreas Huber                bufWidth = (mCropWidth + 1) & ~1;
749dc4c66f36ca0158b470c78b0929cd9dd929a375Andreas Huber                bufHeight = (mCropHeight + 1) & ~1;
759dc4c66f36ca0158b470c78b0929cd9dd929a375Andreas Huber                break;
769dc4c66f36ca0158b470c78b0929cd9dd929a375Andreas Huber            }
779dc4c66f36ca0158b470c78b0929cd9dd929a375Andreas Huber
789dc4c66f36ca0158b470c78b0929cd9dd929a375Andreas Huber            // fall through.
795e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        }
805e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber
815daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber        default:
825daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber            halFormat = HAL_PIXEL_FORMAT_RGB_565;
833571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            bufWidth = mCropWidth;
843571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            bufHeight = mCropHeight;
855daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber
865daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber            mConverter = new ColorConverter(
875daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber                    mColorFormat, OMX_COLOR_Format16bitRGB565);
885daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber            CHECK(mConverter->isValid());
895daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber            break;
9089e7fff6a5d7410815f42b4a55958a59d4463180Andreas Huber    }
9189e7fff6a5d7410815f42b4a55958a59d4463180Andreas Huber
921173118eace0e9e347cb007f0da817cee87579edGlenn Kasten    CHECK(mNativeWindow != NULL);
933571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber    CHECK(mCropWidth > 0);
943571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber    CHECK(mCropHeight > 0);
955daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    CHECK(mConverter == NULL || mConverter->isValid());
965daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber
975daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    CHECK_EQ(0,
985daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber            native_window_set_usage(
991173118eace0e9e347cb007f0da817cee87579edGlenn Kasten            mNativeWindow.get(),
1005daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber            GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_OFTEN
101103487c0cb5c06f47225484486a98bc84745a059Andreas Huber            | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP));
10220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1039bc7af17974f448291a44912566ec7472a0d798bMathias Agopian    CHECK_EQ(0,
1049bc7af17974f448291a44912566ec7472a0d798bMathias Agopian            native_window_set_scaling_mode(
1059bc7af17974f448291a44912566ec7472a0d798bMathias Agopian            mNativeWindow.get(),
1069bc7af17974f448291a44912566ec7472a0d798bMathias Agopian            NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW));
1079bc7af17974f448291a44912566ec7472a0d798bMathias Agopian
1085daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    // Width must be multiple of 32???
1095daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    CHECK_EQ(0, native_window_set_buffers_geometry(
1101173118eace0e9e347cb007f0da817cee87579edGlenn Kasten                mNativeWindow.get(),
1115e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber                bufWidth,
1125e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber                bufHeight,
1135daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber                halFormat));
114ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
11525a147aaad0ce30da8db763054d963ceaedb4065Lajos Molnar    // NOTE: native window uses extended right-bottom coordinate
11625a147aaad0ce30da8db763054d963ceaedb4065Lajos Molnar    android_native_rect_t crop;
11725a147aaad0ce30da8db763054d963ceaedb4065Lajos Molnar    crop.left = mCropLeft;
11825a147aaad0ce30da8db763054d963ceaedb4065Lajos Molnar    crop.top = mCropTop;
11925a147aaad0ce30da8db763054d963ceaedb4065Lajos Molnar    crop.right = mCropRight + 1;
12025a147aaad0ce30da8db763054d963ceaedb4065Lajos Molnar    crop.bottom = mCropBottom + 1;
12125a147aaad0ce30da8db763054d963ceaedb4065Lajos Molnar    ALOGV("setting crop: [%d, %d, %d, %d] for size [%zu, %zu]",
12225a147aaad0ce30da8db763054d963ceaedb4065Lajos Molnar          crop.left, crop.top, crop.right, crop.bottom, bufWidth, bufHeight);
12325a147aaad0ce30da8db763054d963ceaedb4065Lajos Molnar
12425a147aaad0ce30da8db763054d963ceaedb4065Lajos Molnar    CHECK_EQ(0, native_window_set_crop(mNativeWindow.get(), &crop));
12525a147aaad0ce30da8db763054d963ceaedb4065Lajos Molnar
126ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    uint32_t transform;
127ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    switch (rotationDegrees) {
128ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        case 0: transform = 0; break;
129ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        case 90: transform = HAL_TRANSFORM_ROT_90; break;
130ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        case 180: transform = HAL_TRANSFORM_ROT_180; break;
131ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        case 270: transform = HAL_TRANSFORM_ROT_270; break;
132ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        default: transform = 0; break;
133ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    }
134ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
135ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    if (transform) {
136ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        CHECK_EQ(0, native_window_set_buffers_transform(
1371173118eace0e9e347cb007f0da817cee87579edGlenn Kasten                    mNativeWindow.get(), transform));
138ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    }
13920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
14020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
14120111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberSoftwareRenderer::~SoftwareRenderer() {
1425daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    delete mConverter;
1435daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    mConverter = NULL;
1445daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber}
1455daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber
1465e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huberstatic int ALIGN(int x, int y) {
1475e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber    // y must be a power of 2.
1485e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber    return (x + y - 1) & ~(y - 1);
1495e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber}
1505e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber
15120111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubervoid SoftwareRenderer::render(
152908ea6603c64e29e40277a74c9fb0e776c097830Lajos Molnar        const void *data, size_t size, int64_t timestampNs, void *platformPrivate) {
1538ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev    ANativeWindowBuffer *buf;
1545de4999e6dd8a3f2740d20e30e8a3fccdcb76362Andreas Huber    int err;
1551e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    if ((err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(),
1561e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis            &buf)) != 0) {
1575ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("Surface::dequeueBuffer returned error %d", err);
1585de4999e6dd8a3f2740d20e30e8a3fccdcb76362Andreas Huber        return;
1595de4999e6dd8a3f2740d20e30e8a3fccdcb76362Andreas Huber    }
1605de4999e6dd8a3f2740d20e30e8a3fccdcb76362Andreas Huber
1615daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    GraphicBufferMapper &mapper = GraphicBufferMapper::get();
1625daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber
1633571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber    Rect bounds(mCropWidth, mCropHeight);
1645daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber
1655daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    void *dst;
1665daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    CHECK_EQ(0, mapper.lock(
1675daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber                buf->handle, GRALLOC_USAGE_SW_WRITE_OFTEN, bounds, &dst));
1685daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber
1695daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    if (mConverter) {
1705daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber        mConverter->convert(
171f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber                data,
172f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber                mWidth, mHeight,
1733571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber                mCropLeft, mCropTop, mCropRight, mCropBottom,
174f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber                dst,
175f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber                buf->stride, buf->height,
1763571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber                0, 0, mCropWidth - 1, mCropHeight - 1);
1773571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber    } else if (mColorFormat == OMX_COLOR_FormatYUV420Planar) {
1785e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        const uint8_t *src_y = (const uint8_t *)data;
1795e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        const uint8_t *src_u = (const uint8_t *)data + mWidth * mHeight;
1805e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        const uint8_t *src_v = src_u + (mWidth / 2 * mHeight / 2);
1815e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber
1825e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        uint8_t *dst_y = (uint8_t *)dst;
1835e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        size_t dst_y_size = buf->stride * buf->height;
1845e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        size_t dst_c_stride = ALIGN(buf->stride / 2, 16);
1855e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        size_t dst_c_size = dst_c_stride * buf->height / 2;
1865e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        uint8_t *dst_v = dst_y + dst_y_size;
1875e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        uint8_t *dst_u = dst_v + dst_c_size;
1885e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber
1893571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        for (int y = 0; y < mCropHeight; ++y) {
1903571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            memcpy(dst_y, src_y, mCropWidth);
1915e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber
1925e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber            src_y += mWidth;
1935e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber            dst_y += buf->stride;
1945e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        }
1955e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber
1963571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        for (int y = 0; y < (mCropHeight + 1) / 2; ++y) {
1973571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            memcpy(dst_u, src_u, (mCropWidth + 1) / 2);
1983571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            memcpy(dst_v, src_v, (mCropWidth + 1) / 2);
1995e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber
2005e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber            src_u += mWidth / 2;
2015e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber            src_v += mWidth / 2;
2025e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber            dst_u += dst_c_stride;
2035e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber            dst_v += dst_c_stride;
2045e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        }
2053571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber    } else {
2063571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        CHECK_EQ(mColorFormat, OMX_TI_COLOR_FormatYUV420PackedSemiPlanar);
2073571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber
2083571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        const uint8_t *src_y =
2093571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            (const uint8_t *)data;
2103571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber
2113571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        const uint8_t *src_uv =
2123571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            (const uint8_t *)data + mWidth * (mHeight - mCropTop / 2);
2133571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber
2143571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        uint8_t *dst_y = (uint8_t *)dst;
2153571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber
2163571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        size_t dst_y_size = buf->stride * buf->height;
2173571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        size_t dst_c_stride = ALIGN(buf->stride / 2, 16);
2183571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        size_t dst_c_size = dst_c_stride * buf->height / 2;
2193571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        uint8_t *dst_v = dst_y + dst_y_size;
2203571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        uint8_t *dst_u = dst_v + dst_c_size;
2213571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber
2223571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        for (int y = 0; y < mCropHeight; ++y) {
2233571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            memcpy(dst_y, src_y, mCropWidth);
2243571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber
2253571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            src_y += mWidth;
2263571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            dst_y += buf->stride;
2273571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        }
2283571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber
2293571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        for (int y = 0; y < (mCropHeight + 1) / 2; ++y) {
2303571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            size_t tmp = (mCropWidth + 1) / 2;
2313571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            for (size_t x = 0; x < tmp; ++x) {
2323571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber                dst_u[x] = src_uv[2 * x];
2333571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber                dst_v[x] = src_uv[2 * x + 1];
2343571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            }
2353571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber
2363571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            src_uv += mWidth;
2373571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            dst_u += dst_c_stride;
2383571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            dst_v += dst_c_stride;
2393571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        }
2405daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    }
2414265a834394bfe14a008a2ac58fbbe388566ad07Andreas Huber
2425daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    CHECK_EQ(0, mapper.unlock(buf->handle));
2434265a834394bfe14a008a2ac58fbbe388566ad07Andreas Huber
244908ea6603c64e29e40277a74c9fb0e776c097830Lajos Molnar    if ((err = native_window_set_buffers_timestamp(mNativeWindow.get(),
245908ea6603c64e29e40277a74c9fb0e776c097830Lajos Molnar            timestampNs)) != 0) {
246908ea6603c64e29e40277a74c9fb0e776c097830Lajos Molnar        ALOGW("Surface::set_buffers_timestamp returned error %d", err);
247908ea6603c64e29e40277a74c9fb0e776c097830Lajos Molnar    }
248908ea6603c64e29e40277a74c9fb0e776c097830Lajos Molnar
2491e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    if ((err = mNativeWindow->queueBuffer(mNativeWindow.get(), buf,
2501e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis            -1)) != 0) {
2515ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("Surface::queueBuffer returned error %d", err);
2525de4999e6dd8a3f2740d20e30e8a3fccdcb76362Andreas Huber    }
2535daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    buf = NULL;
2544265a834394bfe14a008a2ac58fbbe388566ad07Andreas Huber}
2554265a834394bfe14a008a2ac58fbbe388566ad07Andreas Huber
25620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}  // namespace android
257