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#include "ANativeWindowDisplayAdapter.h"
18c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#include <OMX_IVCommon.h>
196c73fda9fdca5431e4e7911bb3171e36088a861eTyler Luu#include <ui/GraphicBuffer.h>
20c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#include <ui/GraphicBufferMapper.h>
21c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#include <hal_public.h>
22c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
23f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmonsnamespace Ti {
24f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmonsnamespace Camera {
25c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
26c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev///Constant declarations
27c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev///@todo Check the time units
28c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevconst int ANativeWindowDisplayAdapter::DISPLAY_TIMEOUT = 1000;  // seconds
29c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
30c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev//Suspends buffers after given amount of failed dq's
31c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevconst int ANativeWindowDisplayAdapter::FAILED_DQS_TO_SUSPEND = 3;
32c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
33c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
34c322989ae6ff6769490828de1b5eda12b749cce9Iliyan MalchevOMX_COLOR_FORMATTYPE toOMXPixFormat(const char* parameters_format)
35c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
36c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    OMX_COLOR_FORMATTYPE pixFormat;
37c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
38c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( parameters_format != NULL )
39c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    {
40f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        if (strcmp(parameters_format, android::CameraParameters::PIXEL_FORMAT_YUV422I) == 0)
41c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            {
42c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            CAMHAL_LOGDA("CbYCrY format selected");
43c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            pixFormat = OMX_COLOR_FormatCbYCrY;
44c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            }
45f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        else if(strcmp(parameters_format, android::CameraParameters::PIXEL_FORMAT_YUV420SP) == 0)
46c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            {
47c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            CAMHAL_LOGDA("YUV420SP format selected");
48c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            pixFormat = OMX_COLOR_FormatYUV420SemiPlanar;
49c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            }
50f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        else if(strcmp(parameters_format, android::CameraParameters::PIXEL_FORMAT_RGB565) == 0)
51c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            {
52c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            CAMHAL_LOGDA("RGB565 format selected");
53c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            pixFormat = OMX_COLOR_Format16bitRGB565;
54c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            }
55c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        else
56c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            {
57f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            CAMHAL_LOGDA("Invalid format, NV12 format selected as default");
58f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            pixFormat = OMX_COLOR_FormatYUV420SemiPlanar;
59c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
60c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
61c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    else {
62f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        CAMHAL_LOGEA("Preview format is NULL, defaulting to NV12");
63f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        pixFormat = OMX_COLOR_FormatYUV420SemiPlanar;
64c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
65c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
66c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    return pixFormat;
67c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
68c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
69c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev/*--------------------ANativeWindowDisplayAdapter Class STARTS here-----------------------------*/
70c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
71c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
72c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev/**
73c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * Display Adapter class STARTS here..
74c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev */
75c322989ae6ff6769490828de1b5eda12b749cce9Iliyan MalchevANativeWindowDisplayAdapter::ANativeWindowDisplayAdapter():mDisplayThread(NULL),
76c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                                        mDisplayState(ANativeWindowDisplayAdapter::DISPLAY_INIT),
77c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                                        mDisplayEnabled(false),
78c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                                        mBufferCount(0)
79c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
80c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
81c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
82c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
83c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
84c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
85c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
86c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
87c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mShotToShot = false;
88c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mStartCapture.tv_sec = 0;
89c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mStartCapture.tv_usec = 0;
90c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mStandbyToShot.tv_sec = 0;
91c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mStandbyToShot.tv_usec = 0;
92c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mMeasureStandby = false;
93c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#endif
94c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
95c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mPixelFormat = NULL;
96f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    mBuffers = NULL;
97c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mOffsetsMap = NULL;
98c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mFrameProvider = NULL;
997702898343dbb27a4543c642d189cff5de7046c9Sundar Raman    mANativeWindow = NULL;
100c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
101c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mFrameWidth = 0;
102c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mFrameHeight = 0;
103c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mPreviewWidth = 0;
104c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mPreviewHeight = 0;
105c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
106c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mSuspend = false;
107c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mFailedDQs = 0;
108c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
109c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mPaused = false;
110130ed815e4cea7c2906a1e1f0d665c2f94b690f5Akwasi Boateng    mXOff = -1;
111130ed815e4cea7c2906a1e1f0d665c2f94b690f5Akwasi Boateng    mYOff = -1;
112c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mFirstInit = false;
113c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
114c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mFD = -1;
115c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
116c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
117c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
118c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
119c322989ae6ff6769490828de1b5eda12b749cce9Iliyan MalchevANativeWindowDisplayAdapter::~ANativeWindowDisplayAdapter()
120c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
121f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    Utils::Semaphore sem;
122f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    Utils::Message msg;
123c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
124c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
125c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
126c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    ///If Frame provider exists
12797e6bcc45eb2161c10761abc4fbf12ce3e1d52c8Tyler Luu    if (mFrameProvider) {
128c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        // Unregister with the frame provider
129c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mFrameProvider->disableFrameNotification(CameraFrame::ALL_FRAMES);
13097e6bcc45eb2161c10761abc4fbf12ce3e1d52c8Tyler Luu        delete mFrameProvider;
131c493114006e0e136c8c88c2fc9865994054959bfSundar Raman        mFrameProvider = NULL;
132c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
133c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
134c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    ///The ANativeWindow object will get destroyed here
135c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    destroy();
136c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
137c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    ///If Display thread exists
138c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if(mDisplayThread.get())
139c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
140c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        ///Kill the display thread
141c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        sem.Create();
142c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        msg.command = DisplayThread::DISPLAY_EXIT;
143c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
144c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        // Send the semaphore to signal once the command is completed
145c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        msg.arg1 = &sem;
146c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
147c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        ///Post the message to display thread
148c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mDisplayThread->msgQ().put(&msg);
149c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
150c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        ///Wait for the ACK - implies that the thread is now started and waiting for frames
151c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        sem.Wait();
152c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
153c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        // Exit and cleanup the thread
154c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mDisplayThread->requestExitAndWait();
155c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
156c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        // Delete the display thread
157c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mDisplayThread.clear();
158c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
159c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
160c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
161c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
162c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
163c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
164c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevstatus_t ANativeWindowDisplayAdapter::initialize()
165c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
166c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
167c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
168c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    ///Create the display thread
169c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mDisplayThread = new DisplayThread(this);
170c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( !mDisplayThread.get() )
171c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
172c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        CAMHAL_LOGEA("Couldn't create display thread");
173c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        LOG_FUNCTION_NAME_EXIT;
174c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        return NO_MEMORY;
175c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
176c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
177c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    ///Start the display thread
178f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    status_t ret = mDisplayThread->run("DisplayThread", android::PRIORITY_URGENT_DISPLAY);
179c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( ret != NO_ERROR )
180c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
181c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        CAMHAL_LOGEA("Couldn't run display thread");
182c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        LOG_FUNCTION_NAME_EXIT;
183c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        return ret;
184c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
185c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
186c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
187c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
188c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    return ret;
189c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
190c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
191c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevint ANativeWindowDisplayAdapter::setPreviewWindow(preview_stream_ops_t* window)
192c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
193c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
194c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    ///Note that Display Adapter cannot work without a valid window object
195c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( !window)
196c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
197c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        CAMHAL_LOGEA("NULL window object passed to DisplayAdapter");
198c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        LOG_FUNCTION_NAME_EXIT;
199c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        return BAD_VALUE;
200c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
201c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
20239371f31292f050f7fd75f7d36c7c9eeffd4ae64Tyler Luu    if ( window == mANativeWindow ) {
20339371f31292f050f7fd75f7d36c7c9eeffd4ae64Tyler Luu        return ALREADY_EXISTS;
20439371f31292f050f7fd75f7d36c7c9eeffd4ae64Tyler Luu    }
20539371f31292f050f7fd75f7d36c7c9eeffd4ae64Tyler Luu
206c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    ///Destroy the existing window object, if it exists
207c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    destroy();
208c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
209c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    ///Move to new window obj
210c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mANativeWindow = window;
211c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
212c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
213c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
214c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    return NO_ERROR;
215c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
216c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
217c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevint ANativeWindowDisplayAdapter::setFrameProvider(FrameNotifier *frameProvider)
218c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
219c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
220c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
221c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    // Check for NULL pointer
22297e6bcc45eb2161c10761abc4fbf12ce3e1d52c8Tyler Luu    if ( !frameProvider ) {
223c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        CAMHAL_LOGEA("NULL passed for frame provider");
224c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        LOG_FUNCTION_NAME_EXIT;
225c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        return BAD_VALUE;
226c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
227c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
22897e6bcc45eb2161c10761abc4fbf12ce3e1d52c8Tyler Luu    //Release any previous frame providers
22997e6bcc45eb2161c10761abc4fbf12ce3e1d52c8Tyler Luu    if ( NULL != mFrameProvider ) {
23097e6bcc45eb2161c10761abc4fbf12ce3e1d52c8Tyler Luu        delete mFrameProvider;
23197e6bcc45eb2161c10761abc4fbf12ce3e1d52c8Tyler Luu    }
23297e6bcc45eb2161c10761abc4fbf12ce3e1d52c8Tyler Luu
233c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    /** Dont do anything here, Just save the pointer for use when display is
234c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev         actually enabled or disabled
235c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    */
236c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mFrameProvider = new FrameProvider(frameProvider, this, frameCallbackRelay);
237c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
238c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
239c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
240c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    return NO_ERROR;
241c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
242c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
243c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevint ANativeWindowDisplayAdapter::setErrorHandler(ErrorNotifier *errorNotifier)
244c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
245c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    status_t ret = NO_ERROR;
246c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
247c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
248c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
249f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if ( NULL == errorNotifier ) {
250c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        CAMHAL_LOGEA("Invalid Error Notifier reference");
251f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        ret = BAD_VALUE;
252c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
253c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
254c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( NO_ERROR == ret )
255c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
256c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mErrorNotifier = errorNotifier;
257c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
258c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
259c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
260c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
261c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    return ret;
262c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
263c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
264c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
265c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
266c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevstatus_t ANativeWindowDisplayAdapter::setSnapshotTimeRef(struct timeval *refTime)
267c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
268c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    status_t ret = NO_ERROR;
269c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
270c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
271c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
272c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( NULL != refTime )
273c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
274f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        android::AutoMutex lock(mLock);
275c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        memcpy(&mStartCapture, refTime, sizeof(struct timeval));
276c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
277c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
278c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
279c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
280c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    return ret;
281c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
282c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
283c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#endif
284c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
285c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
286f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmonsint ANativeWindowDisplayAdapter::enableDisplay(int width, int height, struct timeval *refTime)
287c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
288f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    Utils::Semaphore sem;
289f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    Utils::Message msg;
290c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
291c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
292c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
293c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( mDisplayEnabled )
294c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
295c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        CAMHAL_LOGDA("Display is already enabled");
296c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        LOG_FUNCTION_NAME_EXIT;
297c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
298c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        return NO_ERROR;
299c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
300c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
301c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
302c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
303c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( NULL != refTime )
304c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
305f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        android::AutoMutex lock(mLock);
306c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        memcpy(&mStandbyToShot, refTime, sizeof(struct timeval));
307c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mMeasureStandby = true;
308c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
309c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
310c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#endif
311c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
312c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    //Send START_DISPLAY COMMAND to display thread. Display thread will start and then wait for a message
313c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    sem.Create();
314c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    msg.command = DisplayThread::DISPLAY_START;
315c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
316c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    // Send the semaphore to signal once the command is completed
317c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    msg.arg1 = &sem;
318c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
319c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    ///Post the message to display thread
320c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mDisplayThread->msgQ().put(&msg);
321c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
322c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    ///Wait for the ACK - implies that the thread is now started and waiting for frames
323c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    sem.Wait();
324c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
325c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    // Register with the frame provider for frames
326c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mFrameProvider->enableFrameNotification(CameraFrame::PREVIEW_FRAME_SYNC);
327f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    mFrameProvider->enableFrameNotification(CameraFrame::SNAPSHOT_FRAME);
328c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
329c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mDisplayEnabled = true;
330c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mPreviewWidth = width;
331c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mPreviewHeight = height;
332c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
333c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    CAMHAL_LOGVB("mPreviewWidth = %d mPreviewHeight = %d", mPreviewWidth, mPreviewHeight);
334c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
335c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
336c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
337c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    return NO_ERROR;
338c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
339c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
340816f63fd6a78b45e18819d9967d409c212c88eaeSundar Ramanint ANativeWindowDisplayAdapter::disableDisplay(bool cancel_buffer)
341c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
3427702898343dbb27a4543c642d189cff5de7046c9Sundar Raman    status_t ret = NO_ERROR;
343f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    android::GraphicBufferMapper &mapper = android::GraphicBufferMapper::get();
3447702898343dbb27a4543c642d189cff5de7046c9Sundar Raman
345c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
346c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
347c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if(!mDisplayEnabled)
348c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
349c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        CAMHAL_LOGDA("Display is already disabled");
350c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        LOG_FUNCTION_NAME_EXIT;
351c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        return ALREADY_EXISTS;
352c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
353c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
354c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    // Unregister with the frame provider here
355c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mFrameProvider->disableFrameNotification(CameraFrame::PREVIEW_FRAME_SYNC);
356f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    mFrameProvider->disableFrameNotification(CameraFrame::SNAPSHOT_FRAME);
3578e88af31129b8cc09675279ca2eac88256d8526bAkwasi Boateng    mFrameProvider->removeFramePointers();
358c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
359c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( NULL != mDisplayThread.get() )
360c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
361c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        //Send STOP_DISPLAY COMMAND to display thread. Display thread will stop and dequeue all messages
362c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        // and then wait for message
363f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        Utils::Semaphore sem;
364c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        sem.Create();
365f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        Utils::Message msg;
366c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        msg.command = DisplayThread::DISPLAY_STOP;
367c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
368c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        // Send the semaphore to signal once the command is completed
369c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        msg.arg1 = &sem;
370c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
371c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        ///Post the message to display thread
372c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mDisplayThread->msgQ().put(&msg);
373c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
374c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        ///Wait for the ACK for display to be disabled
375c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
376c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        sem.Wait();
377c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
378c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
379c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
380f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    android::AutoMutex lock(mLock);
381c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    {
382c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        ///Reset the display enabled flag
383c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mDisplayEnabled = false;
384c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
385f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        // Reset pause flag since display is being disabled
386f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        mPaused = false;
387f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
388c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        ///Reset the offset values
389130ed815e4cea7c2906a1e1f0d665c2f94b690f5Akwasi Boateng        mXOff = -1;
390130ed815e4cea7c2906a1e1f0d665c2f94b690f5Akwasi Boateng        mYOff = -1;
391c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
392c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        ///Reset the frame width and height values
393c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mFrameWidth =0;
394c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mFrameHeight = 0;
395c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mPreviewWidth = 0;
396c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mPreviewHeight = 0;
397c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
398816f63fd6a78b45e18819d9967d409c212c88eaeSundar Raman       if(cancel_buffer)
399816f63fd6a78b45e18819d9967d409c212c88eaeSundar Raman        {
400b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman        // Return the buffers to ANativeWindow here, the mFramesWithCameraAdapterMap is also cleared inside
401b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman        returnBuffersToWindow();
402816f63fd6a78b45e18819d9967d409c212c88eaeSundar Raman        }
403816f63fd6a78b45e18819d9967d409c212c88eaeSundar Raman       else
404816f63fd6a78b45e18819d9967d409c212c88eaeSundar Raman        {
405816f63fd6a78b45e18819d9967d409c212c88eaeSundar Raman        mANativeWindow = NULL;
406b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman        // Clear the frames with camera adapter map
407b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman        mFramesWithCameraAdapterMap.clear();
408816f63fd6a78b45e18819d9967d409c212c88eaeSundar Raman        }
409c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
410b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman
411c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
412c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
413c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
414c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    return NO_ERROR;
415c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
416c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
417c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevstatus_t ANativeWindowDisplayAdapter::pauseDisplay(bool pause)
418c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
419c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    status_t ret = NO_ERROR;
420c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
421c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
422c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
423c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    {
424f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        android::AutoMutex lock(mLock);
425c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mPaused = pause;
426c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
427c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
428c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
429c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
430c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    return ret;
431c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
432c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
433c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
434c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevvoid ANativeWindowDisplayAdapter::destroy()
435c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
436c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
437c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
438c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    ///Check if the display is disabled, if not disable it
439c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( mDisplayEnabled )
440c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    {
441c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        CAMHAL_LOGDA("WARNING: Calling destroy of Display adapter when display enabled. Disabling display..");
442816f63fd6a78b45e18819d9967d409c212c88eaeSundar Raman        disableDisplay(false);
443c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
444c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
445c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mBufferCount = 0;
446c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
447c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
448c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
449c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
450c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev// Implementation of inherited interfaces
451f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason SimmonsCameraBuffer* ANativeWindowDisplayAdapter::allocateBufferList(int width, int height, const char* format, int &bytes, int numBufs)
452c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
453c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
454c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    status_t err;
455c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    int i = -1;
456c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    const int lnumBufs = numBufs;
457c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    int undequeued = 0;
458f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    android::GraphicBufferMapper &mapper = android::GraphicBufferMapper::get();
459f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    android::Rect bounds;
4606c73fda9fdca5431e4e7911bb3171e36088a861eTyler Luu
461f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    mBuffers = new CameraBuffer [lnumBufs];
462f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    memset (mBuffers, 0, sizeof(CameraBuffer) * lnumBufs);
463f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
464f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    mFramesType.clear();
465c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
4667702898343dbb27a4543c642d189cff5de7046c9Sundar Raman    if ( NULL == mANativeWindow ) {
4677702898343dbb27a4543c642d189cff5de7046c9Sundar Raman        return NULL;
4687702898343dbb27a4543c642d189cff5de7046c9Sundar Raman    }
4697702898343dbb27a4543c642d189cff5de7046c9Sundar Raman
470c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    // Set gralloc usage bits for window.
471941b79b3815eb5f41e0d194d6f65161d1e4a86d0Tyler Luu    err = mANativeWindow->set_usage(mANativeWindow, CAMHAL_GRALLOC_USAGE);
472f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if ( NO_ERROR != err ) {
473f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        CAMHAL_LOGE("Surface::setUsage failed: %s (%d)", strerror(-err), -err);
4747702898343dbb27a4543c642d189cff5de7046c9Sundar Raman
475f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        if ( NO_INIT == err ) {
4767702898343dbb27a4543c642d189cff5de7046c9Sundar Raman            CAMHAL_LOGEA("Preview surface abandoned!");
4777702898343dbb27a4543c642d189cff5de7046c9Sundar Raman            mANativeWindow = NULL;
4787702898343dbb27a4543c642d189cff5de7046c9Sundar Raman        }
4797702898343dbb27a4543c642d189cff5de7046c9Sundar Raman
480c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        return NULL;
481c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
482c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
483c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    CAMHAL_LOGDB("Number of buffers set to ANativeWindow %d", numBufs);
484b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman    ///Set the number of buffers needed for camera preview
485b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman    err = mANativeWindow->set_buffer_count(mANativeWindow, numBufs);
486f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if ( NO_ERROR != err ) {
487f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        CAMHAL_LOGE("Surface::setBufferCount failed: %s (%d)", strerror(-err), -err);
4887702898343dbb27a4543c642d189cff5de7046c9Sundar Raman
489f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        if ( NO_INIT == err ) {
490b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman            CAMHAL_LOGEA("Preview surface abandoned!");
491b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman            mANativeWindow = NULL;
492c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
493b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman
494b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman        return NULL;
495b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman    }
496b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman    CAMHAL_LOGDB("Configuring %d buffers for ANativeWindow", numBufs);
497b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman    mBufferCount = numBufs;
498b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman
499c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
500c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    // Set window geometry
501c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    err = mANativeWindow->set_buffers_geometry(
502c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            mANativeWindow,
503c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            width,
504c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            height,
5052e986e5e29b391b070f608d641538c14b778d4baIliyan Malchev            /*toOMXPixFormat(format)*/HAL_PIXEL_FORMAT_TI_NV12);  // Gralloc only supports NV12 alloc!
506c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
507f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if ( NO_ERROR != err ) {
508f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        CAMHAL_LOGE("native_window_set_buffers_geometry failed: %s (%d)", strerror(-err), -err);
5097702898343dbb27a4543c642d189cff5de7046c9Sundar Raman
510f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        if ( NO_INIT == err ) {
5117702898343dbb27a4543c642d189cff5de7046c9Sundar Raman            CAMHAL_LOGEA("Preview surface abandoned!");
5127702898343dbb27a4543c642d189cff5de7046c9Sundar Raman            mANativeWindow = NULL;
5137702898343dbb27a4543c642d189cff5de7046c9Sundar Raman        }
5147702898343dbb27a4543c642d189cff5de7046c9Sundar Raman
515c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        return NULL;
516c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
517c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
518c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    ///We just return the buffers from ANativeWindow, if the width and height are same, else (vstab, vnf case)
519c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    ///re-allocate buffers using ANativeWindow and then get them
520c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    ///@todo - Re-allocate buffers for vnf and vstab using the width, height, format, numBufs etc
521f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if ( mBuffers == NULL )
522c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    {
523c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        CAMHAL_LOGEA("Couldn't create array for ANativeWindow buffers");
524c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        LOG_FUNCTION_NAME_EXIT;
525c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        return NULL;
526c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
527c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
528c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mANativeWindow->get_min_undequeued_buffer_count(mANativeWindow, &undequeued);
529f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    mPixelFormat = CameraHal::getPixelFormatConstant(format);
530c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
531c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    for ( i=0; i < mBufferCount; i++ )
532c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    {
533f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        buffer_handle_t *handle;
534c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        int stride;  // dummy variable to get stride
535c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        // TODO(XXX): Do we need to keep stride information in camera hal?
536c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
537f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        err = mANativeWindow->dequeue_buffer(mANativeWindow, &handle, &stride);
538c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
539f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        if ( NO_ERROR != err ) {
540f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            CAMHAL_LOGE("Surface::dequeueBuffer failed: %s (%d)", strerror(-err), -err);
5417702898343dbb27a4543c642d189cff5de7046c9Sundar Raman
542f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            if ( NO_INIT == err ) {
5437702898343dbb27a4543c642d189cff5de7046c9Sundar Raman                CAMHAL_LOGEA("Preview surface abandoned!");
5447702898343dbb27a4543c642d189cff5de7046c9Sundar Raman                mANativeWindow = NULL;
5457702898343dbb27a4543c642d189cff5de7046c9Sundar Raman            }
5467702898343dbb27a4543c642d189cff5de7046c9Sundar Raman
547c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            goto fail;
548c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
549c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
550f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        CAMHAL_LOGDB("got handle %p", handle);
551f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        mBuffers[i].opaque = (void *)handle;
552f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        mBuffers[i].type = CAMERA_BUFFER_ANW;
553f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        mBuffers[i].format = mPixelFormat;
554f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        mFramesWithCameraAdapterMap.add(handle, i);
555c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
556f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        // Tag remaining preview buffers as preview frames
557f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        if ( i >= ( mBufferCount - undequeued ) ) {
558f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            mFramesType.add( (int) mBuffers[i].opaque,
559f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                            CameraFrame::PREVIEW_FRAME_SYNC);
560f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        }
561c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
562f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        bytes = CameraHal::calculateBufferSize(format, width, height);
563c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
564c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
565c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
566c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    // lock the initial queueable buffers
5676c73fda9fdca5431e4e7911bb3171e36088a861eTyler Luu    bounds.left = 0;
5686c73fda9fdca5431e4e7911bb3171e36088a861eTyler Luu    bounds.top = 0;
5696c73fda9fdca5431e4e7911bb3171e36088a861eTyler Luu    bounds.right = width;
5706c73fda9fdca5431e4e7911bb3171e36088a861eTyler Luu    bounds.bottom = height;
5716c73fda9fdca5431e4e7911bb3171e36088a861eTyler Luu
572c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    for( i = 0;  i < mBufferCount-undequeued; i++ )
573c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    {
5746c73fda9fdca5431e4e7911bb3171e36088a861eTyler Luu        void *y_uv[2];
575f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        buffer_handle_t *handle = (buffer_handle_t *) mBuffers[i].opaque;
5766c73fda9fdca5431e4e7911bb3171e36088a861eTyler Luu
577f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        mANativeWindow->lock_buffer(mANativeWindow, handle);
5786c73fda9fdca5431e4e7911bb3171e36088a861eTyler Luu
579f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        mapper.lock(*handle, CAMHAL_GRALLOC_USAGE, bounds, y_uv);
580f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        mBuffers[i].mapped = y_uv[0];
581f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        mFrameProvider->addFramePointers(&mBuffers[i], y_uv);
582c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
583c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
584c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    // return the rest of the buffers back to ANativeWindow
585c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    for(i = (mBufferCount-undequeued); i >= 0 && i < mBufferCount; i++)
586c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    {
587f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        buffer_handle_t *handle = (buffer_handle_t *) mBuffers[i].opaque;
588f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        err = mANativeWindow->cancel_buffer(mANativeWindow, handle);
589f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        if ( NO_ERROR != err ) {
590f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            CAMHAL_LOGE("Surface::cancelBuffer failed: %s (%d)", strerror(-err), -err);
5917702898343dbb27a4543c642d189cff5de7046c9Sundar Raman
592f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            if ( NO_INIT == err ) {
5937702898343dbb27a4543c642d189cff5de7046c9Sundar Raman                CAMHAL_LOGEA("Preview surface abandoned!");
5947702898343dbb27a4543c642d189cff5de7046c9Sundar Raman                mANativeWindow = NULL;
5957702898343dbb27a4543c642d189cff5de7046c9Sundar Raman            }
5967702898343dbb27a4543c642d189cff5de7046c9Sundar Raman
5977702898343dbb27a4543c642d189cff5de7046c9Sundar Raman            goto fail;
5987702898343dbb27a4543c642d189cff5de7046c9Sundar Raman        }
599f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        mFramesWithCameraAdapterMap.removeItem((buffer_handle_t *) mBuffers[i].opaque);
6008e88af31129b8cc09675279ca2eac88256d8526bAkwasi Boateng        //LOCK UNLOCK TO GET YUV POINTERS
6018e88af31129b8cc09675279ca2eac88256d8526bAkwasi Boateng        void *y_uv[2];
602f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        mapper.lock(*(buffer_handle_t *) mBuffers[i].opaque, CAMHAL_GRALLOC_USAGE, bounds, y_uv);
603f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        mBuffers[i].mapped = y_uv[0];
604f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        mFrameProvider->addFramePointers(&mBuffers[i], y_uv);
605f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        mapper.unlock(*(buffer_handle_t *) mBuffers[i].opaque);
606c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
607c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
608c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mFirstInit = true;
609c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mFrameWidth = width;
610c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mFrameHeight = height;
611c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
612f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    return mBuffers;
613c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
614c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev fail:
615c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    // need to cancel buffers if any were dequeued
616c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    for (int start = 0; start < i && i > 0; start++) {
617f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        status_t err = mANativeWindow->cancel_buffer(mANativeWindow,
618f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                (buffer_handle_t *) mBuffers[start].opaque);
619f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        if ( NO_ERROR != err ) {
620f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons          CAMHAL_LOGE("Surface::cancelBuffer failed w/ error 0x%08x", err);
6217702898343dbb27a4543c642d189cff5de7046c9Sundar Raman          break;
622c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
623f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        mFramesWithCameraAdapterMap.removeItem((buffer_handle_t *) mBuffers[start].opaque);
624c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
62588006b1ebee79cb0f1a2c682258b313eb801049dSundar Raman
626f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    freeBufferList(mBuffers);
62788006b1ebee79cb0f1a2c682258b313eb801049dSundar Raman
628c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    CAMHAL_LOGEA("Error occurred, performing cleanup");
629c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
630f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if ( NULL != mErrorNotifier.get() ) {
631f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        mErrorNotifier->errorNotify(NO_MEMORY);
632c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
633c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
634c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
635c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    return NULL;
636c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
637c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
638c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
639f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason SimmonsCameraBuffer* ANativeWindowDisplayAdapter::getBufferList(int *numBufs) {
640f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    LOG_FUNCTION_NAME;
641f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if (numBufs) *numBufs = -1;
642f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
643f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    return NULL;
644f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons}
645f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
646c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevuint32_t * ANativeWindowDisplayAdapter::getOffsets()
647c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
648c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    const int lnumBufs = mBufferCount;
649c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
650c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
651c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
652c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    // TODO(XXX): Need to remove getOffsets from the API. No longer needed
653c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
654c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( NULL == mANativeWindow )
655c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    {
656c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        CAMHAL_LOGEA("mANativeWindow reference is missing");
657c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        goto fail;
658c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
659c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
660f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if( mBuffers == NULL)
661c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    {
662c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        CAMHAL_LOGEA("Buffers not allocated yet!!");
663c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        goto fail;
664c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
665c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
666c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if(mOffsetsMap == NULL)
667c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    {
668c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mOffsetsMap = new uint32_t[lnumBufs];
669c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        for(int i = 0; i < mBufferCount; i++)
670c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
671c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            mOffsetsMap[i] = 0;
672c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
673c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
674c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
675c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
676c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
677c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    return mOffsetsMap;
678c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
679c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev fail:
680c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
681c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( NULL != mOffsetsMap )
682c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    {
683c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        delete [] mOffsetsMap;
684c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mOffsetsMap = NULL;
685c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
686c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
687f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if ( NULL != mErrorNotifier.get() ) {
688f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        mErrorNotifier->errorNotify(INVALID_OPERATION);
689c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
690c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
691c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
692c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
693c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    return NULL;
694c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
695c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
696f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmonsstatus_t ANativeWindowDisplayAdapter::minUndequeueableBuffers(int& undequeueable) {
697c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
698f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    status_t ret = NO_ERROR;
699c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
700f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if(!mANativeWindow) {
701f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        ret = INVALID_OPERATION;
702c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        goto end;
703c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
704c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
705f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    ret = mANativeWindow->get_min_undequeued_buffer_count(mANativeWindow, &undequeueable);
7067702898343dbb27a4543c642d189cff5de7046c9Sundar Raman    if ( NO_ERROR != ret ) {
7077702898343dbb27a4543c642d189cff5de7046c9Sundar Raman        CAMHAL_LOGEB("get_min_undequeued_buffer_count failed: %s (%d)", strerror(-ret), -ret);
7087702898343dbb27a4543c642d189cff5de7046c9Sundar Raman
709f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        if ( NO_INIT == ret ) {
7107702898343dbb27a4543c642d189cff5de7046c9Sundar Raman            CAMHAL_LOGEA("Preview surface abandoned!");
7117702898343dbb27a4543c642d189cff5de7046c9Sundar Raman            mANativeWindow = NULL;
7127702898343dbb27a4543c642d189cff5de7046c9Sundar Raman        }
7137702898343dbb27a4543c642d189cff5de7046c9Sundar Raman
714f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        return ret;
715f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
716f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
717f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons end:
718f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    return ret;
719f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    LOG_FUNCTION_NAME_EXIT;
720f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
721f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons}
722f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
723f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmonsstatus_t ANativeWindowDisplayAdapter::maxQueueableBuffers(unsigned int& queueable)
724f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons{
725f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    LOG_FUNCTION_NAME;
726f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    status_t ret = NO_ERROR;
727f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    int undequeued = 0;
728f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
729f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if(mBufferCount == 0)
730f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    {
731f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        ret = INVALID_OPERATION;
732f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        goto end;
733f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
734f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
735f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    ret = minUndequeueableBuffers(undequeued);
736f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if (ret != NO_ERROR) {
737f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        goto end;
7387702898343dbb27a4543c642d189cff5de7046c9Sundar Raman    }
739c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
740c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    queueable = mBufferCount - undequeued;
741c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
742c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev end:
743c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    return ret;
744c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
745c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
746c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
747c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevint ANativeWindowDisplayAdapter::getFd()
748c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
749c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
750c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
751c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if(mFD == -1)
752c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    {
753f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        buffer_handle_t *handle =  (buffer_handle_t *)mBuffers[0].opaque;
754f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        IMG_native_handle_t *img = (IMG_native_handle_t *)handle;
755c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        // TODO: should we dup the fd? not really necessary and another thing for ANativeWindow
756c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        // to manage and close...
757f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
758f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        mFD = dup(img->fd[0]);
759c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
760c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
761c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
762c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
763c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    return mFD;
764c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
765c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
766c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
767b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Ramanstatus_t ANativeWindowDisplayAdapter::returnBuffersToWindow()
768b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman{
769b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman    status_t ret = NO_ERROR;
770b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman
771f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons     android::GraphicBufferMapper &mapper = android::GraphicBufferMapper::get();
772b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman    //Give the buffers back to display here -  sort of free it
773b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman     if (mANativeWindow)
774b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman         for(unsigned int i = 0; i < mFramesWithCameraAdapterMap.size(); i++) {
775b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman             int value = mFramesWithCameraAdapterMap.valueAt(i);
776f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons             buffer_handle_t *handle = (buffer_handle_t *) mBuffers[value].opaque;
777f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
778f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons             // if buffer index is out of bounds skip
779f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons             if ((value < 0) || (value >= mBufferCount)) {
780f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                 CAMHAL_LOGEA("Potential out bounds access to handle...skipping");
781f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                 continue;
782f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons             }
783b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman
784b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman             // unlock buffer before giving it up
785f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons             mapper.unlock(*handle);
786b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman
787f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons             ret = mANativeWindow->cancel_buffer(mANativeWindow, handle);
788f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons             if ( NO_INIT == ret ) {
789b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman                 CAMHAL_LOGEA("Preview surface abandoned!");
790b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman                 mANativeWindow = NULL;
791f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                 return ret;
792b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman             } else if ( NO_ERROR != ret ) {
793f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                 CAMHAL_LOGE("Surface::cancelBuffer() failed: %s (%d)",
794b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman                              strerror(-ret),
795b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman                              -ret);
796f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                return ret;
797b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman             }
798b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman         }
799b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman     else
800f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons         CAMHAL_LOGE("mANativeWindow is NULL");
801b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman
802b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman     ///Clear the frames with camera adapter map
803b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman     mFramesWithCameraAdapterMap.clear();
804b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman
805b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman     return ret;
806b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman
807b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman}
808b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman
809f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmonsint ANativeWindowDisplayAdapter::freeBufferList(CameraBuffer * buflist)
810c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
811c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
812c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
813b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman    status_t ret = NO_ERROR;
814b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman
815f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    android::AutoMutex lock(mLock);
816b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman
817f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if(mBuffers != buflist)
818c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    {
819c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        CAMHAL_LOGEA("CameraHal passed wrong set of buffers to free!!!");
820f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        if (mBuffers != NULL)
821f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            delete []mBuffers;
822f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        mBuffers = NULL;
823c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
824c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
825f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    /* FIXME this will probably want the list that was just deleted */
826b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman    returnBuffersToWindow();
827b3fb1a45ce906ab0365f247caf596665ea0c9f39Sundar Raman
828f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if ( NULL != buflist )
829c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    {
830f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        delete [] buflist;
831f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        mBuffers = NULL;
832c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
833c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
834f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if( mBuffers != NULL)
835c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    {
836f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        delete [] mBuffers;
837f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        mBuffers = NULL;
838c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
839c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
840c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( NULL != mOffsetsMap )
841c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    {
842c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        delete [] mOffsetsMap;
843c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mOffsetsMap = NULL;
844c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
845c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
846c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if( mFD != -1)
847c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    {
848c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        close(mFD);  // close duped handle
849c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mFD = -1;
850c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
851c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
852f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    mFramesType.clear();
853f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
854c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    return NO_ERROR;
855c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
856c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
857c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
858c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevbool ANativeWindowDisplayAdapter::supportsExternalBuffering()
859c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
860c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    return false;
861c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
862c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
863c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevvoid ANativeWindowDisplayAdapter::displayThread()
864c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
865c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    bool shouldLive = true;
866c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    int timeout = 0;
867c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    status_t ret;
868c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
869c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
870c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
871c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    while(shouldLive)
872c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
873f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        ret = Utils::MessageQueue::waitForMsg(&mDisplayThread->msgQ()
874c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                                                                ,  &mDisplayQ
875c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                                                                , NULL
876c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                                                                , ANativeWindowDisplayAdapter::DISPLAY_TIMEOUT);
877c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
878c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        if ( !mDisplayThread->msgQ().isEmpty() )
879c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            {
880c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            ///Received a message from CameraHal, process it
881c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            shouldLive = processHalMsg();
882c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
883c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            }
884c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        else  if( !mDisplayQ.isEmpty())
885c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            {
886c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            if ( mDisplayState== ANativeWindowDisplayAdapter::DISPLAY_INIT )
887c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                {
888c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
889c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                ///If display adapter is not started, continue
890c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                continue;
891c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
892c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                }
893c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            else
894c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                {
895f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                Utils::Message msg;
896c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                ///Get the dummy msg from the displayQ
897c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                if(mDisplayQ.get(&msg)!=NO_ERROR)
898c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    {
899c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    CAMHAL_LOGEA("Error in getting message from display Q");
900c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    continue;
901c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                }
902c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
903c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                // There is a frame from ANativeWindow for us to dequeue
904c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                // We dequeue and return the frame back to Camera adapter
905c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                if(mDisplayState == ANativeWindowDisplayAdapter::DISPLAY_STARTED)
906c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                {
907c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    handleFrameReturn();
908c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                }
909c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
910c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                if (mDisplayState == ANativeWindowDisplayAdapter::DISPLAY_EXITED)
911c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    {
912c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    ///we exit the thread even though there are frames still to dequeue. They will be dequeued
913c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    ///in disableDisplay
914c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    shouldLive = false;
915c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                }
916c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            }
917c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
918c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
919c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
920c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
921c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
922c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
923c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
924c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevbool ANativeWindowDisplayAdapter::processHalMsg()
925c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
926f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    Utils::Message msg;
927c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
928c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
929c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
930c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
931c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mDisplayThread->msgQ().get(&msg);
932c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    bool ret = true, invalidCommand = false;
933c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
934c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    switch ( msg.command )
935c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
936c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
937c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        case DisplayThread::DISPLAY_START:
938c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
939c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            CAMHAL_LOGDA("Display thread received DISPLAY_START command from Camera HAL");
940c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            mDisplayState = ANativeWindowDisplayAdapter::DISPLAY_STARTED;
941c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
942c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            break;
943c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
944c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        case DisplayThread::DISPLAY_STOP:
945c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
946c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            ///@bug There is no API to disable SF without destroying it
947c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            ///@bug Buffers might still be w/ display and will get displayed
948c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            ///@remarks Ideal seqyence should be something like this
949c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            ///mOverlay->setParameter("enabled", false);
950c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            CAMHAL_LOGDA("Display thread received DISPLAY_STOP command from Camera HAL");
951c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            mDisplayState = ANativeWindowDisplayAdapter::DISPLAY_STOPPED;
952c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
953f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            // flush frame message queue
954f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            while ( !mDisplayQ.isEmpty() ) {
955f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                Utils::Message message;
956f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                mDisplayQ.get(&message);
957f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            }
958f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
959c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            break;
960c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
961c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        case DisplayThread::DISPLAY_EXIT:
962c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
963c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            CAMHAL_LOGDA("Display thread received DISPLAY_EXIT command from Camera HAL.");
964c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            CAMHAL_LOGDA("Stopping display thread...");
965c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            mDisplayState = ANativeWindowDisplayAdapter::DISPLAY_EXITED;
966c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            ///Note that the SF can have pending buffers when we disable the display
967c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            ///This is normal and the expectation is that they may not be displayed.
968c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            ///This is to ensure that the user experience is not impacted
969c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            ret = false;
970c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            break;
971c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
972c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        default:
973c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
974c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            CAMHAL_LOGEB("Invalid Display Thread Command 0x%x.", msg.command);
975c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            invalidCommand = true;
976c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
977c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            break;
978c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
979c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
980c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    ///Signal the semaphore if it is sent as part of the message
981c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( ( msg.arg1 ) && ( !invalidCommand ) )
982c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
983c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
984c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        CAMHAL_LOGDA("+Signalling display semaphore");
985f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        Utils::Semaphore &sem = *((Utils::Semaphore*)msg.arg1);
986c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
987c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        sem.Signal();
988c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
989c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        CAMHAL_LOGDA("-Signalling display semaphore");
990c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
991c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
992c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
993c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
994c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    return ret;
995c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
996c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
997c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
998c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevstatus_t ANativeWindowDisplayAdapter::PostFrame(ANativeWindowDisplayAdapter::DisplayFrame &dispFrame)
999c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
1000c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    status_t ret = NO_ERROR;
1001c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    uint32_t actualFramesWithDisplay = 0;
1002c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    android_native_buffer_t *buffer = NULL;
1003f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    android::GraphicBufferMapper &mapper = android::GraphicBufferMapper::get();
1004c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    int i;
1005c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1006c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    ///@todo Do cropping based on the stabilized frame coordinates
1007c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    ///@todo Insert logic to drop frames here based on refresh rate of
1008c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    ///display or rendering rate whichever is lower
1009c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    ///Queue the buffer to overlay
1010348e4eaaf2f88810f2a3c55fd1b0df540a5104edTyler Luu
1011f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if ( NULL == mANativeWindow ) {
1012f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        return NO_INIT;
1013f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
1014f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
1015f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if (!mBuffers || !dispFrame.mBuffer) {
1016348e4eaaf2f88810f2a3c55fd1b0df540a5104edTyler Luu        CAMHAL_LOGEA("NULL sent to PostFrame");
1017f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        return BAD_VALUE;
1018348e4eaaf2f88810f2a3c55fd1b0df540a5104edTyler Luu    }
1019348e4eaaf2f88810f2a3c55fd1b0df540a5104edTyler Luu
1020c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    for ( i = 0; i < mBufferCount; i++ )
1021f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    {
1022f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        if ( dispFrame.mBuffer == &mBuffers[i] )
1023c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
1024c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            break;
1025c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
1026c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
1027c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1028f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
1029f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
1030f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if ( mMeasureStandby ) {
1031f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        CameraHal::PPM("Standby to first shot: Sensor Change completed - ", &mStandbyToShot);
1032f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        mMeasureStandby = false;
1033f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    } else if (CameraFrame::CameraFrame::SNAPSHOT_FRAME == dispFrame.mType) {
1034f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        CameraHal::PPM("Shot to snapshot: ", &mStartCapture);
1035f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        mShotToShot = true;
1036f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    } else if ( mShotToShot ) {
1037f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        CameraHal::PPM("Shot to shot: ", &mStartCapture);
1038f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        mShotToShot = false;
1039f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
1040f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
1041f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons#endif
1042f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
1043f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    android::AutoMutex lock(mLock);
1044f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
1045f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    mFramesType.add( (int)mBuffers[i].opaque, dispFrame.mType);
1046f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
1047c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( mDisplayState == ANativeWindowDisplayAdapter::DISPLAY_STARTED &&
1048c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                (!mPaused ||  CameraFrame::CameraFrame::SNAPSHOT_FRAME == dispFrame.mType) &&
1049c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                !mSuspend)
1050c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    {
1051f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        uint32_t xOff, yOff;
1052f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
1053f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        CameraHal::getXYFromOffset(&xOff, &yOff, dispFrame.mOffset, PAGE_SIZE, mPixelFormat);
1054c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1055c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        // Set crop only if current x and y offsets do not match with frame offsets
1056f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        if ((mXOff != xOff) || (mYOff != yOff)) {
1057f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            CAMHAL_LOGDB("offset = %u left = %d top = %d right = %d bottom = %d",
1058f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                          dispFrame.mOffset, xOff, yOff ,
1059f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                          xOff + mPreviewWidth, yOff + mPreviewHeight);
1060c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1061c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            // We'll ignore any errors here, if the surface is
1062c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            // already invalid, we'll know soon enough.
1063f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            mANativeWindow->set_crop(mANativeWindow, xOff, yOff,
1064f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                                     xOff + mPreviewWidth, yOff + mPreviewHeight);
1065c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1066f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            // Update the current x and y offsets
1067c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            mXOff = xOff;
1068c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            mYOff = yOff;
1069c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
1070c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1071f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        {
1072f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            buffer_handle_t *handle = (buffer_handle_t *) mBuffers[i].opaque;
1073f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            // unlock buffer before sending to display
1074f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            mapper.unlock(*handle);
1075f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            ret = mANativeWindow->enqueue_buffer(mANativeWindow, handle);
1076f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        }
1077f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        if ( NO_ERROR != ret ) {
1078f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            CAMHAL_LOGE("Surface::queueBuffer returned error %d", ret);
1079c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
1080c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1081f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        mFramesWithCameraAdapterMap.removeItem((buffer_handle_t *) dispFrame.mBuffer->opaque);
1082c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1083c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1084c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        // HWComposer has not minimum buffer requirement. We should be able to dequeue
1085c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        // the buffer immediately
1086f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        Utils::Message msg;
1087c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mDisplayQ.put(&msg);
1088c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1089c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
1090c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    else
1091c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    {
1092f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        buffer_handle_t *handle = (buffer_handle_t *) mBuffers[i].opaque;
10936c73fda9fdca5431e4e7911bb3171e36088a861eTyler Luu
10946c73fda9fdca5431e4e7911bb3171e36088a861eTyler Luu        // unlock buffer before giving it up
1095f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        mapper.unlock(*handle);
10966c73fda9fdca5431e4e7911bb3171e36088a861eTyler Luu
1097c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        // cancel buffer and dequeue another one
1098f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        ret = mANativeWindow->cancel_buffer(mANativeWindow, handle);
1099f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        if ( NO_ERROR != ret ) {
1100f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            CAMHAL_LOGE("Surface::cancelBuffer returned error %d", ret);
1101c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
1102c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1103f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        mFramesWithCameraAdapterMap.removeItem((buffer_handle_t *) dispFrame.mBuffer->opaque);
1104c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1105f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        Utils::Message msg;
1106c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mDisplayQ.put(&msg);
1107c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        ret = NO_ERROR;
1108c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
1109c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1110c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    return ret;
1111c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
1112c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1113c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1114c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevbool ANativeWindowDisplayAdapter::handleFrameReturn()
1115c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
1116c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    status_t err;
1117f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    buffer_handle_t *buf;
1118c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    int i = 0;
1119f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    unsigned int k;
1120c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    int stride;  // dummy variable to get stride
1121f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    android::GraphicBufferMapper &mapper = android::GraphicBufferMapper::get();
1122f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    android::Rect bounds;
1123f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    CameraFrame::FrameType frameType = CameraFrame::PREVIEW_FRAME_SYNC;
1124f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
11256c73fda9fdca5431e4e7911bb3171e36088a861eTyler Luu    void *y_uv[2];
11266c73fda9fdca5431e4e7911bb3171e36088a861eTyler Luu
1127c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    // TODO(XXX): Do we need to keep stride information in camera hal?
1128c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
11297702898343dbb27a4543c642d189cff5de7046c9Sundar Raman    if ( NULL == mANativeWindow ) {
11307702898343dbb27a4543c642d189cff5de7046c9Sundar Raman        return false;
11317702898343dbb27a4543c642d189cff5de7046c9Sundar Raman    }
11327702898343dbb27a4543c642d189cff5de7046c9Sundar Raman
1133c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    err = mANativeWindow->dequeue_buffer(mANativeWindow, &buf, &stride);
1134c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if (err != 0) {
1135f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        CAMHAL_LOGE("Surface::dequeueBuffer failed: %s (%d)", strerror(-err), -err);
11367702898343dbb27a4543c642d189cff5de7046c9Sundar Raman
1137f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        if ( NO_INIT == err ) {
11387702898343dbb27a4543c642d189cff5de7046c9Sundar Raman            CAMHAL_LOGEA("Preview surface abandoned!");
11397702898343dbb27a4543c642d189cff5de7046c9Sundar Raman            mANativeWindow = NULL;
11407702898343dbb27a4543c642d189cff5de7046c9Sundar Raman        }
11417702898343dbb27a4543c642d189cff5de7046c9Sundar Raman
11427702898343dbb27a4543c642d189cff5de7046c9Sundar Raman        return false;
1143c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
1144c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1145c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    err = mANativeWindow->lock_buffer(mANativeWindow, buf);
1146f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if ( NO_ERROR != err ) {
1147f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        CAMHAL_LOGE("Surface::lockBuffer failed: %s (%d)", strerror(-err), -err);
11487702898343dbb27a4543c642d189cff5de7046c9Sundar Raman
1149f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        if ( NO_INIT == err ) {
11507702898343dbb27a4543c642d189cff5de7046c9Sundar Raman            CAMHAL_LOGEA("Preview surface abandoned!");
11517702898343dbb27a4543c642d189cff5de7046c9Sundar Raman            mANativeWindow = NULL;
11527702898343dbb27a4543c642d189cff5de7046c9Sundar Raman        }
11537702898343dbb27a4543c642d189cff5de7046c9Sundar Raman
11547702898343dbb27a4543c642d189cff5de7046c9Sundar Raman        return false;
1155c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
1156c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1157c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    for(i = 0; i < mBufferCount; i++)
1158c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    {
1159f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        if (mBuffers[i].opaque == buf)
1160c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            break;
1161c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
1162f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if (i == mBufferCount) {
1163f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        CAMHAL_LOGEB("Failed to find handle %p", buf);
1164f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
1165c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
11666c73fda9fdca5431e4e7911bb3171e36088a861eTyler Luu    // lock buffer before sending to FrameProvider for filling
11676c73fda9fdca5431e4e7911bb3171e36088a861eTyler Luu    bounds.left = 0;
11686c73fda9fdca5431e4e7911bb3171e36088a861eTyler Luu    bounds.top = 0;
11696c73fda9fdca5431e4e7911bb3171e36088a861eTyler Luu    bounds.right = mFrameWidth;
11706c73fda9fdca5431e4e7911bb3171e36088a861eTyler Luu    bounds.bottom = mFrameHeight;
11718e88af31129b8cc09675279ca2eac88256d8526bAkwasi Boateng
11728e88af31129b8cc09675279ca2eac88256d8526bAkwasi Boateng    int lock_try_count = 0;
1173f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    while (mapper.lock(*(buffer_handle_t *) mBuffers[i].opaque, CAMHAL_GRALLOC_USAGE, bounds, y_uv) < 0){
11748e88af31129b8cc09675279ca2eac88256d8526bAkwasi Boateng      if (++lock_try_count > LOCK_BUFFER_TRIES){
11758e88af31129b8cc09675279ca2eac88256d8526bAkwasi Boateng        if ( NULL != mErrorNotifier.get() ){
11768e88af31129b8cc09675279ca2eac88256d8526bAkwasi Boateng          mErrorNotifier->errorNotify(CAMERA_ERROR_UNKNOWN);
11778e88af31129b8cc09675279ca2eac88256d8526bAkwasi Boateng        }
11788e88af31129b8cc09675279ca2eac88256d8526bAkwasi Boateng        return false;
11798e88af31129b8cc09675279ca2eac88256d8526bAkwasi Boateng      }
11808e88af31129b8cc09675279ca2eac88256d8526bAkwasi Boateng      CAMHAL_LOGEA("Gralloc Lock FrameReturn Error: Sleeping 15ms");
11818e88af31129b8cc09675279ca2eac88256d8526bAkwasi Boateng      usleep(15000);
11828e88af31129b8cc09675279ca2eac88256d8526bAkwasi Boateng    }
11836c73fda9fdca5431e4e7911bb3171e36088a861eTyler Luu
1184f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    {
1185f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        android::AutoMutex lock(mLock);
1186f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        mFramesWithCameraAdapterMap.add((buffer_handle_t *) mBuffers[i].opaque, i);
1187f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
1188f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        for( k = 0; k < mFramesType.size() ; k++) {
1189f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            if(mFramesType.keyAt(k) == (int)mBuffers[i].opaque)
1190f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                break;
1191f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        }
1192f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
1193f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        if ( k == mFramesType.size() ) {
1194f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            CAMHAL_LOGE("Frame type for preview buffer 0%x not found!!", mBuffers[i].opaque);
1195f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            return false;
1196f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        }
1197f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
1198f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        frameType = (CameraFrame::FrameType) mFramesType.valueAt(k);
1199f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        mFramesType.removeItem((int) mBuffers[i].opaque);
1200f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
1201c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1202c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    CAMHAL_LOGVB("handleFrameReturn: found graphic buffer %d of %d", i, mBufferCount-1);
1203f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    mFrameProvider->returnFrame(&mBuffers[i], frameType);
1204f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
1205c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    return true;
1206c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
1207c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1208c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevvoid ANativeWindowDisplayAdapter::frameCallbackRelay(CameraFrame* caFrame)
1209c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
1210c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1211c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( NULL != caFrame )
1212c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
1213c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        if ( NULL != caFrame->mCookie )
1214c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            {
1215c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            ANativeWindowDisplayAdapter *da = (ANativeWindowDisplayAdapter*) caFrame->mCookie;
1216c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            da->frameCallback(caFrame);
1217c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
1218c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        else
1219c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            {
1220c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            CAMHAL_LOGEB("Invalid Cookie in Camera Frame = %p, Cookie = %p", caFrame, caFrame->mCookie);
1221c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            }
1222c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
1223c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    else
1224c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
1225c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        CAMHAL_LOGEB("Invalid Camera Frame = %p", caFrame);
1226c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
1227c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1228c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
1229c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1230c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevvoid ANativeWindowDisplayAdapter::frameCallback(CameraFrame* caFrame)
1231c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
1232c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    ///Call queueBuffer of overlay in the context of the callback thread
1233f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
1234c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    DisplayFrame df;
1235c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    df.mBuffer = caFrame->mBuffer;
1236c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    df.mType = (CameraFrame::FrameType) caFrame->mFrameType;
1237c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    df.mOffset = caFrame->mOffset;
1238c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    df.mWidthStride = caFrame->mAlignment;
1239c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    df.mLength = caFrame->mLength;
1240c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    df.mWidth = caFrame->mWidth;
1241c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    df.mHeight = caFrame->mHeight;
1242c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    PostFrame(df);
1243c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
1244c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1245c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1246c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev/*--------------------ANativeWindowDisplayAdapter Class ENDS here-----------------------------*/
1247c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1248f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons} // namespace Camera
1249f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons} // namespace Ti
1250