1f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons/*
2f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons * Copyright (C) Texas Instruments - http://www.ti.com/
3f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons *
4f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons * Licensed under the Apache License, Version 2.0 (the "License");
5f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons * you may not use this file except in compliance with the License.
6f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons * You may obtain a copy of the License at
7f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons *
8f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons *      http://www.apache.org/licenses/LICENSE-2.0
9f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons *
10f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons * Unless required by applicable law or agreed to in writing, software
11f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons * distributed under the License is distributed on an "AS IS" BASIS,
12f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons * See the License for the specific language governing permissions and
14f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons * limitations under the License.
15f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons */
16f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
17f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons#ifdef OMAP_ENHANCEMENT_CPCAM
18f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
19f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons#include "BufferSourceAdapter.h"
20f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons#include <ui/GraphicBuffer.h>
21f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons#include <ui/GraphicBufferMapper.h>
22f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons#include <hal_public.h>
23f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
24f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmonsnamespace Ti {
25f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmonsnamespace Camera {
26f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
27f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmonsstatic int getANWFormat(const char* parameters_format)
28f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons{
29f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    int format = HAL_PIXEL_FORMAT_TI_NV12;
30f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
31f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if (parameters_format != NULL) {
32f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        if (strcmp(parameters_format, android::CameraParameters::PIXEL_FORMAT_YUV422I) == 0) {
33f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            CAMHAL_LOGDA("CbYCrY format selected");
34d68392bec3edfd02bc24f8be35d84acbbd62f02cEmilian Peev            format = HAL_PIXEL_FORMAT_TI_UYVY;
35f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        } else if (strcmp(parameters_format, android::CameraParameters::PIXEL_FORMAT_YUV420SP) == 0) {
36f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            CAMHAL_LOGDA("YUV420SP format selected");
37f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            format = HAL_PIXEL_FORMAT_TI_NV12;
38f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        } else if (strcmp(parameters_format, android::CameraParameters::PIXEL_FORMAT_RGB565) == 0) {
39f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            CAMHAL_LOGDA("RGB565 format selected");
40f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            // TODO(XXX): not defined yet
41f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            format = -1;
42f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        } else if (strcmp(parameters_format, android::CameraParameters::PIXEL_FORMAT_BAYER_RGGB) == 0) {
43f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            format = HAL_PIXEL_FORMAT_TI_Y16;
44f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        } else {
45f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            CAMHAL_LOGDA("Invalid format, NV12 format selected as default");
46f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            format = HAL_PIXEL_FORMAT_TI_NV12;
47f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        }
48f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
49f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
50f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    return format;
51f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons}
52f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
53f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmonsstatic int getUsageFromANW(int format)
54f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons{
55f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    int usage = GRALLOC_USAGE_SW_READ_RARELY |
56f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                GRALLOC_USAGE_SW_WRITE_NEVER;
57f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
58f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    switch (format) {
59f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        case HAL_PIXEL_FORMAT_TI_NV12:
60632f68a15eb49aad3fdcc1e81b257ba066d64ce4Vladimir Petrov        case HAL_PIXEL_FORMAT_TI_Y16:
61f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            // This usage flag indicates to gralloc we want the
62f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            // buffers to come from system heap
63f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            usage |= GRALLOC_USAGE_PRIVATE_0;
64f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            break;
65f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        default:
66f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            // No special flags needed
67f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            break;
68f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
69f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    return usage;
70f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons}
71f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
72f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmonsstatic const char* getFormatFromANW(int format)
73f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons{
74f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    switch (format) {
75f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        case HAL_PIXEL_FORMAT_TI_NV12:
76f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            // Assuming NV12 1D is RAW or Image frame
77f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            return android::CameraParameters::PIXEL_FORMAT_YUV420SP;
78f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        case HAL_PIXEL_FORMAT_TI_Y16:
79f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            return android::CameraParameters::PIXEL_FORMAT_BAYER_RGGB;
80d68392bec3edfd02bc24f8be35d84acbbd62f02cEmilian Peev        case HAL_PIXEL_FORMAT_TI_UYVY:
81d68392bec3edfd02bc24f8be35d84acbbd62f02cEmilian Peev            return android::CameraParameters::PIXEL_FORMAT_YUV422I;
82f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        default:
83f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            break;
84f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
85f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    return android::CameraParameters::PIXEL_FORMAT_YUV420SP;
86f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons}
87f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
88f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmonsstatic CameraFrame::FrameType formatToOutputFrameType(const char* format) {
89f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    switch (getANWFormat(format)) {
90f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        case HAL_PIXEL_FORMAT_TI_NV12:
91f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        case HAL_PIXEL_FORMAT_TI_Y16:
92d68392bec3edfd02bc24f8be35d84acbbd62f02cEmilian Peev        case HAL_PIXEL_FORMAT_TI_UYVY:
93f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            // Assuming NV12 1D is RAW or Image frame
94f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            return CameraFrame::RAW_FRAME;
95f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        default:
96f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            break;
97f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
98f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    return CameraFrame::RAW_FRAME;
99f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons}
100f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
101f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmonsstatic int getHeightFromFormat(const char* format, int stride, int size) {
102f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    CAMHAL_ASSERT((NULL != format) && (0 <= stride) && (0 <= size));
103f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    switch (getANWFormat(format)) {
104f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        case HAL_PIXEL_FORMAT_TI_NV12:
105f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            return (size / (3 * stride)) * 2;
106f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        case HAL_PIXEL_FORMAT_TI_Y16:
107d68392bec3edfd02bc24f8be35d84acbbd62f02cEmilian Peev        case HAL_PIXEL_FORMAT_TI_UYVY:
108f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            return (size / stride) / 2;
109f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        default:
110f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            break;
111f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
112f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    return 0;
113f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons}
114f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
115f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons/*--------------------BufferSourceAdapter Class STARTS here-----------------------------*/
116f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
117f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
118f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons///Constant definitions
119f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons// TODO(XXX): Temporarily increase number of buffers we can allocate from ANW
120f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons// until faux-NPA mode is implemented
121f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmonsconst int BufferSourceAdapter::NO_BUFFERS_IMAGE_CAPTURE_SYSTEM_HEAP = 15;
122f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
123f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons/**
124f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons * Display Adapter class STARTS here..
125f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons */
126f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason SimmonsBufferSourceAdapter::BufferSourceAdapter() : mBufferCount(0)
127f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons{
128f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    LOG_FUNCTION_NAME;
129f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
130f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    mPixelFormat = NULL;
131f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    mBuffers = NULL;
132f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    mFrameProvider = NULL;
133f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    mBufferSource = NULL;
134f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
135f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    mFrameWidth = 0;
136f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    mFrameHeight = 0;
137f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    mPreviewWidth = 0;
138f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    mPreviewHeight = 0;
139f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
140f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    LOG_FUNCTION_NAME_EXIT;
141f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons}
142f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
143f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason SimmonsBufferSourceAdapter::~BufferSourceAdapter()
144f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons{
145f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    LOG_FUNCTION_NAME;
146f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
1471d40b78f3a968634194f0c1d878d1ba122f435d7Tyler Luu    freeBufferList(mBuffers);
1481d40b78f3a968634194f0c1d878d1ba122f435d7Tyler Luu
149f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    android::AutoMutex lock(mLock);
150f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
151f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    destroy();
152f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
153f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if (mFrameProvider) {
154f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        // Unregister with the frame provider
155f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        mFrameProvider->disableFrameNotification(CameraFrame::ALL_FRAMES);
156f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        delete mFrameProvider;
157f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        mFrameProvider = NULL;
158f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
159f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
160f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if (mQueueFrame.get()) {
161f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        mQueueFrame->requestExit();
162f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        mQueueFrame.clear();
163f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
164f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
165f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if (mReturnFrame.get()) {
166f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        mReturnFrame->requestExit();
167f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        mReturnFrame.clear();
168f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
169f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
170f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    LOG_FUNCTION_NAME_EXIT;
171f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons}
172f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
173f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmonsstatus_t BufferSourceAdapter::initialize()
174f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons{
175f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    status_t ret = NO_ERROR;
176f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
177f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    LOG_FUNCTION_NAME;
178f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
179f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    mReturnFrame.clear();
180f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    mReturnFrame = new ReturnFrame(this);
181f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    mReturnFrame->run();
182f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
183f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    mQueueFrame.clear();
184f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    mQueueFrame = new QueueFrame(this);
185f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    mQueueFrame->run();
186f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
187f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    LOG_FUNCTION_NAME_EXIT;
188f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
189f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    return ret;
190f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons}
191f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
192f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmonsint BufferSourceAdapter::setPreviewWindow(preview_stream_ops_t *source)
193f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons{
194f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    LOG_FUNCTION_NAME;
195f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
196f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if (!source) {
197f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        CAMHAL_LOGEA("NULL window object passed to DisplayAdapter");
198f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        LOG_FUNCTION_NAME_EXIT;
199f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        return BAD_VALUE;
200f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
201f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
202f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if (mBufferSource) {
203f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        char id1[OP_STR_SIZE], id2[OP_STR_SIZE];
204f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        status_t ret;
205f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
206f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        ret = extendedOps()->get_id(mBufferSource, id1, sizeof(id1));
207f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        if (ret != 0) {
208f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            CAMHAL_LOGE("Surface::getId returned error %d", ret);
209f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            return ret;
210f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        }
211f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
212f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        ret = extendedOps()->get_id(source, id2, sizeof(id2));
213f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        if (ret != 0) {
214f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            CAMHAL_LOGE("Surface::getId returned error %d", ret);
215f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            return ret;
216f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        }
217f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        if ((0 >= strlen(id1)) || (0 >= strlen(id2))) {
218f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            CAMHAL_LOGE("Cannot set ST without name: id1:\"%s\" id2:\"%s\"",
219f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                        id1, id2);
220f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            return NOT_ENOUGH_DATA;
221f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        }
222f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        if (0 == strcmp(id1, id2)) {
223f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            return ALREADY_EXISTS;
224f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        }
225f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
226f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        // client has to unset mBufferSource before being able to set a new one
227f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        return BAD_VALUE;
228f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
229f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
230f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    // Move to new source obj
231f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    mBufferSource = source;
232f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
233f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    LOG_FUNCTION_NAME_EXIT;
234f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
235f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    return NO_ERROR;
236f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons}
237f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
238f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmonsbool BufferSourceAdapter::match(const char * str) {
239f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    char id1[OP_STR_SIZE];
240f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    status_t ret;
241f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
242f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    ret = extendedOps()->get_id(mBufferSource, id1, sizeof(id1));
243f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
244f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if (ret != 0) {
245f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        CAMHAL_LOGE("Surface::getId returned error %d", ret);
246f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
247f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
248f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    return strcmp(id1, str) == 0;
249f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons}
250f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
251f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmonsint BufferSourceAdapter::setFrameProvider(FrameNotifier *frameProvider)
252f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons{
253f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    LOG_FUNCTION_NAME;
254f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
255f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if ( !frameProvider ) {
256f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        CAMHAL_LOGEA("NULL passed for frame provider");
257f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        LOG_FUNCTION_NAME_EXIT;
258f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        return BAD_VALUE;
259f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
260f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
261f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if ( NULL != mFrameProvider ) {
262f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        delete mFrameProvider;
263f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
264f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
265f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    mFrameProvider = new FrameProvider(frameProvider, this, frameCallback);
266f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
267f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    LOG_FUNCTION_NAME_EXIT;
268f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
269f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    return NO_ERROR;
270f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons}
271f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
272f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmonsint BufferSourceAdapter::setErrorHandler(ErrorNotifier *errorNotifier)
273f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons{
274f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    status_t ret = NO_ERROR;
275f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
276f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    LOG_FUNCTION_NAME;
277f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
278f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if ( NULL == errorNotifier ) {
279f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        CAMHAL_LOGEA("Invalid Error Notifier reference");
280f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        return -EINVAL;
281f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
282f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
283f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    mErrorNotifier = errorNotifier;
284f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
285f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    LOG_FUNCTION_NAME_EXIT;
286f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
287f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    return ret;
288f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons}
289f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
290f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmonsint BufferSourceAdapter::enableDisplay(int width, int height,
291f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                                       struct timeval *refTime)
292f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons{
293f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    LOG_FUNCTION_NAME;
294f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    CameraFrame::FrameType frameType;
295f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
296f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if (mFrameProvider == NULL) {
297f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        // no-op frame provider not set yet
298f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        return NO_ERROR;
299f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
300f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
301f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if (mBufferSourceDirection == BUFFER_SOURCE_TAP_IN) {
302f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        // only supporting one type of input frame
303f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        frameType = CameraFrame::REPROCESS_INPUT_FRAME;
304f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    } else {
305f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        frameType = formatToOutputFrameType(mPixelFormat);
306f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
307f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
308f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    mFrameProvider->enableFrameNotification(frameType);
309f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    LOG_FUNCTION_NAME_EXIT;
310f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
311f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    return NO_ERROR;
312f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons}
313f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
314f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmonsint BufferSourceAdapter::disableDisplay(bool cancel_buffer)
315f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons{
316f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    LOG_FUNCTION_NAME;
317f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
318f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if (mFrameProvider) mFrameProvider->disableFrameNotification(CameraFrame::ALL_FRAMES);
319f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
320f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    LOG_FUNCTION_NAME_EXIT;
321f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
322f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    return NO_ERROR;
323f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons}
324f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
325f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmonsstatus_t BufferSourceAdapter::pauseDisplay(bool pause)
326f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons{
327f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    status_t ret = NO_ERROR;
328f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
329f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    LOG_FUNCTION_NAME;
330f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
331f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    // no-op for BufferSourceAdapter
332f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
333f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    LOG_FUNCTION_NAME_EXIT;
334f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
335f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    return ret;
336f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons}
337f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
338f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
339f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmonsvoid BufferSourceAdapter::destroy()
340f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons{
341f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    LOG_FUNCTION_NAME;
342f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
343f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    mBufferCount = 0;
344f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
345f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    LOG_FUNCTION_NAME_EXIT;
346f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons}
347f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
348f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason SimmonsCameraBuffer* BufferSourceAdapter::allocateBufferList(int width, int dummyHeight, const char* format,
349f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                                                      int &bytes, int numBufs)
350f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons{
351f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    LOG_FUNCTION_NAME;
352f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    status_t err;
353f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    int i = -1;
354f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    const int lnumBufs = numBufs;
355f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    int undequeued = 0;
356f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    android::GraphicBufferMapper &mapper = android::GraphicBufferMapper::get();
357f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
358f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    mBuffers = new CameraBuffer [lnumBufs];
359f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    memset (mBuffers, 0, sizeof(CameraBuffer) * lnumBufs);
360f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
361f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if ( NULL == mBufferSource ) {
362f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        return NULL;
363f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
364f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
365f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    int pixFormat = getANWFormat(format);
366f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    int usage = getUsageFromANW(pixFormat);
367f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    mPixelFormat = CameraHal::getPixelFormatConstant(format);
368f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
369f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    // Set gralloc usage bits for window.
370f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    err = mBufferSource->set_usage(mBufferSource, usage);
371f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if (err != 0) {
372f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        CAMHAL_LOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err);
373f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
374f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        if ( ENODEV == err ) {
375f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            CAMHAL_LOGEA("Preview surface abandoned!");
376f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            mBufferSource = NULL;
377f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        }
378f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
379f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        return NULL;
380f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
381f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
382f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    CAMHAL_LOGDB("Number of buffers set to BufferSourceAdapter %d", numBufs);
383f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    // Set the number of buffers needed for this buffer source
384f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    err = mBufferSource->set_buffer_count(mBufferSource, numBufs);
385f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if (err != 0) {
386f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        CAMHAL_LOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err), -err);
387f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
388f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        if ( ENODEV == err ) {
389f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            CAMHAL_LOGEA("Preview surface abandoned!");
390f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            mBufferSource = NULL;
391f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        }
392f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
393f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        return NULL;
394f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
395f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
396f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    CAMHAL_LOGDB("Configuring %d buffers for ANativeWindow", numBufs);
397f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    mBufferCount = numBufs;
398f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
399f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    // re-calculate height depending on stride and size
400f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    int height = getHeightFromFormat(format, width, bytes);
401f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
402f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    // Set window geometry
403f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    err = mBufferSource->set_buffers_geometry(mBufferSource,
404f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                                              width, height,
405f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                                              pixFormat);
406f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
407f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if (err != 0) {
408f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        CAMHAL_LOGE("native_window_set_buffers_geometry failed: %s (%d)", strerror(-err), -err);
409f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        if ( ENODEV == err ) {
410f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            CAMHAL_LOGEA("Preview surface abandoned!");
411f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            mBufferSource = NULL;
412f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        }
413f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        return NULL;
414f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
415f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
416f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if ( mBuffers == NULL ) {
417f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        CAMHAL_LOGEA("Couldn't create array for ANativeWindow buffers");
418f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        LOG_FUNCTION_NAME_EXIT;
419f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        return NULL;
420f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
421f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
422f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    mBufferSource->get_min_undequeued_buffer_count(mBufferSource, &undequeued);
423f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
424f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    for (i = 0; i < mBufferCount; i++ ) {
425f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        buffer_handle_t *handle;
426f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        int stride;  // dummy variable to get stride
427f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        // TODO(XXX): Do we need to keep stride information in camera hal?
428f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
429f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        err = mBufferSource->dequeue_buffer(mBufferSource, &handle, &stride);
430f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
431f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        if (err != 0) {
432f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            CAMHAL_LOGEB("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
433f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            if ( ENODEV == err ) {
434f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                CAMHAL_LOGEA("Preview surface abandoned!");
435f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                mBufferSource = NULL;
436f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            }
437f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            goto fail;
438f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        }
439f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
440f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        CAMHAL_LOGDB("got handle %p", handle);
441f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        mBuffers[i].opaque = (void *)handle;
442f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        mBuffers[i].type = CAMERA_BUFFER_ANW;
443f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        mBuffers[i].format = mPixelFormat;
444f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        mFramesWithCameraAdapterMap.add(handle, i);
445f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
446f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        bytes = CameraHal::calculateBufferSize(format, width, height);
447f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
448f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
449f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    for( i = 0;  i < mBufferCount-undequeued; i++ ) {
450f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        void *y_uv[2];
451f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        android::Rect bounds(width, height);
452f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
453f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        buffer_handle_t *handle = (buffer_handle_t *) mBuffers[i].opaque;
454f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        mBufferSource->lock_buffer(mBufferSource, handle);
455f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        mapper.lock(*handle, CAMHAL_GRALLOC_USAGE, bounds, y_uv);
456f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        mBuffers[i].mapped = y_uv[0];
457f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
458f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
459f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    // return the rest of the buffers back to ANativeWindow
460f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    for(i = (mBufferCount-undequeued); i >= 0 && i < mBufferCount; i++) {
461f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        buffer_handle_t *handle = (buffer_handle_t *) mBuffers[i].opaque;
462f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        void *y_uv[2];
463f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        android::Rect bounds(width, height);
464f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
465f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        mapper.lock(*handle, CAMHAL_GRALLOC_USAGE, bounds, y_uv);
466f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        mBuffers[i].mapped = y_uv[0];
467f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        mapper.unlock(*handle);
468f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
469f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        err = mBufferSource->cancel_buffer(mBufferSource, handle);
470f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        if (err != 0) {
471f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            CAMHAL_LOGEB("cancel_buffer failed: %s (%d)", strerror(-err), -err);
472f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            if ( ENODEV == err ) {
473f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                CAMHAL_LOGEA("Preview surface abandoned!");
474f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                mBufferSource = NULL;
475f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            }
476f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            goto fail;
477f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        }
478f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        mFramesWithCameraAdapterMap.removeItem((buffer_handle_t *) mBuffers[i].opaque);
479f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
480f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
481f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    mFrameWidth = width;
482f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    mFrameHeight = height;
483f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    mBufferSourceDirection = BUFFER_SOURCE_TAP_OUT;
484f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
485f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    return mBuffers;
486f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
487f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons fail:
488f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    // need to cancel buffers if any were dequeued
489f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    for (int start = 0; start < i && i > 0; start++) {
490f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        int err = mBufferSource->cancel_buffer(mBufferSource,
491f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                (buffer_handle_t *) mBuffers[start].opaque);
492f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        if (err != 0) {
493f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons          CAMHAL_LOGEB("cancelBuffer failed w/ error 0x%08x", err);
494f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons          break;
495f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        }
496f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        mFramesWithCameraAdapterMap.removeItem((buffer_handle_t *) mBuffers[start].opaque);
497f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
498f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
499f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    freeBufferList(mBuffers);
500f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
501f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    CAMHAL_LOGEA("Error occurred, performing cleanup");
502f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
503f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if (NULL != mErrorNotifier.get()) {
504f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        mErrorNotifier->errorNotify(-ENOMEM);
505f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
506f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
507f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    LOG_FUNCTION_NAME_EXIT;
508f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    return NULL;
509f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
510f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons}
511f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
512f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason SimmonsCameraBuffer *BufferSourceAdapter::getBuffers(bool reset) {
513f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    int undequeued = 0;
514f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    status_t err;
515f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    android::Mutex::Autolock lock(mLock);
516f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
517f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if (!mBufferSource || !mBuffers) {
518f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        CAMHAL_LOGE("Adapter is not set up properly: "
519f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                    "mBufferSource:%p mBuffers:%p",
520f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                     mBufferSource, mBuffers);
521f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        goto fail;
522f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
523f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
524f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    // CameraHal is indicating to us that the state of the mBuffer
525f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    // might have changed. We might need to check the state of the
526f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    // buffer list and pass a new one depending on the state of our
527f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    // surface
528f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if (reset) {
529f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        const int lnumBufs = mBufferCount;
530f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        android::GraphicBufferMapper &mapper = android::GraphicBufferMapper::get();
531f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        android::Rect bounds(mFrameWidth, mFrameHeight);
532f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        void *y_uv[2];
533f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        CameraBuffer * newBuffers = NULL;
534f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        unsigned int index = 0;
535f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        android::KeyedVector<void*, int> missingIndices;
536f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
537f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        newBuffers = new CameraBuffer [lnumBufs];
538f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        memset (newBuffers, 0, sizeof(CameraBuffer) * lnumBufs);
539f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
540f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        // Use this vector to figure out missing indices
541f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        for (int i = 0; i < mBufferCount; i++) {
542f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            missingIndices.add(mBuffers[i].opaque, i);
543f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        }
544f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
545f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        // assign buffers that we have already dequeued
546f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        for (index = 0; index < mFramesWithCameraAdapterMap.size(); index++) {
547f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            int value = mFramesWithCameraAdapterMap.valueAt(index);
548f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            newBuffers[index].opaque = mBuffers[value].opaque;
549f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            newBuffers[index].type = mBuffers[value].type;
550f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            newBuffers[index].format = mBuffers[value].format;
551f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            newBuffers[index].mapped = mBuffers[value].mapped;
552f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            mFramesWithCameraAdapterMap.replaceValueAt(index, index);
553f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            missingIndices.removeItem(newBuffers[index].opaque);
554f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        }
555f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
556f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        mBufferSource->get_min_undequeued_buffer_count(mBufferSource, &undequeued);
557f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
558f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        // dequeue the rest of the buffers
559f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        for (index; index < (unsigned int)(mBufferCount-undequeued); index++) {
560f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            buffer_handle_t *handle;
561f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            int stride;  // dummy variable to get stride
562f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
563f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            err = mBufferSource->dequeue_buffer(mBufferSource, &handle, &stride);
564f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            if (err != 0) {
565f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                CAMHAL_LOGEB("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
566f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                if ( ENODEV == err ) {
567f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                    CAMHAL_LOGEA("Preview surface abandoned!");
568f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                    mBufferSource = NULL;
569f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                }
570f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                goto fail;
571f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            }
572f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            newBuffers[index].opaque = (void *)handle;
573f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            newBuffers[index].type = CAMERA_BUFFER_ANW;
574f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            newBuffers[index].format = mPixelFormat;
575f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            mFramesWithCameraAdapterMap.add(handle, index);
576f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
577f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            mBufferSource->lock_buffer(mBufferSource, handle);
578f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            mapper.lock(*handle, CAMHAL_GRALLOC_USAGE, bounds, y_uv);
579f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            newBuffers[index].mapped = y_uv[0];
580f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            CAMHAL_LOGDB("got handle %p", handle);
581f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
582f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            missingIndices.removeItem(newBuffers[index].opaque);
583f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        }
584f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
585f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        // now we need to figure out which buffers aren't dequeued
586f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        // which are in mBuffers but not newBuffers yet
587f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        if ((mBufferCount - index) != missingIndices.size()) {
588f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            CAMHAL_LOGD("Hrmm somethings gone awry. We are missing a different number"
589f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                        " of buffers than we can fill");
590f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        }
591f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        for (unsigned int i = 0; i < missingIndices.size(); i++) {
592f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            int j = missingIndices.valueAt(i);
593f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
594f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            CAMHAL_LOGD("Filling at %d", j);
595f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            newBuffers[index].opaque = mBuffers[j].opaque;
596f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            newBuffers[index].type = mBuffers[j].type;
597f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            newBuffers[index].format = mBuffers[j].format;
598f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            newBuffers[index].mapped = mBuffers[j].mapped;
599f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        }
600f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
601f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        delete [] mBuffers;
602f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        mBuffers = newBuffers;
603f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
604f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
605f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    return mBuffers;
606f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
607f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons fail:
608f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    return NULL;
609f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons}
610f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
611f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmonsunsigned int BufferSourceAdapter::getSize() {
612f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    android::Mutex::Autolock lock(mLock);
613f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    return CameraHal::calculateBufferSize(mPixelFormat, mFrameWidth, mFrameHeight);
614f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons}
615f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
616f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmonsint BufferSourceAdapter::getBufferCount() {
617f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    int count = -1;
618f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
619f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    android::Mutex::Autolock lock(mLock);
6201d40b78f3a968634194f0c1d878d1ba122f435d7Tyler Luu    if (mBufferSource) extendedOps()->get_buffer_count(mBufferSource, &count);
6211d40b78f3a968634194f0c1d878d1ba122f435d7Tyler Luu    return count;
622f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons}
623f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
624f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason SimmonsCameraBuffer* BufferSourceAdapter::getBufferList(int *num) {
625f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    LOG_FUNCTION_NAME;
626f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    status_t err;
627f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    const int lnumBufs = 1;
628f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    int formatSource;
629f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    android::GraphicBufferMapper &mapper = android::GraphicBufferMapper::get();
630f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    buffer_handle_t *handle;
631f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
632f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    // TODO(XXX): Only supporting one input buffer at a time right now
633f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    *num = 1;
634f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    mBuffers = new CameraBuffer [lnumBufs];
635f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    memset (mBuffers, 0, sizeof(CameraBuffer) * lnumBufs);
636f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
637f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if ( NULL == mBufferSource ) {
638f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        return NULL;
639f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
640f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
641f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    err = extendedOps()->update_and_get_buffer(mBufferSource, &handle, &mBuffers[0].stride);
642f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if (err != 0) {
643f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        CAMHAL_LOGEB("update and get buffer failed: %s (%d)", strerror(-err), -err);
644f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        if ( ENODEV == err ) {
645f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            CAMHAL_LOGEA("Preview surface abandoned!");
646f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            mBufferSource = NULL;
647f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        }
648f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        goto fail;
649f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
650f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
651f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    CAMHAL_LOGD("got handle %p", handle);
652f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    mBuffers[0].opaque = (void *)handle;
653f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    mBuffers[0].type = CAMERA_BUFFER_ANW;
654f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    mFramesWithCameraAdapterMap.add(handle, 0);
655f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
656f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    err = extendedOps()->get_buffer_dimension(mBufferSource, &mBuffers[0].width, &mBuffers[0].height);
657f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    err = extendedOps()->get_buffer_format(mBufferSource, &formatSource);
658f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
65911308f1fc42a01958b9c13fad908141028fda9adEmilian Peev    int t, l, r, b, w, h;
66011308f1fc42a01958b9c13fad908141028fda9adEmilian Peev    err = extendedOps()->get_crop(mBufferSource, &l, &t, &r, &b);
66111308f1fc42a01958b9c13fad908141028fda9adEmilian Peev    err = extendedOps()->get_current_size(mBufferSource, &w, &h);
66211308f1fc42a01958b9c13fad908141028fda9adEmilian Peev
663f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    // lock buffer
664f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    {
665f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        void *y_uv[2];
666f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        android::Rect bounds(mBuffers[0].width, mBuffers[0].height);
667f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        mapper.lock(*handle, CAMHAL_GRALLOC_USAGE, bounds, y_uv);
668f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        mBuffers[0].mapped = y_uv[0];
669f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
670f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
671f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    mFrameWidth = mBuffers[0].width;
672f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    mFrameHeight = mBuffers[0].height;
673f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    mPixelFormat = getFormatFromANW(formatSource);
674f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
675f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    mBuffers[0].format = mPixelFormat;
67611308f1fc42a01958b9c13fad908141028fda9adEmilian Peev    mBuffers[0].actual_size = CameraHal::calculateBufferSize(mPixelFormat, w, h);
67711308f1fc42a01958b9c13fad908141028fda9adEmilian Peev    mBuffers[0].offset = t * w + l * CameraHal::getBPP(mPixelFormat);
678f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    mBufferSourceDirection = BUFFER_SOURCE_TAP_IN;
679f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
680f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    return mBuffers;
681f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
682f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons fail:
683f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    // need to cancel buffers if any were dequeued
684f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    freeBufferList(mBuffers);
685f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
686f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if (NULL != mErrorNotifier.get()) {
687f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        mErrorNotifier->errorNotify(-ENOMEM);
688f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
689f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
690f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    LOG_FUNCTION_NAME_EXIT;
691f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    return NULL;
692f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons}
693f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
694f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmonsuint32_t * BufferSourceAdapter::getOffsets()
695f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons{
696f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    LOG_FUNCTION_NAME;
697f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
698f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    LOG_FUNCTION_NAME_EXIT;
699f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
700f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    return NULL;
701f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons}
702f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
703f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmonsint BufferSourceAdapter::minUndequeueableBuffers(int& undequeueable) {
704f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    LOG_FUNCTION_NAME;
705f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    int ret = NO_ERROR;
706f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
707f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if(!mBufferSource)
708f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    {
709f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        ret = INVALID_OPERATION;
710f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        goto end;
711f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
712f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
713f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    ret = mBufferSource->get_min_undequeued_buffer_count(mBufferSource, &undequeueable);
714f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if ( NO_ERROR != ret ) {
715f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        CAMHAL_LOGEB("get_min_undequeued_buffer_count failed: %s (%d)", strerror(-ret), -ret);
716f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        if ( ENODEV == ret ) {
717f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            CAMHAL_LOGEA("Preview surface abandoned!");
718f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            mBufferSource = NULL;
719f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        }
720f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        return -ret;
721f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
722f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
723f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons end:
724f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    return ret;
725f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    LOG_FUNCTION_NAME_EXIT;
726f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
727f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons}
728f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
729f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmonsint BufferSourceAdapter::maxQueueableBuffers(unsigned int& queueable)
730f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons{
731f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    LOG_FUNCTION_NAME;
732f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    int ret = NO_ERROR;
733f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    int undequeued = 0;
734f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
735f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if(mBufferCount == 0) {
736f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        ret = INVALID_OPERATION;
737f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        goto end;
738f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
739f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
740f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    ret = minUndequeueableBuffers(undequeued);
741f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if (ret != NO_ERROR) {
742f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        goto end;
743f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
744f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
745f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    queueable = mBufferCount - undequeued;
746f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
747f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons end:
748f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    return ret;
749f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    LOG_FUNCTION_NAME_EXIT;
750f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons}
751f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
752f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmonsint BufferSourceAdapter::getFd()
753f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons{
754f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    LOG_FUNCTION_NAME;
755f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
756f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    LOG_FUNCTION_NAME_EXIT;
757f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
758f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    return -1;
759f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
760f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons}
761f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
762f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmonsstatus_t BufferSourceAdapter::returnBuffersToWindow()
763f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons{
764f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    status_t ret = NO_ERROR;
765f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    android::GraphicBufferMapper &mapper = android::GraphicBufferMapper::get();
766f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
767f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    //Give the buffers back to display here -  sort of free it
768f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if (mBufferSource) {
769f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        for(unsigned int i = 0; i < mFramesWithCameraAdapterMap.size(); i++) {
770f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            int value = mFramesWithCameraAdapterMap.valueAt(i);
771f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            buffer_handle_t *handle = (buffer_handle_t *) mBuffers[value].opaque;
772f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
773f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            // if buffer index is out of bounds skip
774f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            if ((value < 0) || (value >= mBufferCount)) {
775f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                CAMHAL_LOGEA("Potential out bounds access to handle...skipping");
776f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                continue;
777f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            }
778f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
779f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            // unlock buffer before giving it up
780f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            mapper.unlock(*handle);
781f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
782f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            ret = mBufferSource->cancel_buffer(mBufferSource, handle);
783f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            if ( ENODEV == ret ) {
784f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                CAMHAL_LOGEA("Preview surface abandoned!");
785f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                mBufferSource = NULL;
786f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                return -ret;
787f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            } else if ( NO_ERROR != ret ) {
788f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                CAMHAL_LOGEB("cancel_buffer() failed: %s (%d)",
789f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                              strerror(-ret),
790f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                              -ret);
791f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                return -ret;
792f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            }
793f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        }
794f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    } else {
795f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons         CAMHAL_LOGE("mBufferSource is NULL");
796f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
797f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
798f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons     ///Clear the frames with camera adapter map
799f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons     mFramesWithCameraAdapterMap.clear();
800f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
801f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons     return ret;
802f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
803f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons}
804f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
805f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmonsint BufferSourceAdapter::freeBufferList(CameraBuffer * buflist)
806f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons{
807f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    LOG_FUNCTION_NAME;
808f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
809f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    status_t ret = NO_ERROR;
810f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
8117623df0b09b71fa3aef507afb3015a77c445877aEmilian Peev    if ( mBuffers != buflist ) {
8127623df0b09b71fa3aef507afb3015a77c445877aEmilian Peev        return BAD_VALUE;
8137623df0b09b71fa3aef507afb3015a77c445877aEmilian Peev    }
8147623df0b09b71fa3aef507afb3015a77c445877aEmilian Peev
815f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    android::AutoMutex lock(mLock);
816f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
817f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if (mBufferSourceDirection == BUFFER_SOURCE_TAP_OUT) returnBuffersToWindow();
818f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
819f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if( mBuffers != NULL)
820f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    {
821f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        delete [] mBuffers;
822f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        mBuffers = NULL;
823f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
824f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
825f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    return NO_ERROR;
826f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons}
827f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
828f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
829f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmonsbool BufferSourceAdapter::supportsExternalBuffering()
830f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons{
831f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    return false;
832f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons}
833f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
834f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmonsvoid BufferSourceAdapter::addFrame(CameraFrame* frame)
835f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons{
836f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if (mQueueFrame.get()) {
837f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        mQueueFrame->addFrame(frame);
838f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
839f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons}
840f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
841f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmonsvoid BufferSourceAdapter::handleFrameCallback(CameraFrame* frame)
842f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons{
843f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    status_t ret = NO_ERROR;
844f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    buffer_handle_t *handle = NULL;
845f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    int i;
846f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    uint32_t x, y;
847f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    android::GraphicBufferMapper &mapper = android::GraphicBufferMapper::get();
848f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
849f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    android::AutoMutex lock(mLock);
850f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
851f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if (!mBuffers || !frame->mBuffer) {
852f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        CAMHAL_LOGEA("Adapter sent BufferSourceAdapter a NULL frame?");
853f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        return;
854f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
855f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
856f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    for ( i = 0; i < mBufferCount; i++ ) {
857f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        if (frame->mBuffer == &mBuffers[i]) {
858f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            break;
859f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        }
860f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
861f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
862f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if (i >= mBufferCount) {
863f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        CAMHAL_LOGD("Can't find frame in buffer list");
864f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        if (frame->mFrameType != CameraFrame::REPROCESS_INPUT_FRAME) {
865f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            mFrameProvider->returnFrame(frame->mBuffer,
866f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                    static_cast<CameraFrame::FrameType>(frame->mFrameType));
867f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        }
868f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        return;
869f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
870f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
871f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    handle = (buffer_handle_t *) mBuffers[i].opaque;
872f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
873f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    // Handle input buffers
874f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    // TODO(XXX): Move handling of input buffers out of here if
875f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    // it becomes more complex
876f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if (frame->mFrameType == CameraFrame::REPROCESS_INPUT_FRAME) {
877f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        CAMHAL_LOGD("Unlock %p (buffer #%d)", handle, i);
878f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        mapper.unlock(*handle);
879f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        return;
880f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
881f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
882f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    CameraHal::getXYFromOffset(&x, &y, frame->mOffset, frame->mAlignment, mPixelFormat);
883f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    CAMHAL_LOGVB("offset = %u left = %d top = %d right = %d bottom = %d",
884f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                  frame->mOffset, x, y, x + frame->mWidth, y + frame->mHeight);
885f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    ret = mBufferSource->set_crop(mBufferSource, x, y, x + frame->mWidth, y + frame->mHeight);
886f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if (NO_ERROR != ret) {
887f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        CAMHAL_LOGE("mBufferSource->set_crop returned error %d", ret);
8887623df0b09b71fa3aef507afb3015a77c445877aEmilian Peev        goto fail;
889f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
890f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
891f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if ( NULL != frame->mMetaData.get() ) {
892f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        camera_memory_t *extMeta = frame->mMetaData->getExtendedMetadata();
893f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        if ( NULL != extMeta ) {
894f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            camera_metadata_t *metaData = static_cast<camera_metadata_t *> (extMeta->data);
895f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            metaData->timestamp = frame->mTimestamp;
896f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            ret = extendedOps()->set_metadata(mBufferSource, extMeta);
897f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            if (ret != 0) {
898f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                CAMHAL_LOGE("Surface::set_metadata returned error %d", ret);
8997623df0b09b71fa3aef507afb3015a77c445877aEmilian Peev                goto fail;
900f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            }
901f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        }
902f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
903f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
904f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    // unlock buffer before enqueueing
905f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    mapper.unlock(*handle);
906f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
907f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    ret = mBufferSource->enqueue_buffer(mBufferSource, handle);
908f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if (ret != 0) {
909f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        CAMHAL_LOGE("Surface::queueBuffer returned error %d", ret);
9107623df0b09b71fa3aef507afb3015a77c445877aEmilian Peev        goto fail;
911f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
912f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
913f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    mFramesWithCameraAdapterMap.removeItem((buffer_handle_t *) frame->mBuffer->opaque);
9147623df0b09b71fa3aef507afb3015a77c445877aEmilian Peev
9157623df0b09b71fa3aef507afb3015a77c445877aEmilian Peev    return;
9167623df0b09b71fa3aef507afb3015a77c445877aEmilian Peev
9177623df0b09b71fa3aef507afb3015a77c445877aEmilian Peevfail:
9187623df0b09b71fa3aef507afb3015a77c445877aEmilian Peev    mFramesWithCameraAdapterMap.clear();
9197623df0b09b71fa3aef507afb3015a77c445877aEmilian Peev    mBufferSource = NULL;
9207623df0b09b71fa3aef507afb3015a77c445877aEmilian Peev    mReturnFrame->requestExit();
9217623df0b09b71fa3aef507afb3015a77c445877aEmilian Peev    mQueueFrame->requestExit();
922f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons}
923f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
924f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
925f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmonsbool BufferSourceAdapter::handleFrameReturn()
926f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons{
927f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    status_t err;
928f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    buffer_handle_t *buf;
929f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    int i = 0;
930f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    int stride;  // dummy variable to get stride
931f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    CameraFrame::FrameType type;
932f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    android::GraphicBufferMapper &mapper = android::GraphicBufferMapper::get();
933f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    void *y_uv[2];
934f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    android::Rect bounds(mFrameWidth, mFrameHeight);
935f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
936f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    android::AutoMutex lock(mLock);
937f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
938f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if ( (NULL == mBufferSource) || (NULL == mBuffers) ) {
939f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        return false;
940f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
941f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
942f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    err = mBufferSource->dequeue_buffer(mBufferSource, &buf, &stride);
943f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if (err != 0) {
944f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        CAMHAL_LOGEB("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
945f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
946f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        if ( ENODEV == err ) {
947f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            CAMHAL_LOGEA("Preview surface abandoned!");
948f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            mBufferSource = NULL;
949f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        }
950f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
951f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        return false;
952f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
953f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
954f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    err = mBufferSource->lock_buffer(mBufferSource, buf);
955f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if (err != 0) {
956f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        CAMHAL_LOGEB("lockbuffer failed: %s (%d)", strerror(-err), -err);
957f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
958f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        if ( ENODEV == err ) {
959f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            CAMHAL_LOGEA("Preview surface abandoned!");
960f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            mBufferSource = NULL;
961f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        }
962f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
963f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        return false;
964f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
965f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
966f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    mapper.lock(*buf, CAMHAL_GRALLOC_USAGE, bounds, y_uv);
967f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
968f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    for(i = 0; i < mBufferCount; i++) {
969f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        if (mBuffers[i].opaque == buf)
970f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            break;
971f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
972f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
973f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if (i >= mBufferCount) {
974f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        CAMHAL_LOGEB("Failed to find handle %p", buf);
975f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
976f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
977f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    mFramesWithCameraAdapterMap.add((buffer_handle_t *) mBuffers[i].opaque, i);
978f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
979f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    CAMHAL_LOGVB("handleFrameReturn: found graphic buffer %d of %d", i, mBufferCount - 1);
980f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
981f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    mFrameProvider->returnFrame(&mBuffers[i], formatToOutputFrameType(mPixelFormat));
982f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    return true;
983f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons}
984f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
985f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmonsvoid BufferSourceAdapter::frameCallback(CameraFrame* caFrame)
986f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons{
987f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if ((NULL != caFrame) && (NULL != caFrame->mCookie)) {
988f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        BufferSourceAdapter *da = (BufferSourceAdapter*) caFrame->mCookie;
989f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        da->addFrame(caFrame);
990f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    } else {
991f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        CAMHAL_LOGEB("Invalid Cookie in Camera Frame = %p, Cookie = %p",
992f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                    caFrame, caFrame ? caFrame->mCookie : NULL);
993f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
994f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons}
995f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
996f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons/*--------------------BufferSourceAdapter Class ENDS here-----------------------------*/
997f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
998f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons} // namespace Camera
999f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons} // namespace Ti
1000f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
1001f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons#endif
1002