1b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar/* 2b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar * Copyright 2015 The Android Open Source Project 3b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar * 4b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar * Licensed under the Apache License, Version 2.0 (the "License"); 5b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar * you may not use this file except in compliance with the License. 6b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar * You may obtain a copy of the License at 7b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar * 8b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar * http://www.apache.org/licenses/LICENSE-2.0 9b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar * 10b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar * Unless required by applicable law or agreed to in writing, software 11b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar * distributed under the License is distributed on an "AS IS" BASIS, 12b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar * See the License for the specific language governing permissions and 14b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar * limitations under the License. 15b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar */ 16b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar 17b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar//#define LOG_NDEBUG 0 18b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar#define LOG_TAG "SurfaceUtils" 19b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar#include <utils/Log.h> 20b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar 212d2a2967ce29281816b9ddb9434b3c0084e4ce52Chong Zhang#include <media/hardware/VideoAPI.h> 22b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar#include <media/stagefright/SurfaceUtils.h> 23b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar#include <gui/Surface.h> 24b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar 25b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnarnamespace android { 26b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar 27b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnarstatus_t setNativeWindowSizeFormatAndUsage( 28b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar ANativeWindow *nativeWindow /* nonnull */, 29098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar int width, int height, int format, int rotation, int usage, bool reconnect) { 30098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar status_t err = NO_ERROR; 31098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar 32098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar // In some cases we need to reconnect so that we can dequeue all buffers 33098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar if (reconnect) { 34181fd9b5b64bab24bb49a34208f60a16e98488c5Chong Zhang err = nativeWindowDisconnect(nativeWindow, "setNativeWindowSizeFormatAndUsage"); 35098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar if (err != NO_ERROR) { 36181fd9b5b64bab24bb49a34208f60a16e98488c5Chong Zhang ALOGE("nativeWindowDisconnect failed: %s (%d)", strerror(-err), -err); 37098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar return err; 38098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar } 39098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar 40181fd9b5b64bab24bb49a34208f60a16e98488c5Chong Zhang err = nativeWindowConnect(nativeWindow, "setNativeWindowSizeFormatAndUsage"); 41098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar if (err != NO_ERROR) { 42181fd9b5b64bab24bb49a34208f60a16e98488c5Chong Zhang ALOGE("nativeWindowConnect failed: %s (%d)", strerror(-err), -err); 43098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar return err; 44098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar } 45098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar } 46098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar 47098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar err = native_window_set_buffers_dimensions(nativeWindow, width, height); 48b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar if (err != NO_ERROR) { 49b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar ALOGE("native_window_set_buffers_dimensions failed: %s (%d)", strerror(-err), -err); 50b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar return err; 51b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar } 52b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar 53b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar err = native_window_set_buffers_format(nativeWindow, format); 54b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar if (err != NO_ERROR) { 55b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar ALOGE("native_window_set_buffers_format failed: %s (%d)", strerror(-err), -err); 56b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar return err; 57b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar } 58b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar 59b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar int transform = 0; 60b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar if ((rotation % 90) == 0) { 61b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar switch ((rotation / 90) & 3) { 62b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar case 1: transform = HAL_TRANSFORM_ROT_90; break; 63b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar case 2: transform = HAL_TRANSFORM_ROT_180; break; 64b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar case 3: transform = HAL_TRANSFORM_ROT_270; break; 65b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar default: transform = 0; break; 66b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar } 67b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar } 68b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar 69b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar err = native_window_set_buffers_transform(nativeWindow, transform); 70b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar if (err != NO_ERROR) { 71b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar ALOGE("native_window_set_buffers_transform failed: %s (%d)", strerror(-err), -err); 72b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar return err; 73b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar } 74b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar 75b397a2a9923dcf0bec088e06df7dbe8eb128b677Craig Donner int consumerUsage = 0; 76b397a2a9923dcf0bec088e06df7dbe8eb128b677Craig Donner err = nativeWindow->query(nativeWindow, NATIVE_WINDOW_CONSUMER_USAGE_BITS, &consumerUsage); 77b397a2a9923dcf0bec088e06df7dbe8eb128b677Craig Donner if (err != NO_ERROR) { 78b397a2a9923dcf0bec088e06df7dbe8eb128b677Craig Donner ALOGW("failed to get consumer usage bits. ignoring"); 79b397a2a9923dcf0bec088e06df7dbe8eb128b677Craig Donner err = NO_ERROR; 80b397a2a9923dcf0bec088e06df7dbe8eb128b677Craig Donner } 81b397a2a9923dcf0bec088e06df7dbe8eb128b677Craig Donner 82b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar // Make sure to check whether either Stagefright or the video decoder 83b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar // requested protected buffers. 84b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar if (usage & GRALLOC_USAGE_PROTECTED) { 85b397a2a9923dcf0bec088e06df7dbe8eb128b677Craig Donner // Check if the ANativeWindow sends images directly to SurfaceFlinger. 86b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar int queuesToNativeWindow = 0; 87b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar err = nativeWindow->query( 88b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar nativeWindow, NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER, &queuesToNativeWindow); 89b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar if (err != NO_ERROR) { 90b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar ALOGE("error authenticating native window: %s (%d)", strerror(-err), -err); 91b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar return err; 92b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar } 93b397a2a9923dcf0bec088e06df7dbe8eb128b677Craig Donner 94b5625ce949ceb29e5971b6e2c94d9ee054c057d7Jiwen 'Steve' Cai // Check if the consumer end of the ANativeWindow can handle protected content. 95b5625ce949ceb29e5971b6e2c94d9ee054c057d7Jiwen 'Steve' Cai int isConsumerProtected = 0; 96b5625ce949ceb29e5971b6e2c94d9ee054c057d7Jiwen 'Steve' Cai err = nativeWindow->query( 97b5625ce949ceb29e5971b6e2c94d9ee054c057d7Jiwen 'Steve' Cai nativeWindow, NATIVE_WINDOW_CONSUMER_IS_PROTECTED, &isConsumerProtected); 98b5625ce949ceb29e5971b6e2c94d9ee054c057d7Jiwen 'Steve' Cai if (err != NO_ERROR) { 99b5625ce949ceb29e5971b6e2c94d9ee054c057d7Jiwen 'Steve' Cai ALOGE("error query native window: %s (%d)", strerror(-err), -err); 100b5625ce949ceb29e5971b6e2c94d9ee054c057d7Jiwen 'Steve' Cai return err; 101b5625ce949ceb29e5971b6e2c94d9ee054c057d7Jiwen 'Steve' Cai } 102b5625ce949ceb29e5971b6e2c94d9ee054c057d7Jiwen 'Steve' Cai 103b5625ce949ceb29e5971b6e2c94d9ee054c057d7Jiwen 'Steve' Cai // Deny queuing into native window if neither condition is satisfied. 104b5625ce949ceb29e5971b6e2c94d9ee054c057d7Jiwen 'Steve' Cai if (queuesToNativeWindow != 1 && isConsumerProtected != 1) { 105b5625ce949ceb29e5971b6e2c94d9ee054c057d7Jiwen 'Steve' Cai ALOGE("native window cannot handle protected buffers: the consumer should either be " 106b5625ce949ceb29e5971b6e2c94d9ee054c057d7Jiwen 'Steve' Cai "a hardware composer or support hardware protection"); 107b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar return PERMISSION_DENIED; 108b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar } 109b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar } 110b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar 111b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar int finalUsage = usage | consumerUsage; 112b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar ALOGV("gralloc usage: %#x(producer) + %#x(consumer) = %#x", usage, consumerUsage, finalUsage); 113b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar err = native_window_set_usage(nativeWindow, finalUsage); 114b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar if (err != NO_ERROR) { 115b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar ALOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err); 116b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar return err; 117b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar } 118b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar 119b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar err = native_window_set_scaling_mode( 120b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar nativeWindow, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW); 121b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar if (err != NO_ERROR) { 122b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar ALOGE("native_window_set_scaling_mode failed: %s (%d)", strerror(-err), -err); 123b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar return err; 124b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar } 125b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar 126b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar ALOGD("set up nativeWindow %p for %dx%d, color %#x, rotation %d, usage %#x", 127b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar nativeWindow, width, height, format, rotation, finalUsage); 128b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar return NO_ERROR; 129b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar} 130b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar 1312d2a2967ce29281816b9ddb9434b3c0084e4ce52Chong Zhangvoid setNativeWindowHdrMetadata(ANativeWindow *nativeWindow, HDRStaticInfo *info) { 1322d2a2967ce29281816b9ddb9434b3c0084e4ce52Chong Zhang struct android_smpte2086_metadata smpte2086_meta = { 1332d2a2967ce29281816b9ddb9434b3c0084e4ce52Chong Zhang .displayPrimaryRed = { 1342d2a2967ce29281816b9ddb9434b3c0084e4ce52Chong Zhang info->sType1.mR.x * 0.00002f, 1352d2a2967ce29281816b9ddb9434b3c0084e4ce52Chong Zhang info->sType1.mR.y * 0.00002f 1362d2a2967ce29281816b9ddb9434b3c0084e4ce52Chong Zhang }, 1372d2a2967ce29281816b9ddb9434b3c0084e4ce52Chong Zhang .displayPrimaryGreen = { 1382d2a2967ce29281816b9ddb9434b3c0084e4ce52Chong Zhang info->sType1.mG.x * 0.00002f, 1392d2a2967ce29281816b9ddb9434b3c0084e4ce52Chong Zhang info->sType1.mG.y * 0.00002f 1402d2a2967ce29281816b9ddb9434b3c0084e4ce52Chong Zhang }, 1412d2a2967ce29281816b9ddb9434b3c0084e4ce52Chong Zhang .displayPrimaryBlue = { 1422d2a2967ce29281816b9ddb9434b3c0084e4ce52Chong Zhang info->sType1.mB.x * 0.00002f, 1432d2a2967ce29281816b9ddb9434b3c0084e4ce52Chong Zhang info->sType1.mB.y * 0.00002f 1442d2a2967ce29281816b9ddb9434b3c0084e4ce52Chong Zhang }, 1452d2a2967ce29281816b9ddb9434b3c0084e4ce52Chong Zhang .whitePoint = { 1462d2a2967ce29281816b9ddb9434b3c0084e4ce52Chong Zhang info->sType1.mW.x * 0.00002f, 1472d2a2967ce29281816b9ddb9434b3c0084e4ce52Chong Zhang info->sType1.mW.y * 0.00002f 1482d2a2967ce29281816b9ddb9434b3c0084e4ce52Chong Zhang }, 1492d2a2967ce29281816b9ddb9434b3c0084e4ce52Chong Zhang .maxLuminance = (float) info->sType1.mMaxDisplayLuminance, 1502d2a2967ce29281816b9ddb9434b3c0084e4ce52Chong Zhang .minLuminance = info->sType1.mMinDisplayLuminance * 0.0001f 1512d2a2967ce29281816b9ddb9434b3c0084e4ce52Chong Zhang }; 1522d2a2967ce29281816b9ddb9434b3c0084e4ce52Chong Zhang 1532d2a2967ce29281816b9ddb9434b3c0084e4ce52Chong Zhang int err = native_window_set_buffers_smpte2086_metadata(nativeWindow, &smpte2086_meta); 1542d2a2967ce29281816b9ddb9434b3c0084e4ce52Chong Zhang ALOGW_IF(err != 0, "failed to set smpte2086 metadata on surface (%d)", err); 1552d2a2967ce29281816b9ddb9434b3c0084e4ce52Chong Zhang 1562d2a2967ce29281816b9ddb9434b3c0084e4ce52Chong Zhang struct android_cta861_3_metadata cta861_meta = { 1572d2a2967ce29281816b9ddb9434b3c0084e4ce52Chong Zhang .maxContentLightLevel = (float) info->sType1.mMaxContentLightLevel, 1582d2a2967ce29281816b9ddb9434b3c0084e4ce52Chong Zhang .maxFrameAverageLightLevel = (float) info->sType1.mMaxFrameAverageLightLevel 1592d2a2967ce29281816b9ddb9434b3c0084e4ce52Chong Zhang }; 1602d2a2967ce29281816b9ddb9434b3c0084e4ce52Chong Zhang 1612d2a2967ce29281816b9ddb9434b3c0084e4ce52Chong Zhang err = native_window_set_buffers_cta861_3_metadata(nativeWindow, &cta861_meta); 1622d2a2967ce29281816b9ddb9434b3c0084e4ce52Chong Zhang ALOGW_IF(err != 0, "failed to set cta861_3 metadata on surface (%d)", err); 1632d2a2967ce29281816b9ddb9434b3c0084e4ce52Chong Zhang} 1642d2a2967ce29281816b9ddb9434b3c0084e4ce52Chong Zhang 165b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnarstatus_t pushBlankBuffersToNativeWindow(ANativeWindow *nativeWindow /* nonnull */) { 166b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar status_t err = NO_ERROR; 167b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar ANativeWindowBuffer* anb = NULL; 168b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar int numBufs = 0; 169b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar int minUndequeuedBufs = 0; 170b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar 171b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar // We need to reconnect to the ANativeWindow as a CPU client to ensure that 172b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar // no frames get dropped by SurfaceFlinger assuming that these are video 173b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar // frames. 174181fd9b5b64bab24bb49a34208f60a16e98488c5Chong Zhang err = nativeWindowDisconnect(nativeWindow, "pushBlankBuffersToNativeWindow"); 175b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar if (err != NO_ERROR) { 176b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)", strerror(-err), -err); 177b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar return err; 178b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar } 179b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar 180b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar err = native_window_api_connect(nativeWindow, NATIVE_WINDOW_API_CPU); 181b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar if (err != NO_ERROR) { 182b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar ALOGE("error pushing blank frames: api_connect failed: %s (%d)", strerror(-err), -err); 183181fd9b5b64bab24bb49a34208f60a16e98488c5Chong Zhang (void)nativeWindowConnect(nativeWindow, "pushBlankBuffersToNativeWindow(err)"); 184b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar return err; 185b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar } 186b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar 187b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar err = setNativeWindowSizeFormatAndUsage( 188098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar nativeWindow, 1, 1, HAL_PIXEL_FORMAT_RGBX_8888, 0, GRALLOC_USAGE_SW_WRITE_OFTEN, 189098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar false /* reconnect */); 190b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar if (err != NO_ERROR) { 191b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar goto error; 192b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar } 193b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar 194b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar static_cast<Surface*>(nativeWindow)->getIGraphicBufferProducer()->allowAllocation(true); 195b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar 196b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar err = nativeWindow->query(nativeWindow, 197b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs); 198b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar if (err != NO_ERROR) { 199b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar ALOGE("error pushing blank frames: MIN_UNDEQUEUED_BUFFERS query " 200b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar "failed: %s (%d)", strerror(-err), -err); 201b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar goto error; 202b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar } 203b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar 204b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar numBufs = minUndequeuedBufs + 1; 205b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar err = native_window_set_buffer_count(nativeWindow, numBufs); 206b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar if (err != NO_ERROR) { 207b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar ALOGE("error pushing blank frames: set_buffer_count failed: %s (%d)", strerror(-err), -err); 208b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar goto error; 209b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar } 210b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar 211b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar // We push numBufs + 1 buffers to ensure that we've drawn into the same 212b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar // buffer twice. This should guarantee that the buffer has been displayed 213b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar // on the screen and then been replaced, so an previous video frames are 214b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar // guaranteed NOT to be currently displayed. 215b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar for (int i = 0; i < numBufs + 1; i++) { 216b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar err = native_window_dequeue_buffer_and_wait(nativeWindow, &anb); 217b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar if (err != NO_ERROR) { 218b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar ALOGE("error pushing blank frames: dequeueBuffer failed: %s (%d)", 219b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar strerror(-err), -err); 220b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar break; 221b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar } 222b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar 22304e331c5032609f7ed42c344780b9c1b4cfe4afbMathias Agopian sp<GraphicBuffer> buf(GraphicBuffer::from(anb)); 224b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar 225b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar // Fill the buffer with the a 1x1 checkerboard pattern ;) 226b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar uint32_t *img = NULL; 227b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img)); 228b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar if (err != NO_ERROR) { 229b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar ALOGE("error pushing blank frames: lock failed: %s (%d)", strerror(-err), -err); 230b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar break; 231b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar } 232b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar 233b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar *img = 0; 234b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar 235b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar err = buf->unlock(); 236b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar if (err != NO_ERROR) { 237b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar ALOGE("error pushing blank frames: unlock failed: %s (%d)", strerror(-err), -err); 238b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar break; 239b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar } 240b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar 241b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar err = nativeWindow->queueBuffer(nativeWindow, buf->getNativeBuffer(), -1); 242b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar if (err != NO_ERROR) { 243b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar ALOGE("error pushing blank frames: queueBuffer failed: %s (%d)", strerror(-err), -err); 244b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar break; 245b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar } 246b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar 247b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar anb = NULL; 248b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar } 249b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar 250b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnarerror: 251b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar 252b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar if (anb != NULL) { 253b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar nativeWindow->cancelBuffer(nativeWindow, anb, -1); 254b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar anb = NULL; 255b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar } 256b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar 257b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar // Clean up after success or error. 258b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar status_t err2 = native_window_api_disconnect(nativeWindow, NATIVE_WINDOW_API_CPU); 259b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar if (err2 != NO_ERROR) { 260b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)", strerror(-err2), -err2); 261b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar if (err == NO_ERROR) { 262b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar err = err2; 263b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar } 264b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar } 265b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar 266181fd9b5b64bab24bb49a34208f60a16e98488c5Chong Zhang err2 = nativeWindowConnect(nativeWindow, "pushBlankBuffersToNativeWindow(err2)"); 267b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar if (err2 != NO_ERROR) { 268b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar ALOGE("error pushing blank frames: api_connect failed: %s (%d)", strerror(-err), -err); 269b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar if (err == NO_ERROR) { 270b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar err = err2; 271b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar } 272b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar } 273b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar 274b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar return err; 275b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar} 276b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar 277181fd9b5b64bab24bb49a34208f60a16e98488c5Chong Zhangstatus_t nativeWindowConnect(ANativeWindow *surface, const char *reason) { 278181fd9b5b64bab24bb49a34208f60a16e98488c5Chong Zhang ALOGD("connecting to surface %p, reason %s", surface, reason); 279181fd9b5b64bab24bb49a34208f60a16e98488c5Chong Zhang 280181fd9b5b64bab24bb49a34208f60a16e98488c5Chong Zhang status_t err = native_window_api_connect(surface, NATIVE_WINDOW_API_MEDIA); 281181fd9b5b64bab24bb49a34208f60a16e98488c5Chong Zhang ALOGE_IF(err != OK, "Failed to connect to surface %p, err %d", surface, err); 282181fd9b5b64bab24bb49a34208f60a16e98488c5Chong Zhang 283181fd9b5b64bab24bb49a34208f60a16e98488c5Chong Zhang return err; 284181fd9b5b64bab24bb49a34208f60a16e98488c5Chong Zhang} 285181fd9b5b64bab24bb49a34208f60a16e98488c5Chong Zhang 286181fd9b5b64bab24bb49a34208f60a16e98488c5Chong Zhangstatus_t nativeWindowDisconnect(ANativeWindow *surface, const char *reason) { 287181fd9b5b64bab24bb49a34208f60a16e98488c5Chong Zhang ALOGD("disconnecting from surface %p, reason %s", surface, reason); 288181fd9b5b64bab24bb49a34208f60a16e98488c5Chong Zhang 289181fd9b5b64bab24bb49a34208f60a16e98488c5Chong Zhang status_t err = native_window_api_disconnect(surface, NATIVE_WINDOW_API_MEDIA); 290181fd9b5b64bab24bb49a34208f60a16e98488c5Chong Zhang ALOGE_IF(err != OK, "Failed to disconnect from surface %p, err %d", surface, err); 291181fd9b5b64bab24bb49a34208f60a16e98488c5Chong Zhang 292181fd9b5b64bab24bb49a34208f60a16e98488c5Chong Zhang return err; 293181fd9b5b64bab24bb49a34208f60a16e98488c5Chong Zhang} 294b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar} // namespace android 295b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar 296