1c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev/*
2c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * Copyright (C) Texas Instruments - http://www.ti.com/
3c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev *
4c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * Licensed under the Apache License, Version 2.0 (the "License");
5c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * you may not use this file except in compliance with the License.
6c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * You may obtain a copy of the License at
7c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev *
8c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev *      http://www.apache.org/licenses/LICENSE-2.0
9c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev *
10c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * Unless required by applicable law or agreed to in writing, software
11c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * distributed under the License is distributed on an "AS IS" BASIS,
12c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * See the License for the specific language governing permissions and
14c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * limitations under the License.
15c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev */
16c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
17c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
18c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
19c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
20c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#define LOG_TAG "CameraHAL"
21c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
22c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#include "ANativeWindowDisplayAdapter.h"
23c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#include <OMX_IVCommon.h>
246c73fda9fdca5431e4e7911bb3171e36088a861eTyler Luu#include <ui/GraphicBuffer.h>
25c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#include <ui/GraphicBufferMapper.h>
26c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#include <hal_public.h>
27c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
28c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevnamespace android {
29c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
30c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev///Constant declarations
31c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev///@todo Check the time units
32c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevconst int ANativeWindowDisplayAdapter::DISPLAY_TIMEOUT = 1000;  // seconds
33c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
34c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev//Suspends buffers after given amount of failed dq's
35c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevconst int ANativeWindowDisplayAdapter::FAILED_DQS_TO_SUSPEND = 3;
36c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
37c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
38c322989ae6ff6769490828de1b5eda12b749cce9Iliyan MalchevOMX_COLOR_FORMATTYPE toOMXPixFormat(const char* parameters_format)
39c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
40c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    OMX_COLOR_FORMATTYPE pixFormat;
41c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
42c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( parameters_format != NULL )
43c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    {
44c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        if (strcmp(parameters_format, (const char *) CameraParameters::PIXEL_FORMAT_YUV422I) == 0)
45c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            {
46c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            CAMHAL_LOGDA("CbYCrY format selected");
47c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            pixFormat = OMX_COLOR_FormatCbYCrY;
48c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            }
49c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        else if(strcmp(parameters_format, (const char *) CameraParameters::PIXEL_FORMAT_YUV420SP) == 0)
50c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            {
51c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            CAMHAL_LOGDA("YUV420SP format selected");
52c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            pixFormat = OMX_COLOR_FormatYUV420SemiPlanar;
53c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            }
54c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        else if(strcmp(parameters_format, (const char *) CameraParameters::PIXEL_FORMAT_RGB565) == 0)
55c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            {
56c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            CAMHAL_LOGDA("RGB565 format selected");
57c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            pixFormat = OMX_COLOR_Format16bitRGB565;
58c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            }
59c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        else
60c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            {
61c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            CAMHAL_LOGDA("Invalid format, CbYCrY format selected as default");
62c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            pixFormat = OMX_COLOR_FormatCbYCrY;
63c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
64c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
65c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    else {
66c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        CAMHAL_LOGEA("Preview format is NULL, defaulting to CbYCrY");
67c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        pixFormat = OMX_COLOR_FormatCbYCrY;
68c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
69c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
70c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    return pixFormat;
71c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
72c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
73c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevconst char* getPixFormatConstant(const char* parameters_format)
74c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
75c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    const char* pixFormat;
76c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
77c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( parameters_format != NULL )
78c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    {
79c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        if (strcmp(parameters_format, (const char *) CameraParameters::PIXEL_FORMAT_YUV422I) == 0)
80c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
81c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            CAMHAL_LOGVA("CbYCrY format selected");
82c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            pixFormat = (const char *) CameraParameters::PIXEL_FORMAT_YUV422I;
83c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
84c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        else if(strcmp(parameters_format, (const char *) CameraParameters::PIXEL_FORMAT_YUV420SP) == 0 ||
85c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                strcmp(parameters_format, (const char *) CameraParameters::PIXEL_FORMAT_YUV420P) == 0)
86c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
87c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            // TODO(XXX): We are treating YV12 the same as YUV420SP
88c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            CAMHAL_LOGVA("YUV420SP format selected");
89c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            pixFormat = (const char *) CameraParameters::PIXEL_FORMAT_YUV420SP;
90c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
91c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        else if(strcmp(parameters_format, (const char *) CameraParameters::PIXEL_FORMAT_RGB565) == 0)
92c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
93c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            CAMHAL_LOGVA("RGB565 format selected");
94c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            pixFormat = (const char *) CameraParameters::PIXEL_FORMAT_RGB565;
95c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
96c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        else
97c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
98c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            CAMHAL_LOGEA("Invalid format, CbYCrY format selected as default");
99c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            pixFormat = (const char *) CameraParameters::PIXEL_FORMAT_YUV422I;
100c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
101c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
102c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    else
103c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    {
104c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        CAMHAL_LOGEA("Preview format is NULL, defaulting to CbYCrY");
105c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        pixFormat = (const char *) CameraParameters::PIXEL_FORMAT_YUV422I;
106c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
107c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
108c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    return pixFormat;
109c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
110c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
111c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevconst size_t getBufSize(const char* parameters_format, int width, int height)
112c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
113c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    int buf_size;
114c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
115c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( parameters_format != NULL ) {
116c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        if (strcmp(parameters_format,
117c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                  (const char *) CameraParameters::PIXEL_FORMAT_YUV422I) == 0) {
118c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            buf_size = width * height * 2;
119c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
120c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        else if((strcmp(parameters_format, CameraParameters::PIXEL_FORMAT_YUV420SP) == 0) ||
121c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                (strcmp(parameters_format, CameraParameters::PIXEL_FORMAT_YUV420P) == 0)) {
122c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            buf_size = width * height * 3 / 2;
123c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
124c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        else if(strcmp(parameters_format,
125c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                      (const char *) CameraParameters::PIXEL_FORMAT_RGB565) == 0) {
126c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            buf_size = width * height * 2;
127c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        } else {
128c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            CAMHAL_LOGEA("Invalid format");
129c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            buf_size = 0;
130c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
131c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    } else {
132c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        CAMHAL_LOGEA("Preview format is NULL");
133c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        buf_size = 0;
134c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
135c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
136c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    return buf_size;
137c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
138c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev/*--------------------ANativeWindowDisplayAdapter Class STARTS here-----------------------------*/
139c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
140c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
141c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev/**
142c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * Display Adapter class STARTS here..
143c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev */
144c322989ae6ff6769490828de1b5eda12b749cce9Iliyan MalchevANativeWindowDisplayAdapter::ANativeWindowDisplayAdapter():mDisplayThread(NULL),
145c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                                        mDisplayState(ANativeWindowDisplayAdapter::DISPLAY_INIT),
146c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                                        mDisplayEnabled(false),
147c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                                        mBufferCount(0)
148c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
149c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
150c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
151c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
152c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
153c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
154c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
155c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
156c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mShotToShot = false;
157c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mStartCapture.tv_sec = 0;
158c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mStartCapture.tv_usec = 0;
159c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mStandbyToShot.tv_sec = 0;
160c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mStandbyToShot.tv_usec = 0;
161c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mMeasureStandby = false;
162c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#endif
163c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
164c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mPixelFormat = NULL;
165c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mBufferHandleMap = NULL;
166c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mGrallocHandleMap = NULL;
167c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mOffsetsMap = NULL;
168c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mFrameProvider = NULL;
1697702898343dbb27a4543c642d189cff5de7046c9Sundar Raman    mANativeWindow = NULL;
170c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
171c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mFrameWidth = 0;
172c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mFrameHeight = 0;
173c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mPreviewWidth = 0;
174c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mPreviewHeight = 0;
175c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
176c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mSuspend = false;
177c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mFailedDQs = 0;
178c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
179c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mPaused = false;
180130ed815e4cea7c2906a1e1f0d665c2f94b690f5Akwasi Boateng    mXOff = -1;
181130ed815e4cea7c2906a1e1f0d665c2f94b690f5Akwasi Boateng    mYOff = -1;
182c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mFirstInit = false;
183c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
184c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mFD = -1;
185c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
186c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
187c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
188c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
189c322989ae6ff6769490828de1b5eda12b749cce9Iliyan MalchevANativeWindowDisplayAdapter::~ANativeWindowDisplayAdapter()
190c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
191c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    Semaphore sem;
192c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    TIUTILS::Message msg;
193c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
194c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
195c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
196c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    ///If Frame provider exists
19797e6bcc45eb2161c10761abc4fbf12ce3e1d52c8Tyler Luu    if (mFrameProvider) {
198c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        // Unregister with the frame provider
199c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mFrameProvider->disableFrameNotification(CameraFrame::ALL_FRAMES);
20097e6bcc45eb2161c10761abc4fbf12ce3e1d52c8Tyler Luu        delete mFrameProvider;
201c493114006e0e136c8c88c2fc9865994054959bfSundar Raman        mFrameProvider = NULL;
202c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
203c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
204c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    ///The ANativeWindow object will get destroyed here
205c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    destroy();
206c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
207c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    ///If Display thread exists
208c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if(mDisplayThread.get())
209c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
210c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        ///Kill the display thread
211c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        sem.Create();
212c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        msg.command = DisplayThread::DISPLAY_EXIT;
213c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
214c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        // Send the semaphore to signal once the command is completed
215c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        msg.arg1 = &sem;
216c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
217c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        ///Post the message to display thread
218c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mDisplayThread->msgQ().put(&msg);
219c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
220c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        ///Wait for the ACK - implies that the thread is now started and waiting for frames
221c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        sem.Wait();
222c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
223c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        // Exit and cleanup the thread
224c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mDisplayThread->requestExitAndWait();
225c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
226c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        // Delete the display thread
227c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mDisplayThread.clear();
228c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
229c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
230c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
231c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
232c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
233c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
234c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevstatus_t ANativeWindowDisplayAdapter::initialize()
235c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
236c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
237c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
238c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    ///Create the display thread
239c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mDisplayThread = new DisplayThread(this);
240c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( !mDisplayThread.get() )
241c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
242c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        CAMHAL_LOGEA("Couldn't create display thread");
243c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        LOG_FUNCTION_NAME_EXIT;
244c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        return NO_MEMORY;
245c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
246c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
247c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    ///Start the display thread
248c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    status_t ret = mDisplayThread->run("DisplayThread", PRIORITY_URGENT_DISPLAY);
249c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( ret != NO_ERROR )
250c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
251c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        CAMHAL_LOGEA("Couldn't run display thread");
252c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        LOG_FUNCTION_NAME_EXIT;
253c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        return ret;
254c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
255c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
256c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
257c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
258c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    return ret;
259c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
260c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
261c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevint ANativeWindowDisplayAdapter::setPreviewWindow(preview_stream_ops_t* window)
262c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
263c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
264c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    ///Note that Display Adapter cannot work without a valid window object
265c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( !window)
266c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
267c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        CAMHAL_LOGEA("NULL window object passed to DisplayAdapter");
268c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        LOG_FUNCTION_NAME_EXIT;
269c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        return BAD_VALUE;
270c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
271c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
27239371f31292f050f7fd75f7d36c7c9eeffd4ae64Tyler Luu    if ( window == mANativeWindow ) {
27339371f31292f050f7fd75f7d36c7c9eeffd4ae64Tyler Luu        return ALREADY_EXISTS;
27439371f31292f050f7fd75f7d36c7c9eeffd4ae64Tyler Luu    }
27539371f31292f050f7fd75f7d36c7c9eeffd4ae64Tyler Luu
276c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    ///Destroy the existing window object, if it exists
277c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    destroy();
278c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
279c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    ///Move to new window obj
280c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mANativeWindow = window;
281c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
282c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
283c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
284c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    return NO_ERROR;
285c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
286c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
287c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevint ANativeWindowDisplayAdapter::setFrameProvider(FrameNotifier *frameProvider)
288c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
289c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
290c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
291c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    // Check for NULL pointer
29297e6bcc45eb2161c10761abc4fbf12ce3e1d52c8Tyler Luu    if ( !frameProvider ) {
293c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        CAMHAL_LOGEA("NULL passed for frame provider");
294c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        LOG_FUNCTION_NAME_EXIT;
295c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        return BAD_VALUE;
296c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
297c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
29897e6bcc45eb2161c10761abc4fbf12ce3e1d52c8Tyler Luu    //Release any previous frame providers
29997e6bcc45eb2161c10761abc4fbf12ce3e1d52c8Tyler Luu    if ( NULL != mFrameProvider ) {
30097e6bcc45eb2161c10761abc4fbf12ce3e1d52c8Tyler Luu        delete mFrameProvider;
30197e6bcc45eb2161c10761abc4fbf12ce3e1d52c8Tyler Luu    }
30297e6bcc45eb2161c10761abc4fbf12ce3e1d52c8Tyler Luu
303c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    /** Dont do anything here, Just save the pointer for use when display is
304c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev         actually enabled or disabled
305c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    */
306c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mFrameProvider = new FrameProvider(frameProvider, this, frameCallbackRelay);
307c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
308c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
309c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
310c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    return NO_ERROR;
311c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
312c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
313c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevint ANativeWindowDisplayAdapter::setErrorHandler(ErrorNotifier *errorNotifier)
314c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
315c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    status_t ret = NO_ERROR;
316c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
317c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
318c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
319c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( NULL == errorNotifier )
320c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
321c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        CAMHAL_LOGEA("Invalid Error Notifier reference");
322c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        ret = -EINVAL;
323c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
324c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
325c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( NO_ERROR == ret )
326c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
327c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mErrorNotifier = errorNotifier;
328c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
329c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
330c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
331c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
332c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    return ret;
333c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
334c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
335c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
336c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
337c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevstatus_t ANativeWindowDisplayAdapter::setSnapshotTimeRef(struct timeval *refTime)
338c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
339c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    status_t ret = NO_ERROR;
340c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
341c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
342c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
343c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( NULL != refTime )
344c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
345c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        Mutex::Autolock lock(mLock);
346c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        memcpy(&mStartCapture, refTime, sizeof(struct timeval));
347c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
348c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
349c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
350c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
351c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    return ret;
352c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
353c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
354c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#endif
355c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
356c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
357c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevint ANativeWindowDisplayAdapter::enableDisplay(int width, int height, struct timeval *refTime, S3DParameters *s3dParams)
358c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
359c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    Semaphore sem;
360c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    TIUTILS::Message msg;
361c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
362c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
363c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
364c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( mDisplayEnabled )
365c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
366c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        CAMHAL_LOGDA("Display is already enabled");
367c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        LOG_FUNCTION_NAME_EXIT;
368c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
369c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        return NO_ERROR;
370c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
371c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
372c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#if 0 //TODO: s3d is not part of bringup...will reenable
373c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if (s3dParams)
374c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mOverlay->set_s3d_params(s3dParams->mode, s3dParams->framePacking,
375c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                                    s3dParams->order, s3dParams->subSampling);
376c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#endif
377c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
378c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
379c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
380c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( NULL != refTime )
381c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
382c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        Mutex::Autolock lock(mLock);
383c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        memcpy(&mStandbyToShot, refTime, sizeof(struct timeval));
384c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mMeasureStandby = true;
385c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
386c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
387c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#endif
388c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
389c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    //Send START_DISPLAY COMMAND to display thread. Display thread will start and then wait for a message
390c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    sem.Create();
391c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    msg.command = DisplayThread::DISPLAY_START;
392c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
393c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    // Send the semaphore to signal once the command is completed
394c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    msg.arg1 = &sem;
395c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
396c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    ///Post the message to display thread
397c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mDisplayThread->msgQ().put(&msg);
398c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
399c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    ///Wait for the ACK - implies that the thread is now started and waiting for frames
400c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    sem.Wait();
401c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
402c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    // Register with the frame provider for frames
403c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mFrameProvider->enableFrameNotification(CameraFrame::PREVIEW_FRAME_SYNC);
404c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
405c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mDisplayEnabled = true;
406c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mPreviewWidth = width;
407c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mPreviewHeight = height;
408c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
409c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    CAMHAL_LOGVB("mPreviewWidth = %d mPreviewHeight = %d", mPreviewWidth, mPreviewHeight);
410c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
411c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
412c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
413c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    return NO_ERROR;
414c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
415c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
416816f63fd6a78b45e18819d9967d409c212c88eaeSundar Ramanint ANativeWindowDisplayAdapter::disableDisplay(bool cancel_buffer)
417c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
4187702898343dbb27a4543c642d189cff5de7046c9Sundar Raman    status_t ret = NO_ERROR;
4196c73fda9fdca5431e4e7911bb3171e36088a861eTyler Luu    GraphicBufferMapper &mapper = GraphicBufferMapper::get();
4207702898343dbb27a4543c642d189cff5de7046c9Sundar Raman
421c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
422c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
423c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if(!mDisplayEnabled)
424c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
425c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        CAMHAL_LOGDA("Display is already disabled");
426c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        LOG_FUNCTION_NAME_EXIT;
427c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        return ALREADY_EXISTS;
428c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
429c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
430c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    // Unregister with the frame provider here
431c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mFrameProvider->disableFrameNotification(CameraFrame::PREVIEW_FRAME_SYNC);
4328e88af31129b8cc09675279ca2eac88256d8526bAkwasi Boateng    mFrameProvider->removeFramePointers();
433c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
434c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( NULL != mDisplayThread.get() )
435c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
436c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        //Send STOP_DISPLAY COMMAND to display thread. Display thread will stop and dequeue all messages
437c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        // and then wait for message
438c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        Semaphore sem;
439c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        sem.Create();
440c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        TIUTILS::Message msg;
441c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        msg.command = DisplayThread::DISPLAY_STOP;
442c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
443c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        // Send the semaphore to signal once the command is completed
444c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        msg.arg1 = &sem;
445c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
446c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        ///Post the message to display thread
447c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mDisplayThread->msgQ().put(&msg);
448c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
449c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        ///Wait for the ACK for display to be disabled
450c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
451c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        sem.Wait();
452c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
453c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
454c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
455c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    Mutex::Autolock lock(mLock);
456c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    {
457c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        ///Reset the display enabled flag
458c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mDisplayEnabled = false;
459c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
460c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        ///Reset the offset values
461130ed815e4cea7c2906a1e1f0d665c2f94b690f5Akwasi Boateng        mXOff = -1;
462130ed815e4cea7c2906a1e1f0d665c2f94b690f5Akwasi Boateng        mYOff = -1;
463c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
464c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        ///Reset the frame width and height values
465c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mFrameWidth =0;
466c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mFrameHeight = 0;
467c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mPreviewWidth = 0;
468c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mPreviewHeight = 0;
469c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
470816f63fd6a78b45e18819d9967d409c212c88eaeSundar Raman       if(cancel_buffer)
471816f63fd6a78b45e18819d9967d409c212c88eaeSundar Raman        {
472b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman        // Return the buffers to ANativeWindow here, the mFramesWithCameraAdapterMap is also cleared inside
473b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman        returnBuffersToWindow();
474816f63fd6a78b45e18819d9967d409c212c88eaeSundar Raman        }
475816f63fd6a78b45e18819d9967d409c212c88eaeSundar Raman       else
476816f63fd6a78b45e18819d9967d409c212c88eaeSundar Raman        {
477816f63fd6a78b45e18819d9967d409c212c88eaeSundar Raman        mANativeWindow = NULL;
478b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman        // Clear the frames with camera adapter map
479b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman        mFramesWithCameraAdapterMap.clear();
480816f63fd6a78b45e18819d9967d409c212c88eaeSundar Raman        }
481c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
482b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman
483c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
484c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
485c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
486c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    return NO_ERROR;
487c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
488c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
489c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevstatus_t ANativeWindowDisplayAdapter::pauseDisplay(bool pause)
490c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
491c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    status_t ret = NO_ERROR;
492c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
493c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
494c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
495c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    {
496c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        Mutex::Autolock lock(mLock);
497c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mPaused = pause;
498c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
499c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
500c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
501c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
502c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    return ret;
503c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
504c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
505c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
506c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevvoid ANativeWindowDisplayAdapter::destroy()
507c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
508c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
509c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
510c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    ///Check if the display is disabled, if not disable it
511c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( mDisplayEnabled )
512c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    {
513c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        CAMHAL_LOGDA("WARNING: Calling destroy of Display adapter when display enabled. Disabling display..");
514816f63fd6a78b45e18819d9967d409c212c88eaeSundar Raman        disableDisplay(false);
515c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
516c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
517c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mBufferCount = 0;
518c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
519c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
520c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
521c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
522c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev// Implementation of inherited interfaces
523c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevvoid* ANativeWindowDisplayAdapter::allocateBuffer(int width, int height, const char* format, int &bytes, int numBufs)
524c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
525c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
526c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    status_t err;
527c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    int i = -1;
528c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    const int lnumBufs = numBufs;
529c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mBufferHandleMap = new buffer_handle_t*[lnumBufs];
530c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mGrallocHandleMap = new IMG_native_handle_t*[lnumBufs];
531c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    int undequeued = 0;
5326c73fda9fdca5431e4e7911bb3171e36088a861eTyler Luu    GraphicBufferMapper &mapper = GraphicBufferMapper::get();
5336c73fda9fdca5431e4e7911bb3171e36088a861eTyler Luu    Rect bounds;
5346c73fda9fdca5431e4e7911bb3171e36088a861eTyler Luu
535c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
5367702898343dbb27a4543c642d189cff5de7046c9Sundar Raman    if ( NULL == mANativeWindow ) {
5377702898343dbb27a4543c642d189cff5de7046c9Sundar Raman        return NULL;
5387702898343dbb27a4543c642d189cff5de7046c9Sundar Raman    }
5397702898343dbb27a4543c642d189cff5de7046c9Sundar Raman
540c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    // Set gralloc usage bits for window.
541941b79b3815eb5f41e0d194d6f65161d1e4a86d0Tyler Luu    err = mANativeWindow->set_usage(mANativeWindow, CAMHAL_GRALLOC_USAGE);
542c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if (err != 0) {
54346de639b23db99d7b99ff1c676ac98b84b6336c6Steve Block        ALOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err);
5447702898343dbb27a4543c642d189cff5de7046c9Sundar Raman
5457702898343dbb27a4543c642d189cff5de7046c9Sundar Raman        if ( ENODEV == err ) {
5467702898343dbb27a4543c642d189cff5de7046c9Sundar Raman            CAMHAL_LOGEA("Preview surface abandoned!");
5477702898343dbb27a4543c642d189cff5de7046c9Sundar Raman            mANativeWindow = NULL;
5487702898343dbb27a4543c642d189cff5de7046c9Sundar Raman        }
5497702898343dbb27a4543c642d189cff5de7046c9Sundar Raman
550c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        return NULL;
551c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
552c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
553c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    CAMHAL_LOGDB("Number of buffers set to ANativeWindow %d", numBufs);
554b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman    ///Set the number of buffers needed for camera preview
555b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman    err = mANativeWindow->set_buffer_count(mANativeWindow, numBufs);
556b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman    if (err != 0) {
55746de639b23db99d7b99ff1c676ac98b84b6336c6Steve Block        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err), -err);
5587702898343dbb27a4543c642d189cff5de7046c9Sundar Raman
559b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman        if ( ENODEV == err ) {
560b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman            CAMHAL_LOGEA("Preview surface abandoned!");
561b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman            mANativeWindow = NULL;
562c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
563b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman
564b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman        return NULL;
565b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman    }
566b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman    CAMHAL_LOGDB("Configuring %d buffers for ANativeWindow", numBufs);
567b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman    mBufferCount = numBufs;
568b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman
569c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
570c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    // Set window geometry
571c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    err = mANativeWindow->set_buffers_geometry(
572c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            mANativeWindow,
573c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            width,
574c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            height,
5752e986e5e29b391b070f608d641538c14b778d4baIliyan Malchev            /*toOMXPixFormat(format)*/HAL_PIXEL_FORMAT_TI_NV12);  // Gralloc only supports NV12 alloc!
576c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
577c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if (err != 0) {
57846de639b23db99d7b99ff1c676ac98b84b6336c6Steve Block        ALOGE("native_window_set_buffers_geometry failed: %s (%d)", strerror(-err), -err);
5797702898343dbb27a4543c642d189cff5de7046c9Sundar Raman
5807702898343dbb27a4543c642d189cff5de7046c9Sundar Raman        if ( ENODEV == err ) {
5817702898343dbb27a4543c642d189cff5de7046c9Sundar Raman            CAMHAL_LOGEA("Preview surface abandoned!");
5827702898343dbb27a4543c642d189cff5de7046c9Sundar Raman            mANativeWindow = NULL;
5837702898343dbb27a4543c642d189cff5de7046c9Sundar Raman        }
5847702898343dbb27a4543c642d189cff5de7046c9Sundar Raman
585c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        return NULL;
586c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
587c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
588c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    ///We just return the buffers from ANativeWindow, if the width and height are same, else (vstab, vnf case)
589c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    ///re-allocate buffers using ANativeWindow and then get them
590c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    ///@todo - Re-allocate buffers for vnf and vstab using the width, height, format, numBufs etc
59197e6bcc45eb2161c10761abc4fbf12ce3e1d52c8Tyler Luu    if ( mBufferHandleMap == NULL )
592c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    {
593c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        CAMHAL_LOGEA("Couldn't create array for ANativeWindow buffers");
594c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        LOG_FUNCTION_NAME_EXIT;
595c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        return NULL;
596c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
597c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
598c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mANativeWindow->get_min_undequeued_buffer_count(mANativeWindow, &undequeued);
599c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
600c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    for ( i=0; i < mBufferCount; i++ )
601c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    {
602c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        IMG_native_handle_t** hndl2hndl;
603c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        IMG_native_handle_t* handle;
604c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        int stride;  // dummy variable to get stride
605c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        // TODO(XXX): Do we need to keep stride information in camera hal?
606c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
607c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        err = mANativeWindow->dequeue_buffer(mANativeWindow, (buffer_handle_t**) &hndl2hndl, &stride);
608c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
609c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        if (err != 0) {
610c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            CAMHAL_LOGEB("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
6117702898343dbb27a4543c642d189cff5de7046c9Sundar Raman
6127702898343dbb27a4543c642d189cff5de7046c9Sundar Raman            if ( ENODEV == err ) {
6137702898343dbb27a4543c642d189cff5de7046c9Sundar Raman                CAMHAL_LOGEA("Preview surface abandoned!");
6147702898343dbb27a4543c642d189cff5de7046c9Sundar Raman                mANativeWindow = NULL;
6157702898343dbb27a4543c642d189cff5de7046c9Sundar Raman            }
6167702898343dbb27a4543c642d189cff5de7046c9Sundar Raman
617c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            goto fail;
618c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
619c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
620c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        handle = *hndl2hndl;
621c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
622c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mBufferHandleMap[i] = (buffer_handle_t*) hndl2hndl;
623c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mGrallocHandleMap[i] = handle;
624c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mFramesWithCameraAdapterMap.add((int) mGrallocHandleMap[i], i);
625c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
626c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        bytes =  getBufSize(format, width, height);
627c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
628c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
629c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
630c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    // lock the initial queueable buffers
6316c73fda9fdca5431e4e7911bb3171e36088a861eTyler Luu    bounds.left = 0;
6326c73fda9fdca5431e4e7911bb3171e36088a861eTyler Luu    bounds.top = 0;
6336c73fda9fdca5431e4e7911bb3171e36088a861eTyler Luu    bounds.right = width;
6346c73fda9fdca5431e4e7911bb3171e36088a861eTyler Luu    bounds.bottom = height;
6356c73fda9fdca5431e4e7911bb3171e36088a861eTyler Luu
636c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    for( i = 0;  i < mBufferCount-undequeued; i++ )
637c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    {
6386c73fda9fdca5431e4e7911bb3171e36088a861eTyler Luu        void *y_uv[2];
6396c73fda9fdca5431e4e7911bb3171e36088a861eTyler Luu
640c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mANativeWindow->lock_buffer(mANativeWindow, mBufferHandleMap[i]);
6416c73fda9fdca5431e4e7911bb3171e36088a861eTyler Luu
642941b79b3815eb5f41e0d194d6f65161d1e4a86d0Tyler Luu        mapper.lock((buffer_handle_t) mGrallocHandleMap[i], CAMHAL_GRALLOC_USAGE, bounds, y_uv);
6438e88af31129b8cc09675279ca2eac88256d8526bAkwasi Boateng        mFrameProvider->addFramePointers(mGrallocHandleMap[i] , y_uv);
644c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
645c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
646c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    // return the rest of the buffers back to ANativeWindow
647c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    for(i = (mBufferCount-undequeued); i >= 0 && i < mBufferCount; i++)
648c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    {
6497702898343dbb27a4543c642d189cff5de7046c9Sundar Raman        err = mANativeWindow->cancel_buffer(mANativeWindow, mBufferHandleMap[i]);
6507702898343dbb27a4543c642d189cff5de7046c9Sundar Raman        if (err != 0) {
6517702898343dbb27a4543c642d189cff5de7046c9Sundar Raman            CAMHAL_LOGEB("cancel_buffer failed: %s (%d)", strerror(-err), -err);
6527702898343dbb27a4543c642d189cff5de7046c9Sundar Raman
6537702898343dbb27a4543c642d189cff5de7046c9Sundar Raman            if ( ENODEV == err ) {
6547702898343dbb27a4543c642d189cff5de7046c9Sundar Raman                CAMHAL_LOGEA("Preview surface abandoned!");
6557702898343dbb27a4543c642d189cff5de7046c9Sundar Raman                mANativeWindow = NULL;
6567702898343dbb27a4543c642d189cff5de7046c9Sundar Raman            }
6577702898343dbb27a4543c642d189cff5de7046c9Sundar Raman
6587702898343dbb27a4543c642d189cff5de7046c9Sundar Raman            goto fail;
6597702898343dbb27a4543c642d189cff5de7046c9Sundar Raman        }
6606c73fda9fdca5431e4e7911bb3171e36088a861eTyler Luu        mFramesWithCameraAdapterMap.removeItem((int) mGrallocHandleMap[i]);
6618e88af31129b8cc09675279ca2eac88256d8526bAkwasi Boateng        //LOCK UNLOCK TO GET YUV POINTERS
6628e88af31129b8cc09675279ca2eac88256d8526bAkwasi Boateng        void *y_uv[2];
6638e88af31129b8cc09675279ca2eac88256d8526bAkwasi Boateng        mapper.lock((buffer_handle_t) mGrallocHandleMap[i], CAMHAL_GRALLOC_USAGE, bounds, y_uv);
6648e88af31129b8cc09675279ca2eac88256d8526bAkwasi Boateng        mFrameProvider->addFramePointers(mGrallocHandleMap[i] , y_uv);
6658e88af31129b8cc09675279ca2eac88256d8526bAkwasi Boateng        mapper.unlock((buffer_handle_t) mGrallocHandleMap[i]);
666c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
667c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
668c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mFirstInit = true;
669c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mPixelFormat = getPixFormatConstant(format);
670c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mFrameWidth = width;
671c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mFrameHeight = height;
672c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
673c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    return mGrallocHandleMap;
674c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
675c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev fail:
676c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    // need to cancel buffers if any were dequeued
677c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    for (int start = 0; start < i && i > 0; start++) {
678c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        int err = mANativeWindow->cancel_buffer(mANativeWindow, mBufferHandleMap[start]);
679c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        if (err != 0) {
680c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev          CAMHAL_LOGEB("cancelBuffer failed w/ error 0x%08x", err);
6817702898343dbb27a4543c642d189cff5de7046c9Sundar Raman          break;
682c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
6836c73fda9fdca5431e4e7911bb3171e36088a861eTyler Luu        mFramesWithCameraAdapterMap.removeItem((int) mGrallocHandleMap[start]);
684c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
68588006b1ebee79cb0f1a2c682258b313eb801049dSundar Raman
68688006b1ebee79cb0f1a2c682258b313eb801049dSundar Raman    freeBuffer(mGrallocHandleMap);
68788006b1ebee79cb0f1a2c682258b313eb801049dSundar Raman
688c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    CAMHAL_LOGEA("Error occurred, performing cleanup");
689c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
690c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( NULL != mErrorNotifier.get() )
691c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
692c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mErrorNotifier->errorNotify(-ENOMEM);
693c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
694c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
695c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
696c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    return NULL;
697c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
698c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
699c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
700c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevuint32_t * ANativeWindowDisplayAdapter::getOffsets()
701c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
702c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    const int lnumBufs = mBufferCount;
703c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
704c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
705c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
706c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    // TODO(XXX): Need to remove getOffsets from the API. No longer needed
707c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
708c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( NULL == mANativeWindow )
709c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    {
710c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        CAMHAL_LOGEA("mANativeWindow reference is missing");
711c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        goto fail;
712c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
713c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
714c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if( mBufferHandleMap == NULL)
715c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    {
716c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        CAMHAL_LOGEA("Buffers not allocated yet!!");
717c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        goto fail;
718c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
719c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
720c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if(mOffsetsMap == NULL)
721c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    {
722c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mOffsetsMap = new uint32_t[lnumBufs];
723c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        for(int i = 0; i < mBufferCount; i++)
724c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
725c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            IMG_native_handle_t* handle =  (IMG_native_handle_t*) *(mBufferHandleMap[i]);
726c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            mOffsetsMap[i] = 0;
727c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
728c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
729c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
730c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
731c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
732c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    return mOffsetsMap;
733c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
734c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev fail:
735c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
736c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( NULL != mOffsetsMap )
737c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    {
738c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        delete [] mOffsetsMap;
739c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mOffsetsMap = NULL;
740c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
741c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
742c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( NULL != mErrorNotifier.get() )
743c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    {
744c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mErrorNotifier->errorNotify(-ENOSYS);
745c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
746c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
747c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
748c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
749c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    return NULL;
750c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
751c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
752c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevint ANativeWindowDisplayAdapter::maxQueueableBuffers(unsigned int& queueable)
753c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
754c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
755c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    int ret = NO_ERROR;
756c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    int undequeued = 0;
757c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
758c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if(mBufferCount == 0)
759c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    {
760c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        ret = -ENOSYS;
761c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        goto end;
762c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
763c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
764c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if(!mANativeWindow)
765c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    {
766c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        ret = -ENOSYS;
767c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        goto end;
768c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
769c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
7707702898343dbb27a4543c642d189cff5de7046c9Sundar Raman    ret = mANativeWindow->get_min_undequeued_buffer_count(mANativeWindow, &undequeued);
7717702898343dbb27a4543c642d189cff5de7046c9Sundar Raman    if ( NO_ERROR != ret ) {
7727702898343dbb27a4543c642d189cff5de7046c9Sundar Raman        CAMHAL_LOGEB("get_min_undequeued_buffer_count failed: %s (%d)", strerror(-ret), -ret);
7737702898343dbb27a4543c642d189cff5de7046c9Sundar Raman
7747702898343dbb27a4543c642d189cff5de7046c9Sundar Raman        if ( ENODEV == ret ) {
7757702898343dbb27a4543c642d189cff5de7046c9Sundar Raman            CAMHAL_LOGEA("Preview surface abandoned!");
7767702898343dbb27a4543c642d189cff5de7046c9Sundar Raman            mANativeWindow = NULL;
7777702898343dbb27a4543c642d189cff5de7046c9Sundar Raman        }
7787702898343dbb27a4543c642d189cff5de7046c9Sundar Raman
7797702898343dbb27a4543c642d189cff5de7046c9Sundar Raman        return -ret;
7807702898343dbb27a4543c642d189cff5de7046c9Sundar Raman    }
781c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
782c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    queueable = mBufferCount - undequeued;
783c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
784c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev end:
785c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    return ret;
786c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
787c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
788c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
789c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevint ANativeWindowDisplayAdapter::getFd()
790c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
791c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
792c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
793c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if(mFD == -1)
794c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    {
795c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        IMG_native_handle_t* handle =  (IMG_native_handle_t*) *(mBufferHandleMap[0]);
796c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        // TODO: should we dup the fd? not really necessary and another thing for ANativeWindow
797c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        // to manage and close...
798c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mFD = dup(handle->fd[0]);
799c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
800c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
801c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
802c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
803c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    return mFD;
804c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
805c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
806c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
807b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Ramanstatus_t ANativeWindowDisplayAdapter::returnBuffersToWindow()
808b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman{
809b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman    status_t ret = NO_ERROR;
810b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman
811b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman     GraphicBufferMapper &mapper = GraphicBufferMapper::get();
812b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman    //Give the buffers back to display here -  sort of free it
813b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman     if (mANativeWindow)
814b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman         for(unsigned int i = 0; i < mFramesWithCameraAdapterMap.size(); i++) {
815b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman             int value = mFramesWithCameraAdapterMap.valueAt(i);
816b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman
817b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman             // unlock buffer before giving it up
818b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman             mapper.unlock((buffer_handle_t) mGrallocHandleMap[value]);
819b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman
820b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman             ret = mANativeWindow->cancel_buffer(mANativeWindow, mBufferHandleMap[value]);
821b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman             if ( ENODEV == ret ) {
822b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman                 CAMHAL_LOGEA("Preview surface abandoned!");
823b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman                 mANativeWindow = NULL;
824b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman                 return -ret;
825b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman             } else if ( NO_ERROR != ret ) {
826b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman                 CAMHAL_LOGEB("cancel_buffer() failed: %s (%d)",
827b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman                              strerror(-ret),
828b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman                              -ret);
829b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman                return -ret;
830b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman             }
831b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman         }
832b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman     else
83346de639b23db99d7b99ff1c676ac98b84b6336c6Steve Block         ALOGE("mANativeWindow is NULL");
834b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman
835b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman     ///Clear the frames with camera adapter map
836b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman     mFramesWithCameraAdapterMap.clear();
837b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman
838b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman     return ret;
839b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman
840b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman}
841b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman
842c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevint ANativeWindowDisplayAdapter::freeBuffer(void* buf)
843c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
844c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
845c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
846c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    int *buffers = (int *) buf;
847b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman    status_t ret = NO_ERROR;
848b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman
849b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman    Mutex::Autolock lock(mLock);
850b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman
851c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if((int *)mGrallocHandleMap != buffers)
852c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    {
853c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        CAMHAL_LOGEA("CameraHal passed wrong set of buffers to free!!!");
854c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        if (mGrallocHandleMap != NULL)
855c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            delete []mGrallocHandleMap;
856c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mGrallocHandleMap = NULL;
857c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
858c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
859b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman
860b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman    returnBuffersToWindow();
861b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman
862c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( NULL != buf )
863c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    {
864c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        delete [] buffers;
865348e4eaaf2f88810f2a3c55fd1b0df540a5104edTyler Luu        mGrallocHandleMap = NULL;
866c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
867c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
868c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if( mBufferHandleMap != NULL)
869c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    {
870c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        delete [] mBufferHandleMap;
871c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mBufferHandleMap = NULL;
872c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
873c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
874c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( NULL != mOffsetsMap )
875c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    {
876c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        delete [] mOffsetsMap;
877c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mOffsetsMap = NULL;
878c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
879c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
880c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if( mFD != -1)
881c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    {
882c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        close(mFD);  // close duped handle
883c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mFD = -1;
884c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
885c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
886c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    return NO_ERROR;
887c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
888c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
889c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
890c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevbool ANativeWindowDisplayAdapter::supportsExternalBuffering()
891c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
892c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    return false;
893c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
894c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
895c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevint ANativeWindowDisplayAdapter::useBuffers(void *bufArr, int num)
896c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
897c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    return NO_ERROR;
898c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
899c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
900c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevvoid ANativeWindowDisplayAdapter::displayThread()
901c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
902c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    bool shouldLive = true;
903c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    int timeout = 0;
904c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    status_t ret;
905c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
906c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
907c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
908c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    while(shouldLive)
909c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
910c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        ret = TIUTILS::MessageQueue::waitForMsg(&mDisplayThread->msgQ()
911c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                                                                ,  &mDisplayQ
912c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                                                                , NULL
913c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                                                                , ANativeWindowDisplayAdapter::DISPLAY_TIMEOUT);
914c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
915c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        if ( !mDisplayThread->msgQ().isEmpty() )
916c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            {
917c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            ///Received a message from CameraHal, process it
918c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            shouldLive = processHalMsg();
919c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
920c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            }
921c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        else  if( !mDisplayQ.isEmpty())
922c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            {
923c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            if ( mDisplayState== ANativeWindowDisplayAdapter::DISPLAY_INIT )
924c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                {
925c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
926c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                ///If display adapter is not started, continue
927c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                continue;
928c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
929c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                }
930c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            else
931c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                {
932c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                TIUTILS::Message msg;
933c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                ///Get the dummy msg from the displayQ
934c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                if(mDisplayQ.get(&msg)!=NO_ERROR)
935c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    {
936c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    CAMHAL_LOGEA("Error in getting message from display Q");
937c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    continue;
938c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                }
939c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
940c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                // There is a frame from ANativeWindow for us to dequeue
941c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                // We dequeue and return the frame back to Camera adapter
942c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                if(mDisplayState == ANativeWindowDisplayAdapter::DISPLAY_STARTED)
943c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                {
944c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    handleFrameReturn();
945c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                }
946c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
947c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                if (mDisplayState == ANativeWindowDisplayAdapter::DISPLAY_EXITED)
948c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    {
949c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    ///we exit the thread even though there are frames still to dequeue. They will be dequeued
950c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    ///in disableDisplay
951c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    shouldLive = false;
952c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                }
953c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            }
954c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
955c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
956c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
957c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
958c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
959c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
960c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
961c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevbool ANativeWindowDisplayAdapter::processHalMsg()
962c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
963c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    TIUTILS::Message msg;
964c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
965c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
966c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
967c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
968c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mDisplayThread->msgQ().get(&msg);
969c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    bool ret = true, invalidCommand = false;
970c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
971c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    switch ( msg.command )
972c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
973c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
974c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        case DisplayThread::DISPLAY_START:
975c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
976c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            CAMHAL_LOGDA("Display thread received DISPLAY_START command from Camera HAL");
977c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            mDisplayState = ANativeWindowDisplayAdapter::DISPLAY_STARTED;
978c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
979c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            break;
980c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
981c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        case DisplayThread::DISPLAY_STOP:
982c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
983c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            ///@bug There is no API to disable SF without destroying it
984c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            ///@bug Buffers might still be w/ display and will get displayed
985c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            ///@remarks Ideal seqyence should be something like this
986c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            ///mOverlay->setParameter("enabled", false);
987c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            CAMHAL_LOGDA("Display thread received DISPLAY_STOP command from Camera HAL");
988c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            mDisplayState = ANativeWindowDisplayAdapter::DISPLAY_STOPPED;
989c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
990c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            break;
991c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
992c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        case DisplayThread::DISPLAY_EXIT:
993c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
994c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            CAMHAL_LOGDA("Display thread received DISPLAY_EXIT command from Camera HAL.");
995c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            CAMHAL_LOGDA("Stopping display thread...");
996c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            mDisplayState = ANativeWindowDisplayAdapter::DISPLAY_EXITED;
997c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            ///Note that the SF can have pending buffers when we disable the display
998c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            ///This is normal and the expectation is that they may not be displayed.
999c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            ///This is to ensure that the user experience is not impacted
1000c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            ret = false;
1001c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            break;
1002c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1003c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        default:
1004c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1005c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            CAMHAL_LOGEB("Invalid Display Thread Command 0x%x.", msg.command);
1006c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            invalidCommand = true;
1007c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1008c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            break;
1009c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
1010c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1011c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    ///Signal the semaphore if it is sent as part of the message
1012c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( ( msg.arg1 ) && ( !invalidCommand ) )
1013c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
1014c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1015c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        CAMHAL_LOGDA("+Signalling display semaphore");
1016c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        Semaphore &sem = *((Semaphore*)msg.arg1);
1017c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1018c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        sem.Signal();
1019c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1020c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        CAMHAL_LOGDA("-Signalling display semaphore");
1021c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
1022c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1023c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1024c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
1025c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    return ret;
1026c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
1027c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1028c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1029c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevstatus_t ANativeWindowDisplayAdapter::PostFrame(ANativeWindowDisplayAdapter::DisplayFrame &dispFrame)
1030c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
1031c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    status_t ret = NO_ERROR;
1032c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    uint32_t actualFramesWithDisplay = 0;
1033c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    android_native_buffer_t *buffer = NULL;
10346c73fda9fdca5431e4e7911bb3171e36088a861eTyler Luu    GraphicBufferMapper &mapper = GraphicBufferMapper::get();
1035c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    int i;
1036c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1037c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    ///@todo Do cropping based on the stabilized frame coordinates
1038c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    ///@todo Insert logic to drop frames here based on refresh rate of
1039c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    ///display or rendering rate whichever is lower
1040c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    ///Queue the buffer to overlay
1041348e4eaaf2f88810f2a3c55fd1b0df540a5104edTyler Luu
1042348e4eaaf2f88810f2a3c55fd1b0df540a5104edTyler Luu    if (!mGrallocHandleMap || !dispFrame.mBuffer) {
1043348e4eaaf2f88810f2a3c55fd1b0df540a5104edTyler Luu        CAMHAL_LOGEA("NULL sent to PostFrame");
1044348e4eaaf2f88810f2a3c55fd1b0df540a5104edTyler Luu        return -EINVAL;
1045348e4eaaf2f88810f2a3c55fd1b0df540a5104edTyler Luu    }
1046348e4eaaf2f88810f2a3c55fd1b0df540a5104edTyler Luu
1047c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    for ( i = 0; i < mBufferCount; i++ )
1048c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
1049c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        if ( ((int) dispFrame.mBuffer ) == (int)mGrallocHandleMap[i] )
1050c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            {
1051c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            break;
1052c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
1053c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
1054c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1055c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( mDisplayState == ANativeWindowDisplayAdapter::DISPLAY_STARTED &&
1056c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                (!mPaused ||  CameraFrame::CameraFrame::SNAPSHOT_FRAME == dispFrame.mType) &&
1057c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                !mSuspend)
1058c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    {
1059c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        Mutex::Autolock lock(mLock);
1060c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        uint32_t xOff = (dispFrame.mOffset% PAGE_SIZE);
1061c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        uint32_t yOff = (dispFrame.mOffset / PAGE_SIZE);
1062c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1063c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        // Set crop only if current x and y offsets do not match with frame offsets
1064c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        if((mXOff!=xOff) || (mYOff!=yOff))
1065c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
1066c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            CAMHAL_LOGDB("Offset %d xOff = %d, yOff = %d", dispFrame.mOffset, xOff, yOff);
1067c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            uint8_t bytesPerPixel;
1068c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            ///Calculate bytes per pixel based on the pixel format
1069c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            if(strcmp(mPixelFormat, (const char *) CameraParameters::PIXEL_FORMAT_YUV422I) == 0)
1070c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                {
1071c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                bytesPerPixel = 2;
1072c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                }
1073c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            else if(strcmp(mPixelFormat, (const char *) CameraParameters::PIXEL_FORMAT_RGB565) == 0)
1074c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                {
1075c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                bytesPerPixel = 2;
1076c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                }
1077c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            else if(strcmp(mPixelFormat, (const char *) CameraParameters::PIXEL_FORMAT_YUV420SP) == 0)
1078c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                {
1079c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                bytesPerPixel = 1;
1080c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                }
1081c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            else
1082c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                {
1083c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                bytesPerPixel = 1;
1084c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            }
1085c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1086c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            CAMHAL_LOGVB(" crop.left = %d crop.top = %d crop.right = %d crop.bottom = %d",
1087c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                          xOff/bytesPerPixel, yOff , (xOff/bytesPerPixel)+mPreviewWidth, yOff+mPreviewHeight);
1088c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            // We'll ignore any errors here, if the surface is
1089c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            // already invalid, we'll know soon enough.
1090c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            mANativeWindow->set_crop(mANativeWindow, xOff/bytesPerPixel, yOff,
1091c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                                     (xOff/bytesPerPixel)+mPreviewWidth, yOff+mPreviewHeight);
1092c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1093c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            ///Update the current x and y offsets
1094c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            mXOff = xOff;
1095c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            mYOff = yOff;
1096c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
1097c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
10986c73fda9fdca5431e4e7911bb3171e36088a861eTyler Luu        // unlock buffer before sending to display
10996c73fda9fdca5431e4e7911bb3171e36088a861eTyler Luu        mapper.unlock((buffer_handle_t) mGrallocHandleMap[i]);
1100c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        ret = mANativeWindow->enqueue_buffer(mANativeWindow, mBufferHandleMap[i]);
1101c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        if (ret != 0) {
110246de639b23db99d7b99ff1c676ac98b84b6336c6Steve Block            ALOGE("Surface::queueBuffer returned error %d", ret);
1103c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
1104c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1105c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mFramesWithCameraAdapterMap.removeItem((int) dispFrame.mBuffer);
1106c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1107c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1108c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        // HWComposer has not minimum buffer requirement. We should be able to dequeue
1109c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        // the buffer immediately
1110c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        TIUTILS::Message msg;
1111c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mDisplayQ.put(&msg);
1112c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1113c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1114c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
1115c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1116c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        if ( mMeasureStandby )
1117c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            {
1118c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            CameraHal::PPM("Standby to first shot: Sensor Change completed - ", &mStandbyToShot);
1119c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            mMeasureStandby = false;
1120c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            }
1121c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        else if (CameraFrame::CameraFrame::SNAPSHOT_FRAME == dispFrame.mType)
1122c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            {
1123c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            CameraHal::PPM("Shot to snapshot: ", &mStartCapture);
1124c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            mShotToShot = true;
1125c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            }
1126c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        else if ( mShotToShot )
1127c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            {
1128c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            CameraHal::PPM("Shot to shot: ", &mStartCapture);
1129c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            mShotToShot = false;
1130c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
1131c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#endif
1132c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1133c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
1134c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    else
1135c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    {
1136c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        Mutex::Autolock lock(mLock);
11376c73fda9fdca5431e4e7911bb3171e36088a861eTyler Luu
11386c73fda9fdca5431e4e7911bb3171e36088a861eTyler Luu        // unlock buffer before giving it up
11396c73fda9fdca5431e4e7911bb3171e36088a861eTyler Luu        mapper.unlock((buffer_handle_t) mGrallocHandleMap[i]);
11406c73fda9fdca5431e4e7911bb3171e36088a861eTyler Luu
1141c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        // cancel buffer and dequeue another one
1142c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        ret = mANativeWindow->cancel_buffer(mANativeWindow, mBufferHandleMap[i]);
1143c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        if (ret != 0) {
114446de639b23db99d7b99ff1c676ac98b84b6336c6Steve Block            ALOGE("Surface::queueBuffer returned error %d", ret);
1145c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
1146c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1147c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mFramesWithCameraAdapterMap.removeItem((int) dispFrame.mBuffer);
1148c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1149c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        TIUTILS::Message msg;
1150c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mDisplayQ.put(&msg);
1151c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        ret = NO_ERROR;
1152c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
1153c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1154c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    return ret;
1155c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
1156c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1157c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1158c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevbool ANativeWindowDisplayAdapter::handleFrameReturn()
1159c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
1160c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    status_t err;
1161c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    buffer_handle_t* buf;
1162c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    int i = 0;
1163c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    int stride;  // dummy variable to get stride
11646c73fda9fdca5431e4e7911bb3171e36088a861eTyler Luu    GraphicBufferMapper &mapper = GraphicBufferMapper::get();
11656c73fda9fdca5431e4e7911bb3171e36088a861eTyler Luu    Rect bounds;
11666c73fda9fdca5431e4e7911bb3171e36088a861eTyler Luu    void *y_uv[2];
11676c73fda9fdca5431e4e7911bb3171e36088a861eTyler Luu
1168c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    // TODO(XXX): Do we need to keep stride information in camera hal?
1169c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
11707702898343dbb27a4543c642d189cff5de7046c9Sundar Raman    if ( NULL == mANativeWindow ) {
11717702898343dbb27a4543c642d189cff5de7046c9Sundar Raman        return false;
11727702898343dbb27a4543c642d189cff5de7046c9Sundar Raman    }
11737702898343dbb27a4543c642d189cff5de7046c9Sundar Raman
1174c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    err = mANativeWindow->dequeue_buffer(mANativeWindow, &buf, &stride);
1175c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if (err != 0) {
1176c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        CAMHAL_LOGEB("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
11777702898343dbb27a4543c642d189cff5de7046c9Sundar Raman
11787702898343dbb27a4543c642d189cff5de7046c9Sundar Raman        if ( ENODEV == err ) {
11797702898343dbb27a4543c642d189cff5de7046c9Sundar Raman            CAMHAL_LOGEA("Preview surface abandoned!");
11807702898343dbb27a4543c642d189cff5de7046c9Sundar Raman            mANativeWindow = NULL;
11817702898343dbb27a4543c642d189cff5de7046c9Sundar Raman        }
11827702898343dbb27a4543c642d189cff5de7046c9Sundar Raman
11837702898343dbb27a4543c642d189cff5de7046c9Sundar Raman        return false;
1184c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
1185c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1186c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    err = mANativeWindow->lock_buffer(mANativeWindow, buf);
1187c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if (err != 0) {
1188c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        CAMHAL_LOGEB("lockbuffer failed: %s (%d)", strerror(-err), -err);
11897702898343dbb27a4543c642d189cff5de7046c9Sundar Raman
11907702898343dbb27a4543c642d189cff5de7046c9Sundar Raman        if ( ENODEV == err ) {
11917702898343dbb27a4543c642d189cff5de7046c9Sundar Raman            CAMHAL_LOGEA("Preview surface abandoned!");
11927702898343dbb27a4543c642d189cff5de7046c9Sundar Raman            mANativeWindow = NULL;
11937702898343dbb27a4543c642d189cff5de7046c9Sundar Raman        }
11947702898343dbb27a4543c642d189cff5de7046c9Sundar Raman
11957702898343dbb27a4543c642d189cff5de7046c9Sundar Raman        return false;
1196c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
1197c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1198c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    for(i = 0; i < mBufferCount; i++)
1199c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    {
1200c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        if (mBufferHandleMap[i] == buf)
1201c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            break;
1202c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
1203c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
12046c73fda9fdca5431e4e7911bb3171e36088a861eTyler Luu    // lock buffer before sending to FrameProvider for filling
12056c73fda9fdca5431e4e7911bb3171e36088a861eTyler Luu    bounds.left = 0;
12066c73fda9fdca5431e4e7911bb3171e36088a861eTyler Luu    bounds.top = 0;
12076c73fda9fdca5431e4e7911bb3171e36088a861eTyler Luu    bounds.right = mFrameWidth;
12086c73fda9fdca5431e4e7911bb3171e36088a861eTyler Luu    bounds.bottom = mFrameHeight;
12098e88af31129b8cc09675279ca2eac88256d8526bAkwasi Boateng
12108e88af31129b8cc09675279ca2eac88256d8526bAkwasi Boateng    int lock_try_count = 0;
12118e88af31129b8cc09675279ca2eac88256d8526bAkwasi Boateng    while (mapper.lock((buffer_handle_t) mGrallocHandleMap[i], CAMHAL_GRALLOC_USAGE, bounds, y_uv) < 0){
12128e88af31129b8cc09675279ca2eac88256d8526bAkwasi Boateng      if (++lock_try_count > LOCK_BUFFER_TRIES){
12138e88af31129b8cc09675279ca2eac88256d8526bAkwasi Boateng        if ( NULL != mErrorNotifier.get() ){
12148e88af31129b8cc09675279ca2eac88256d8526bAkwasi Boateng          mErrorNotifier->errorNotify(CAMERA_ERROR_UNKNOWN);
12158e88af31129b8cc09675279ca2eac88256d8526bAkwasi Boateng        }
12168e88af31129b8cc09675279ca2eac88256d8526bAkwasi Boateng        return false;
12178e88af31129b8cc09675279ca2eac88256d8526bAkwasi Boateng      }
12188e88af31129b8cc09675279ca2eac88256d8526bAkwasi Boateng      CAMHAL_LOGEA("Gralloc Lock FrameReturn Error: Sleeping 15ms");
12198e88af31129b8cc09675279ca2eac88256d8526bAkwasi Boateng      usleep(15000);
12208e88af31129b8cc09675279ca2eac88256d8526bAkwasi Boateng    }
12216c73fda9fdca5431e4e7911bb3171e36088a861eTyler Luu
1222c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mFramesWithCameraAdapterMap.add((int) mGrallocHandleMap[i], i);
1223c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1224c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    CAMHAL_LOGVB("handleFrameReturn: found graphic buffer %d of %d", i, mBufferCount-1);
1225c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mFrameProvider->returnFrame( (void*)mGrallocHandleMap[i], CameraFrame::PREVIEW_FRAME_SYNC);
1226c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    return true;
1227c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
1228c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1229c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevvoid ANativeWindowDisplayAdapter::frameCallbackRelay(CameraFrame* caFrame)
1230c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
1231c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1232c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( NULL != caFrame )
1233c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
1234c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        if ( NULL != caFrame->mCookie )
1235c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            {
1236c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            ANativeWindowDisplayAdapter *da = (ANativeWindowDisplayAdapter*) caFrame->mCookie;
1237c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            da->frameCallback(caFrame);
1238c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
1239c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        else
1240c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            {
1241c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            CAMHAL_LOGEB("Invalid Cookie in Camera Frame = %p, Cookie = %p", caFrame, caFrame->mCookie);
1242c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            }
1243c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
1244c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    else
1245c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
1246c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        CAMHAL_LOGEB("Invalid Camera Frame = %p", caFrame);
1247c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
1248c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1249c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
1250c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1251c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevvoid ANativeWindowDisplayAdapter::frameCallback(CameraFrame* caFrame)
1252c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
1253c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    ///Call queueBuffer of overlay in the context of the callback thread
1254c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    DisplayFrame df;
1255c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    df.mBuffer = caFrame->mBuffer;
1256c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    df.mType = (CameraFrame::FrameType) caFrame->mFrameType;
1257c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    df.mOffset = caFrame->mOffset;
1258c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    df.mWidthStride = caFrame->mAlignment;
1259c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    df.mLength = caFrame->mLength;
1260c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    df.mWidth = caFrame->mWidth;
1261c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    df.mHeight = caFrame->mHeight;
1262c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    PostFrame(df);
1263c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
1264c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1265c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1266c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev/*--------------------ANativeWindowDisplayAdapter Class ENDS here-----------------------------*/
1267c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1268c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev};
1269c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1270