1c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev/*
2c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * Copyright (C) Texas Instruments - http://www.ti.com/
3c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev *
4c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * Licensed under the Apache License, Version 2.0 (the "License");
5c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * you may not use this file except in compliance with the License.
6c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * You may obtain a copy of the License at
7c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev *
8c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev *      http://www.apache.org/licenses/LICENSE-2.0
9c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev *
10c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * Unless required by applicable law or agreed to in writing, software
11c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * distributed under the License is distributed on an "AS IS" BASIS,
12c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * See the License for the specific language governing permissions and
14c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * limitations under the License.
15c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev */
16c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
17c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
18c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
19c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
20c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#define LOG_TAG "CameraHAL"
21c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
22c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
23c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#include "CameraHal.h"
24c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#include "VideoMetadata.h"
25ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu#include "Encoder_libjpeg.h"
26c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#include <MetadataBufferType.h>
27c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#include <ui/GraphicBuffer.h>
28c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#include <ui/GraphicBufferMapper.h>
2972b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng#include "NV12_resize.h"
3072b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng
31c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevnamespace android {
32c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
33c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevconst int AppCallbackNotifier::NOTIFIER_TIMEOUT = -1;
348e52e3bcc31f65a699c25557cf3026d324e631b4Tyler LuuKeyedVector<void*, sp<Encoder_libjpeg> > gEncoderQueue;
35c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
36c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luuvoid AppCallbackNotifierEncoderCallback(void* main_jpeg,
37c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu                                        void* thumb_jpeg,
38ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu                                        CameraFrame::FrameType type,
39ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu                                        void* cookie1,
40ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu                                        void* cookie2,
410c7ae887ee41852f275887fd543fae810668e2d1Tyler Luu                                        void* cookie3,
420c7ae887ee41852f275887fd543fae810668e2d1Tyler Luu                                        bool canceled)
43ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu{
440c7ae887ee41852f275887fd543fae810668e2d1Tyler Luu    if (cookie1 && !canceled) {
45ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu        AppCallbackNotifier* cb = (AppCallbackNotifier*) cookie1;
46c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu        cb->EncoderDoneCb(main_jpeg, thumb_jpeg, type, cookie2, cookie3);
47ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu    }
480c7ae887ee41852f275887fd543fae810668e2d1Tyler Luu
490c7ae887ee41852f275887fd543fae810668e2d1Tyler Luu    if (main_jpeg) {
500c7ae887ee41852f275887fd543fae810668e2d1Tyler Luu        free(main_jpeg);
510c7ae887ee41852f275887fd543fae810668e2d1Tyler Luu    }
520c7ae887ee41852f275887fd543fae810668e2d1Tyler Luu
530c7ae887ee41852f275887fd543fae810668e2d1Tyler Luu    if (thumb_jpeg) {
540c7ae887ee41852f275887fd543fae810668e2d1Tyler Luu       if (((Encoder_libjpeg::params *) thumb_jpeg)->dst) {
550c7ae887ee41852f275887fd543fae810668e2d1Tyler Luu           free(((Encoder_libjpeg::params *) thumb_jpeg)->dst);
560c7ae887ee41852f275887fd543fae810668e2d1Tyler Luu       }
570c7ae887ee41852f275887fd543fae810668e2d1Tyler Luu       free(thumb_jpeg);
580c7ae887ee41852f275887fd543fae810668e2d1Tyler Luu    }
59ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu}
60ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu
61c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev/*--------------------NotificationHandler Class STARTS here-----------------------------*/
62c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
63c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luuvoid AppCallbackNotifier::EncoderDoneCb(void* main_jpeg, void* thumb_jpeg, CameraFrame::FrameType type, void* cookie1, void* cookie2)
64ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu{
65ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu    camera_memory_t* encoded_mem = NULL;
66c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu    Encoder_libjpeg::params *main_param = NULL, *thumb_param = NULL;
67c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu    size_t jpeg_size;
68c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu    uint8_t* src = NULL;
698e52e3bcc31f65a699c25557cf3026d324e631b4Tyler Luu    sp<Encoder_libjpeg> encoder = NULL;
70ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu
71ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu    LOG_FUNCTION_NAME;
72ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu
737207ddb84b57c01ea50c5af85dc4a3984b364deaSundar Raman    camera_memory_t* picture = NULL;
747207ddb84b57c01ea50c5af85dc4a3984b364deaSundar Raman
757207ddb84b57c01ea50c5af85dc4a3984b364deaSundar Raman    {
76ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu    Mutex::Autolock lock(mLock);
77ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu
78c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu    if (!main_jpeg) {
79c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu        goto exit;
80c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu    }
81ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu
82c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu    encoded_mem = (camera_memory_t*) cookie1;
83c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu    main_param = (Encoder_libjpeg::params *) main_jpeg;
84c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu    jpeg_size = main_param->jpeg_size;
85c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu    src = main_param->src;
86ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu
87c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu    if(encoded_mem && encoded_mem->data && (jpeg_size > 0)) {
8836e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu        if (cookie2) {
8936e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu            ExifElementsTable* exif = (ExifElementsTable*) cookie2;
9036e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu            Section_t* exif_section = NULL;
9136e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu
9236e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu            exif->insertExifToJpeg((unsigned char*) encoded_mem->data, jpeg_size);
93c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu
94c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu            if(thumb_jpeg) {
95c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu                thumb_param = (Encoder_libjpeg::params *) thumb_jpeg;
96c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu                exif->insertExifThumbnailImage((const char*)thumb_param->dst,
97c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu                                               (int)thumb_param->jpeg_size);
98c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu            }
99c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu
10036e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu            exif_section = FindSection(M_EXIF);
10136e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu
10236e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu            if (exif_section) {
10336e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu                picture = mRequestMemory(-1, jpeg_size + exif_section->Size, 1, NULL);
10436e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu                if (picture && picture->data) {
10536e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu                    exif->saveJpeg((unsigned char*) picture->data, jpeg_size + exif_section->Size);
10636e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu                }
10736e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu            }
10836e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu            delete exif;
10936e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu            cookie2 = NULL;
11036e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu        } else {
11136e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu            picture = mRequestMemory(-1, jpeg_size, 1, NULL);
11236e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu            if (picture && picture->data) {
11336e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu                memcpy(picture->data, encoded_mem->data, jpeg_size);
11436e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu            }
11536e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu        }
116ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu    }
117c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu    } // scope for mutex lock
118ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu
119c11c07d676f130e6e28ab1611f4862a01a160389Tyler Luu    if (!mRawAvailable) {
120c11c07d676f130e6e28ab1611f4862a01a160389Tyler Luu        dummyRaw();
121c11c07d676f130e6e28ab1611f4862a01a160389Tyler Luu    } else {
122c11c07d676f130e6e28ab1611f4862a01a160389Tyler Luu        mRawAvailable = false;
123c11c07d676f130e6e28ab1611f4862a01a160389Tyler Luu    }
124c11c07d676f130e6e28ab1611f4862a01a160389Tyler Luu
1257207ddb84b57c01ea50c5af85dc4a3984b364deaSundar Raman    // Send the callback to the application only if the notifier is started and the message is enabled
126c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu    if(picture && (mNotifierState==AppCallbackNotifier::NOTIFIER_STARTED) &&
127c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu                  (mCameraHal->msgTypeEnabled(CAMERA_MSG_COMPRESSED_IMAGE)))
128ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu    {
129ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu        Mutex::Autolock lock(mBurstLock);
130ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu#if 0 //TODO: enable burst mode later
131ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu        if ( mBurst )
132ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu        {
133ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu            `(CAMERA_MSG_BURST_IMAGE, JPEGPictureMemBase, mCallbackCookie);
134ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu        }
135ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu        else
136ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu#endif
137ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu        {
138ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu            mDataCb(CAMERA_MSG_COMPRESSED_IMAGE, picture, 0, NULL, mCallbackCookie);
139ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu        }
140ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu    }
141ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu
142c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu exit:
143c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu
144ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu    if (picture) {
145ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu        picture->release(picture);
146ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu    }
147ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu
1488e52e3bcc31f65a699c25557cf3026d324e631b4Tyler Luu    if (mNotifierState == AppCallbackNotifier::NOTIFIER_STARTED) {
1490c7ae887ee41852f275887fd543fae810668e2d1Tyler Luu        if (encoded_mem) {
1500c7ae887ee41852f275887fd543fae810668e2d1Tyler Luu            encoded_mem->release(encoded_mem);
1510c7ae887ee41852f275887fd543fae810668e2d1Tyler Luu        }
1520c7ae887ee41852f275887fd543fae810668e2d1Tyler Luu        if (cookie2) {
1530c7ae887ee41852f275887fd543fae810668e2d1Tyler Luu            delete (ExifElementsTable*) cookie2;
1540c7ae887ee41852f275887fd543fae810668e2d1Tyler Luu        }
1558e52e3bcc31f65a699c25557cf3026d324e631b4Tyler Luu        encoder = gEncoderQueue.valueFor(src);
1568e52e3bcc31f65a699c25557cf3026d324e631b4Tyler Luu        if (encoder.get()) {
1578e52e3bcc31f65a699c25557cf3026d324e631b4Tyler Luu            gEncoderQueue.removeItem(src);
1588e52e3bcc31f65a699c25557cf3026d324e631b4Tyler Luu            encoder.clear();
1598e52e3bcc31f65a699c25557cf3026d324e631b4Tyler Luu        }
1608e52e3bcc31f65a699c25557cf3026d324e631b4Tyler Luu        mFrameProvider->returnFrame(src, type);
1618e52e3bcc31f65a699c25557cf3026d324e631b4Tyler Luu    }
162ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu
163ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu    LOG_FUNCTION_NAME_EXIT;
164ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu}
165ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu
166c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev/**
167c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev  * NotificationHandler class
168c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev  */
169c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
170c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev///Initialization function for AppCallbackNotifier
171c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevstatus_t AppCallbackNotifier::initialize()
172c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
173c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
174c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
175c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mMeasurementEnabled = false;
176c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
177c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    ///Create the app notifier thread
178c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mNotificationThread = new NotificationThread(this);
179c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if(!mNotificationThread.get())
180c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
181c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        CAMHAL_LOGEA("Couldn't create Notification thread");
182c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        return NO_MEMORY;
183c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
184c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
185c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    ///Start the display thread
186c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    status_t ret = mNotificationThread->run("NotificationThread", PRIORITY_URGENT_DISPLAY);
187c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if(ret!=NO_ERROR)
188c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
189c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        CAMHAL_LOGEA("Couldn't run NotificationThread");
190c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mNotificationThread.clear();
191c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        return ret;
192c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
193c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
194c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mUseMetaDataBufferMode = true;
195e6cf8e95b3192621d3b992fbb09df8c58b1a1e5fSundar Raman    mRawAvailable = false;
196c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
197c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
198c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
199c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    return ret;
200c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
201c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
202c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevvoid AppCallbackNotifier::setCallbacks(CameraHal* cameraHal,
203c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                                        camera_notify_callback notify_cb,
204c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                                        camera_data_callback data_cb,
205c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                                        camera_data_timestamp_callback data_cb_timestamp,
206c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                                        camera_request_memory get_memory,
207c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                                        void *user)
208c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
209c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    Mutex::Autolock lock(mLock);
210c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
211c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
212c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
213c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mCameraHal = cameraHal;
214c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mNotifyCb = notify_cb;
215c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mDataCb = data_cb;
216c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mDataCbTimestamp = data_cb_timestamp;
217c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mRequestMemory = get_memory;
218c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mCallbackCookie = user;
219c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
220c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
221c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
222c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
223c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevvoid AppCallbackNotifier::setMeasurements(bool enable)
224c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
225c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    Mutex::Autolock lock(mLock);
226c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
227c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
228c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
229c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mMeasurementEnabled = enable;
230c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
231c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if (  enable  )
232c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
233c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev         mFrameProvider->enableFrameNotification(CameraFrame::FRAME_DATA_SYNC);
234c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
235c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
236c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
237c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
238c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
239c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
240c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev//All sub-components of Camera HAL call this whenever any error happens
241c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevvoid AppCallbackNotifier::errorNotify(int error)
242c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
243c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
244c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
245c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    CAMHAL_LOGEB("AppCallbackNotifier received error %d", error);
246c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
2470ff71809874c00d540af83c123f3dc34759f1871Sundar Raman    // If it is a fatal error abort here!
2480ff71809874c00d540af83c123f3dc34759f1871Sundar Raman    if((error == CAMERA_ERROR_FATAL) || (error == CAMERA_ERROR_HARD)) {
2490ff71809874c00d540af83c123f3dc34759f1871Sundar Raman        //We kill media server if we encounter these errors as there is
2500ff71809874c00d540af83c123f3dc34759f1871Sundar Raman        //no point continuing and apps also don't handle errors other
2510ff71809874c00d540af83c123f3dc34759f1871Sundar Raman        //than media server death always.
2520ff71809874c00d540af83c123f3dc34759f1871Sundar Raman        abort();
2530ff71809874c00d540af83c123f3dc34759f1871Sundar Raman        return;
2540ff71809874c00d540af83c123f3dc34759f1871Sundar Raman    }
2550ff71809874c00d540af83c123f3dc34759f1871Sundar Raman
2566b5eaf29c3d17a24731bf9271bd0d199d433813eAkwasi Boateng    if (  ( NULL != mCameraHal ) &&
2576b5eaf29c3d17a24731bf9271bd0d199d433813eAkwasi Boateng          ( NULL != mNotifyCb ) &&
2586b5eaf29c3d17a24731bf9271bd0d199d433813eAkwasi Boateng          ( mCameraHal->msgTypeEnabled(CAMERA_MSG_ERROR) ) )
2596b5eaf29c3d17a24731bf9271bd0d199d433813eAkwasi Boateng      {
2606b5eaf29c3d17a24731bf9271bd0d199d433813eAkwasi Boateng        CAMHAL_LOGEB("AppCallbackNotifier mNotifyCb %d", error);
2616b5eaf29c3d17a24731bf9271bd0d199d433813eAkwasi Boateng        mNotifyCb(CAMERA_MSG_ERROR, CAMERA_ERROR_UNKNOWN, 0, mCallbackCookie);
2626b5eaf29c3d17a24731bf9271bd0d199d433813eAkwasi Boateng      }
263c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
264c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
265c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
266c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
2673f75fa6e5edf504c155a357494ab77c59b6887b8Tyler Luubool AppCallbackNotifier::notificationThread()
268c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
269c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    bool shouldLive = true;
270c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    status_t ret;
271c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
272c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
273c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
2743f75fa6e5edf504c155a357494ab77c59b6887b8Tyler Luu    //CAMHAL_LOGDA("Notification Thread waiting for message");
2753f75fa6e5edf504c155a357494ab77c59b6887b8Tyler Luu    ret = TIUTILS::MessageQueue::waitForMsg(&mNotificationThread->msgQ(),
2763f75fa6e5edf504c155a357494ab77c59b6887b8Tyler Luu                                            &mEventQ,
2773f75fa6e5edf504c155a357494ab77c59b6887b8Tyler Luu                                            &mFrameQ,
2783f75fa6e5edf504c155a357494ab77c59b6887b8Tyler Luu                                            AppCallbackNotifier::NOTIFIER_TIMEOUT);
279c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
2803f75fa6e5edf504c155a357494ab77c59b6887b8Tyler Luu    //CAMHAL_LOGDA("Notification Thread received message");
281c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
2823f75fa6e5edf504c155a357494ab77c59b6887b8Tyler Luu    if (mNotificationThread->msgQ().hasMsg()) {
2833f75fa6e5edf504c155a357494ab77c59b6887b8Tyler Luu        ///Received a message from CameraHal, process it
2843f75fa6e5edf504c155a357494ab77c59b6887b8Tyler Luu        CAMHAL_LOGDA("Notification Thread received message from Camera HAL");
2853f75fa6e5edf504c155a357494ab77c59b6887b8Tyler Luu        shouldLive = processMessage();
2863f75fa6e5edf504c155a357494ab77c59b6887b8Tyler Luu        if(!shouldLive) {
287bf20bcd681ad3c466099f45334bf639da9baedd0Akwasi Boateng          CAMHAL_LOGDA("Notification Thread exiting.");
288bf20bcd681ad3c466099f45334bf639da9baedd0Akwasi Boateng          return shouldLive;
289c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
2903f75fa6e5edf504c155a357494ab77c59b6887b8Tyler Luu    }
291c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
2923f75fa6e5edf504c155a357494ab77c59b6887b8Tyler Luu    if(mEventQ.hasMsg()) {
2933f75fa6e5edf504c155a357494ab77c59b6887b8Tyler Luu        ///Received an event from one of the event providers
2943f75fa6e5edf504c155a357494ab77c59b6887b8Tyler Luu        CAMHAL_LOGDA("Notification Thread received an event from event provider (CameraAdapter)");
2953f75fa6e5edf504c155a357494ab77c59b6887b8Tyler Luu        notifyEvent();
2963f75fa6e5edf504c155a357494ab77c59b6887b8Tyler Luu     }
297c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
2983f75fa6e5edf504c155a357494ab77c59b6887b8Tyler Luu    if(mFrameQ.hasMsg()) {
2993f75fa6e5edf504c155a357494ab77c59b6887b8Tyler Luu       ///Received a frame from one of the frame providers
3003f75fa6e5edf504c155a357494ab77c59b6887b8Tyler Luu       //CAMHAL_LOGDA("Notification Thread received a frame from frame provider (CameraAdapter)");
3013f75fa6e5edf504c155a357494ab77c59b6887b8Tyler Luu       notifyFrame();
3023f75fa6e5edf504c155a357494ab77c59b6887b8Tyler Luu    }
3033f75fa6e5edf504c155a357494ab77c59b6887b8Tyler Luu
3043f75fa6e5edf504c155a357494ab77c59b6887b8Tyler Luu    LOG_FUNCTION_NAME_EXIT;
3053f75fa6e5edf504c155a357494ab77c59b6887b8Tyler Luu    return shouldLive;
306c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
307c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
308c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevvoid AppCallbackNotifier::notifyEvent()
309c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
310c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    ///Receive and send the event notifications to app
311c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    TIUTILS::Message msg;
312c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
3133ec18006399d61e97382601d14aaa43ee339c8b6Sundar Raman    {
314609bc02b21c725825bd469391e9ecd4e2d462fe1Tyler Luu        Mutex::Autolock lock(mLock);
315609bc02b21c725825bd469391e9ecd4e2d462fe1Tyler Luu        if(!mEventQ.isEmpty()) {
316609bc02b21c725825bd469391e9ecd4e2d462fe1Tyler Luu            mEventQ.get(&msg);
317609bc02b21c725825bd469391e9ecd4e2d462fe1Tyler Luu        } else {
318609bc02b21c725825bd469391e9ecd4e2d462fe1Tyler Luu            return;
319609bc02b21c725825bd469391e9ecd4e2d462fe1Tyler Luu        }
3203ec18006399d61e97382601d14aaa43ee339c8b6Sundar Raman    }
321c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    bool ret = true;
322c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    CameraHalEvent *evt = NULL;
323c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    CameraHalEvent::FocusEventData *focusEvtData;
324c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    CameraHalEvent::ZoomEventData *zoomEvtData;
325c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    CameraHalEvent::FaceEventData faceEvtData;
326c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
327c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if(mNotifierState != AppCallbackNotifier::NOTIFIER_STARTED)
328c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    {
329c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        return;
330c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
331c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
332c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    switch(msg.command)
333c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
334c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        case AppCallbackNotifier::NOTIFIER_CMD_PROCESS_EVENT:
335c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
336c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            evt = ( CameraHalEvent * ) msg.arg1;
337c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
338c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            if ( NULL == evt )
339c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                {
340c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                CAMHAL_LOGEA("Invalid CameraHalEvent");
341c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                return;
342c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                }
343c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
344c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            switch(evt->mEventType)
345c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                {
346c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                case CameraHalEvent::EVENT_SHUTTER:
347c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
348c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    if ( ( NULL != mCameraHal ) &&
349c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                          ( NULL != mNotifyCb ) &&
350c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                          ( mCameraHal->msgTypeEnabled(CAMERA_MSG_SHUTTER) ) )
351c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                        {
352c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                            mNotifyCb(CAMERA_MSG_SHUTTER, 0, 0, mCallbackCookie);
353c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                        }
354e6cf8e95b3192621d3b992fbb09df8c58b1a1e5fSundar Raman                    mRawAvailable = false;
355c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
356c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    break;
357c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
358c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                case CameraHalEvent::EVENT_FOCUS_LOCKED:
359c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                case CameraHalEvent::EVENT_FOCUS_ERROR:
360c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    focusEvtData = &evt->mEventData->focusEvent;
361057f4fd59ec05ded909e9eb9a3363d9ea345b0caTyler Luu                    if ( ( focusEvtData->focusStatus == CameraHalEvent::FOCUS_STATUS_SUCCESS ) &&
362057f4fd59ec05ded909e9eb9a3363d9ea345b0caTyler Luu                         ( NULL != mCameraHal ) &&
363057f4fd59ec05ded909e9eb9a3363d9ea345b0caTyler Luu                         ( NULL != mNotifyCb ) &&
364057f4fd59ec05ded909e9eb9a3363d9ea345b0caTyler Luu                         ( mCameraHal->msgTypeEnabled(CAMERA_MSG_FOCUS) ) )
365c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                        {
3662ecb39c0ca21ce9ae00c4585e3f7002e8b4e6ca7Tyler Luu                         mCameraHal->disableMsgType(CAMERA_MSG_FOCUS);
367a6e104aadf560de4e33291c8e85f79acc8fb46c9Tyler Luu                         mNotifyCb(CAMERA_MSG_FOCUS, true, 0, mCallbackCookie);
368c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                        }
369057f4fd59ec05ded909e9eb9a3363d9ea345b0caTyler Luu                    else if ( ( focusEvtData->focusStatus == CameraHalEvent::FOCUS_STATUS_FAIL ) &&
370057f4fd59ec05ded909e9eb9a3363d9ea345b0caTyler Luu                              ( NULL != mCameraHal ) &&
371057f4fd59ec05ded909e9eb9a3363d9ea345b0caTyler Luu                              ( NULL != mNotifyCb ) &&
372057f4fd59ec05ded909e9eb9a3363d9ea345b0caTyler Luu                              ( mCameraHal->msgTypeEnabled(CAMERA_MSG_FOCUS) ) )
373c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                        {
3742ecb39c0ca21ce9ae00c4585e3f7002e8b4e6ca7Tyler Luu                         mCameraHal->disableMsgType(CAMERA_MSG_FOCUS);
375a6e104aadf560de4e33291c8e85f79acc8fb46c9Tyler Luu                         mNotifyCb(CAMERA_MSG_FOCUS, false, 0, mCallbackCookie);
376c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                        }
377057f4fd59ec05ded909e9eb9a3363d9ea345b0caTyler Luu                    else if ( ( focusEvtData->focusStatus == CameraHalEvent::FOCUS_STATUS_PENDING ) &&
378057f4fd59ec05ded909e9eb9a3363d9ea345b0caTyler Luu                              ( NULL != mCameraHal ) &&
379057f4fd59ec05ded909e9eb9a3363d9ea345b0caTyler Luu                              ( NULL != mNotifyCb ) &&
380057f4fd59ec05ded909e9eb9a3363d9ea345b0caTyler Luu                              ( mCameraHal->msgTypeEnabled(CAMERA_MSG_FOCUS_MOVE) ) )
381057f4fd59ec05ded909e9eb9a3363d9ea345b0caTyler Luu                        {
382057f4fd59ec05ded909e9eb9a3363d9ea345b0caTyler Luu                         mNotifyCb(CAMERA_MSG_FOCUS_MOVE, true, 0, mCallbackCookie);
383057f4fd59ec05ded909e9eb9a3363d9ea345b0caTyler Luu                        }
384057f4fd59ec05ded909e9eb9a3363d9ea345b0caTyler Luu                    else if ( ( focusEvtData->focusStatus == CameraHalEvent::FOCUS_STATUS_DONE ) &&
385057f4fd59ec05ded909e9eb9a3363d9ea345b0caTyler Luu                              ( NULL != mCameraHal ) &&
386057f4fd59ec05ded909e9eb9a3363d9ea345b0caTyler Luu                              ( NULL != mNotifyCb ) &&
387057f4fd59ec05ded909e9eb9a3363d9ea345b0caTyler Luu                              ( mCameraHal->msgTypeEnabled(CAMERA_MSG_FOCUS_MOVE) ) )
388057f4fd59ec05ded909e9eb9a3363d9ea345b0caTyler Luu                        {
389057f4fd59ec05ded909e9eb9a3363d9ea345b0caTyler Luu                         mNotifyCb(CAMERA_MSG_FOCUS_MOVE, false, 0, mCallbackCookie);
390057f4fd59ec05ded909e9eb9a3363d9ea345b0caTyler Luu                        }
391c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
392c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    break;
393c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
394c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                case CameraHalEvent::EVENT_ZOOM_INDEX_REACHED:
395c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
396c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    zoomEvtData = &evt->mEventData->zoomEvent;
397c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
398c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    if ( ( NULL != mCameraHal ) &&
399c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                         ( NULL != mNotifyCb) &&
400c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                         ( mCameraHal->msgTypeEnabled(CAMERA_MSG_ZOOM) ) )
401c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                        {
402c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                        mNotifyCb(CAMERA_MSG_ZOOM, zoomEvtData->currentZoomIndex, zoomEvtData->targetZoomIndexReached, mCallbackCookie);
403c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                        }
404c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
405c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    break;
406c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
407c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                case CameraHalEvent::EVENT_FACE:
408c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
409c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    faceEvtData = evt->mEventData->faceEvent;
410c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
411c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    if ( ( NULL != mCameraHal ) &&
412c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                         ( NULL != mNotifyCb) &&
413c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                         ( mCameraHal->msgTypeEnabled(CAMERA_MSG_PREVIEW_METADATA) ) )
414c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                        {
415c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                        // WA for an issue inside CameraService
416c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                        camera_memory_t *tmpBuffer = mRequestMemory(-1, 1, 1, NULL);
417c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
418c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                        mDataCb(CAMERA_MSG_PREVIEW_METADATA,
419c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                                tmpBuffer,
420c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                                0,
421c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                                faceEvtData->getFaceResult(),
422c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                                mCallbackCookie);
423c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
424c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                        faceEvtData.clear();
425c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
426c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                        if ( NULL != tmpBuffer ) {
427c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                            tmpBuffer->release(tmpBuffer);
428c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                        }
429c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
430c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                        }
431c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
432c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    break;
433c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
434c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                case CameraHalEvent::ALL_EVENTS:
435c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    break;
436c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                default:
437c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    break;
438c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                }
439c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
440c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            break;
441c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
442c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
443c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( NULL != evt )
444c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
445c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        delete evt;
446c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
447c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
448c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
449c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
450c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
451c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
452c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
453d822531f1f2b4c0fea1cd971d28bd1e552ed67baEmilian Peevstatic void alignYV12(int width,
454d822531f1f2b4c0fea1cd971d28bd1e552ed67baEmilian Peev                      int height,
455d822531f1f2b4c0fea1cd971d28bd1e552ed67baEmilian Peev                      int &yStride,
456d822531f1f2b4c0fea1cd971d28bd1e552ed67baEmilian Peev                      int &uvStride,
457d822531f1f2b4c0fea1cd971d28bd1e552ed67baEmilian Peev                      int &ySize,
458d822531f1f2b4c0fea1cd971d28bd1e552ed67baEmilian Peev                      int &uvSize,
459d822531f1f2b4c0fea1cd971d28bd1e552ed67baEmilian Peev                      int &size)
460d822531f1f2b4c0fea1cd971d28bd1e552ed67baEmilian Peev{
461d822531f1f2b4c0fea1cd971d28bd1e552ed67baEmilian Peev    yStride = ( width + 0xF ) & ~0xF;
462d822531f1f2b4c0fea1cd971d28bd1e552ed67baEmilian Peev    uvStride = ( yStride / 2 + 0xF ) & ~0xF;
463d822531f1f2b4c0fea1cd971d28bd1e552ed67baEmilian Peev    ySize = yStride * height;
464d822531f1f2b4c0fea1cd971d28bd1e552ed67baEmilian Peev    uvSize = uvStride * height / 2;
465d822531f1f2b4c0fea1cd971d28bd1e552ed67baEmilian Peev    size = ySize + uvSize * 2;
466d822531f1f2b4c0fea1cd971d28bd1e552ed67baEmilian Peev}
467d822531f1f2b4c0fea1cd971d28bd1e552ed67baEmilian Peev
468c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevstatic void copy2Dto1D(void *dst,
469c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                       void *src,
470c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                       int width,
471c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                       int height,
472c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                       size_t stride,
473c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                       uint32_t offset,
474c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                       unsigned int bytesPerPixel,
475c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                       size_t length,
476c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                       const char *pixelFormat)
477c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
478c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    unsigned int alignedRow, row;
479c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    unsigned char *bufferDst, *bufferSrc;
480c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    unsigned char *bufferDstEnd, *bufferSrcEnd;
481c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    uint16_t *bufferSrc_UV;
482c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
4838e88af31129b8cc09675279ca2eac88256d8526bAkwasi Boateng    unsigned int *y_uv = (unsigned int *)src;
484c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
4858e88af31129b8cc09675279ca2eac88256d8526bAkwasi Boateng    CAMHAL_LOGVB("copy2Dto1D() y= %p ; uv=%p.",y_uv[0], y_uv[1]);
4862dc9bc1f87be40c2e4903b97a3df353d0f7c6781Emilian Peev    CAMHAL_LOGVB("pixelFormat= %s; offset=%d", pixelFormat,offset);
487c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
488c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if (pixelFormat!=NULL) {
489c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        if (strcmp(pixelFormat, CameraParameters::PIXEL_FORMAT_YUV422I) == 0) {
490c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            bytesPerPixel = 2;
491baed3f89bba1cbd3720656f7125f25705be38db7Emilian Peev            bufferSrc = ( unsigned char * ) y_uv[0] + offset;
492baed3f89bba1cbd3720656f7125f25705be38db7Emilian Peev            uint32_t xOff = offset % stride;
493baed3f89bba1cbd3720656f7125f25705be38db7Emilian Peev            uint32_t yOff = offset / stride;
494baed3f89bba1cbd3720656f7125f25705be38db7Emilian Peev            uint8_t *bufferSrcUV = ((uint8_t*)y_uv[1] + (stride/2)*yOff + xOff);
495baed3f89bba1cbd3720656f7125f25705be38db7Emilian Peev            uint8_t *bufferSrcUVEven = bufferSrcUV;
496baed3f89bba1cbd3720656f7125f25705be38db7Emilian Peev
497baed3f89bba1cbd3720656f7125f25705be38db7Emilian Peev            uint8_t *bufferDstY = ( uint8_t * ) dst;
498baed3f89bba1cbd3720656f7125f25705be38db7Emilian Peev            uint8_t *bufferDstU = bufferDstY + 1;
499baed3f89bba1cbd3720656f7125f25705be38db7Emilian Peev            uint8_t *bufferDstV = bufferDstY + 3;
500baed3f89bba1cbd3720656f7125f25705be38db7Emilian Peev
501baed3f89bba1cbd3720656f7125f25705be38db7Emilian Peev            // going to convert from NV12 here and return
502baed3f89bba1cbd3720656f7125f25705be38db7Emilian Peev            for ( int i = 0 ; i < height; i ++ ) {
503baed3f89bba1cbd3720656f7125f25705be38db7Emilian Peev                for ( int j = 0 ; j < width / 2 ; j++ ) {
504baed3f89bba1cbd3720656f7125f25705be38db7Emilian Peev
505baed3f89bba1cbd3720656f7125f25705be38db7Emilian Peev                    // Y
506baed3f89bba1cbd3720656f7125f25705be38db7Emilian Peev                    *bufferDstY = *bufferSrc;
507baed3f89bba1cbd3720656f7125f25705be38db7Emilian Peev                    bufferSrc++;
508baed3f89bba1cbd3720656f7125f25705be38db7Emilian Peev                    bufferDstY += 2;
509baed3f89bba1cbd3720656f7125f25705be38db7Emilian Peev
510baed3f89bba1cbd3720656f7125f25705be38db7Emilian Peev                    *bufferDstY = *bufferSrc;
511baed3f89bba1cbd3720656f7125f25705be38db7Emilian Peev                    bufferSrc++;
512baed3f89bba1cbd3720656f7125f25705be38db7Emilian Peev                    bufferDstY += 2;
513baed3f89bba1cbd3720656f7125f25705be38db7Emilian Peev
514baed3f89bba1cbd3720656f7125f25705be38db7Emilian Peev                    // V
515baed3f89bba1cbd3720656f7125f25705be38db7Emilian Peev                    *bufferDstV = *(bufferSrcUV + 1);
516baed3f89bba1cbd3720656f7125f25705be38db7Emilian Peev                    bufferDstV += 4;
517baed3f89bba1cbd3720656f7125f25705be38db7Emilian Peev
518baed3f89bba1cbd3720656f7125f25705be38db7Emilian Peev                    // U
519baed3f89bba1cbd3720656f7125f25705be38db7Emilian Peev                    *bufferDstU = *bufferSrcUV;
520baed3f89bba1cbd3720656f7125f25705be38db7Emilian Peev                    bufferDstU += 4;
521baed3f89bba1cbd3720656f7125f25705be38db7Emilian Peev
522baed3f89bba1cbd3720656f7125f25705be38db7Emilian Peev                    bufferSrcUV += 2;
523baed3f89bba1cbd3720656f7125f25705be38db7Emilian Peev                }
524baed3f89bba1cbd3720656f7125f25705be38db7Emilian Peev                if ( i % 2 ) {
525baed3f89bba1cbd3720656f7125f25705be38db7Emilian Peev                    bufferSrcUV += ( stride - width);
526baed3f89bba1cbd3720656f7125f25705be38db7Emilian Peev                    bufferSrcUVEven = bufferSrcUV;
527baed3f89bba1cbd3720656f7125f25705be38db7Emilian Peev                } else {
528baed3f89bba1cbd3720656f7125f25705be38db7Emilian Peev                    bufferSrcUV = bufferSrcUVEven;
529baed3f89bba1cbd3720656f7125f25705be38db7Emilian Peev                }
530baed3f89bba1cbd3720656f7125f25705be38db7Emilian Peev                bufferSrc += ( stride - width);
531baed3f89bba1cbd3720656f7125f25705be38db7Emilian Peev            }
532baed3f89bba1cbd3720656f7125f25705be38db7Emilian Peev
533baed3f89bba1cbd3720656f7125f25705be38db7Emilian Peev            return;
534c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        } else if (strcmp(pixelFormat, CameraParameters::PIXEL_FORMAT_YUV420SP) == 0 ||
535c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                   strcmp(pixelFormat, CameraParameters::PIXEL_FORMAT_YUV420P) == 0) {
536c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            bytesPerPixel = 1;
537c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            bufferDst = ( unsigned char * ) dst;
538c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            bufferDstEnd = ( unsigned char * ) dst + width*height*bytesPerPixel;
539c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            bufferSrc = ( unsigned char * ) y_uv[0] + offset;
540c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            bufferSrcEnd = ( unsigned char * ) ( ( size_t ) y_uv[0] + length + offset);
541c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            row = width*bytesPerPixel;
542c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            alignedRow = stride-width;
543c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            int stride_bytes = stride / 8;
544c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            uint32_t xOff = offset % stride;
545c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            uint32_t yOff = offset / stride;
546c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
547c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            // going to convert from NV12 here and return
548c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            // Step 1: Y plane: iterate through each row and copy
549c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            for ( int i = 0 ; i < height ; i++) {
550c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                memcpy(bufferDst, bufferSrc, row);
551c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                bufferSrc += stride;
552c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                bufferDst += row;
553c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                if ( ( bufferSrc > bufferSrcEnd ) || ( bufferDst > bufferDstEnd ) ) {
554c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    break;
555c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                }
556c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            }
557c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
558f8a689d36a1b20942e39d848712e99d4a000fa72Sundar Raman            bufferSrc_UV = ( uint16_t * ) ((uint8_t*)y_uv[1] + (stride/2)*yOff + xOff);
559c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
560c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            if (strcmp(pixelFormat, CameraParameters::PIXEL_FORMAT_YUV420SP) == 0) {
561c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                 uint16_t *bufferDst_UV;
562c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
563c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                // Step 2: UV plane: convert NV12 to NV21 by swapping U & V
564c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                bufferDst_UV = (uint16_t *) (((uint8_t*)dst)+row*height);
565c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
566c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                for (int i = 0 ; i < height/2 ; i++, bufferSrc_UV += alignedRow/2) {
567c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    int n = width;
568c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    asm volatile (
569c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    "   pld [%[src], %[src_stride], lsl #2]                         \n\t"
570c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    "   cmp %[n], #32                                               \n\t"
571c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    "   blt 1f                                                      \n\t"
572c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    "0: @ 32 byte swap                                              \n\t"
573c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    "   sub %[n], %[n], #32                                         \n\t"
574c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    "   vld2.8  {q0, q1} , [%[src]]!                                \n\t"
575c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    "   vswp q0, q1                                                 \n\t"
576c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    "   cmp %[n], #32                                               \n\t"
577c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    "   vst2.8  {q0,q1},[%[dst]]!                                   \n\t"
578c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    "   bge 0b                                                      \n\t"
579c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    "1: @ Is there enough data?                                     \n\t"
580c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    "   cmp %[n], #16                                               \n\t"
581c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    "   blt 3f                                                      \n\t"
582c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    "2: @ 16 byte swap                                              \n\t"
583c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    "   sub %[n], %[n], #16                                         \n\t"
584c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    "   vld2.8  {d0, d1} , [%[src]]!                                \n\t"
585c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    "   vswp d0, d1                                                 \n\t"
586c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    "   cmp %[n], #16                                               \n\t"
587c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    "   vst2.8  {d0,d1},[%[dst]]!                                   \n\t"
588c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    "   bge 2b                                                      \n\t"
589c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    "3: @ Is there enough data?                                     \n\t"
590c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    "   cmp %[n], #8                                                \n\t"
591c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    "   blt 5f                                                      \n\t"
592c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    "4: @ 8 byte swap                                               \n\t"
593c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    "   sub %[n], %[n], #8                                          \n\t"
594c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    "   vld2.8  {d0, d1} , [%[src]]!                                \n\t"
595c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    "   vswp d0, d1                                                 \n\t"
596c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    "   cmp %[n], #8                                                \n\t"
597c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    "   vst2.8  {d0[0],d1[0]},[%[dst]]!                             \n\t"
598c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    "   bge 4b                                                      \n\t"
599c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    "5: @ end                                                       \n\t"
600c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#ifdef NEEDS_ARM_ERRATA_754319_754320
601c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    "   vmov s0,s0  @ add noop for errata item                      \n\t"
602c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#endif
603c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    : [dst] "+r" (bufferDst_UV), [src] "+r" (bufferSrc_UV), [n] "+r" (n)
604c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    : [src_stride] "r" (stride_bytes)
605c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    : "cc", "memory", "q0", "q1"
606c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    );
607c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                }
608c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            } else if (strcmp(pixelFormat, CameraParameters::PIXEL_FORMAT_YUV420P) == 0) {
609c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                 uint16_t *bufferDst_U;
610c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                 uint16_t *bufferDst_V;
611c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
612c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                // Step 2: UV plane: convert NV12 to YV12 by de-interleaving U & V
613c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                // TODO(XXX): This version of CameraHal assumes NV12 format it set at
614c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                //            camera adapter to support YV12. Need to address for
615c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                //            USBCamera
616c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
617d822531f1f2b4c0fea1cd971d28bd1e552ed67baEmilian Peev                int yStride, uvStride, ySize, uvSize, size;
618d822531f1f2b4c0fea1cd971d28bd1e552ed67baEmilian Peev                alignYV12(width, height, yStride, uvStride, ySize, uvSize, size);
619d822531f1f2b4c0fea1cd971d28bd1e552ed67baEmilian Peev
620d822531f1f2b4c0fea1cd971d28bd1e552ed67baEmilian Peev                bufferDst_V = (uint16_t *) (((uint8_t*)dst) + ySize);
621d822531f1f2b4c0fea1cd971d28bd1e552ed67baEmilian Peev                bufferDst_U = (uint16_t *) (((uint8_t*)dst) + ySize + uvSize);
622d822531f1f2b4c0fea1cd971d28bd1e552ed67baEmilian Peev                int inc = (uvStride - width/2)/2;
623c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
624c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                for (int i = 0 ; i < height/2 ; i++, bufferSrc_UV += alignedRow/2) {
625c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    int n = width;
626c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    asm volatile (
627c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    "   pld [%[src], %[src_stride], lsl #2]                         \n\t"
628c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    "   cmp %[n], #32                                               \n\t"
629c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    "   blt 1f                                                      \n\t"
630c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    "0: @ 32 byte swap                                              \n\t"
631c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    "   sub %[n], %[n], #32                                         \n\t"
632c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    "   vld2.8  {q0, q1} , [%[src]]!                                \n\t"
633c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    "   cmp %[n], #32                                               \n\t"
634c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    "   vst1.8  {q1},[%[dst_v]]!                                    \n\t"
635c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    "   vst1.8  {q0},[%[dst_u]]!                                    \n\t"
636c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    "   bge 0b                                                      \n\t"
637c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    "1: @ Is there enough data?                                     \n\t"
638c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    "   cmp %[n], #16                                               \n\t"
639c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    "   blt 3f                                                      \n\t"
640c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    "2: @ 16 byte swap                                              \n\t"
641c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    "   sub %[n], %[n], #16                                         \n\t"
642c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    "   vld2.8  {d0, d1} , [%[src]]!                                \n\t"
643c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    "   cmp %[n], #16                                               \n\t"
644c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    "   vst1.8  {d1},[%[dst_v]]!                                    \n\t"
645c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    "   vst1.8  {d0},[%[dst_u]]!                                    \n\t"
646c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    "   bge 2b                                                      \n\t"
647c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    "3: @ Is there enough data?                                     \n\t"
648c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    "   cmp %[n], #8                                                \n\t"
649c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    "   blt 5f                                                      \n\t"
650c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    "4: @ 8 byte swap                                               \n\t"
651c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    "   sub %[n], %[n], #8                                          \n\t"
652c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    "   vld2.8  {d0, d1} , [%[src]]!                                \n\t"
653c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    "   cmp %[n], #8                                                \n\t"
654c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    "   vst1.8  {d1[0]},[%[dst_v]]!                                 \n\t"
655c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    "   vst1.8  {d0[0]},[%[dst_u]]!                                 \n\t"
656c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    "   bge 4b                                                      \n\t"
657c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    "5: @ end                                                       \n\t"
658c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#ifdef NEEDS_ARM_ERRATA_754319_754320
659c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    "   vmov s0,s0  @ add noop for errata item                      \n\t"
660c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#endif
661c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    : [dst_u] "+r" (bufferDst_U), [dst_v] "+r" (bufferDst_V),
662c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                      [src] "+r" (bufferSrc_UV), [n] "+r" (n)
663c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    : [src_stride] "r" (stride_bytes)
664c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    : "cc", "memory", "q0", "q1"
665c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    );
666d822531f1f2b4c0fea1cd971d28bd1e552ed67baEmilian Peev
667d822531f1f2b4c0fea1cd971d28bd1e552ed67baEmilian Peev                    bufferDst_U += inc;
668d822531f1f2b4c0fea1cd971d28bd1e552ed67baEmilian Peev                    bufferDst_V += inc;
669c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                }
670d822531f1f2b4c0fea1cd971d28bd1e552ed67baEmilian Peev
671c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            }
672c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            return ;
673c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
674c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        } else if(strcmp(pixelFormat, CameraParameters::PIXEL_FORMAT_RGB565) == 0) {
675c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            bytesPerPixel = 2;
676c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
677c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
678c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
679c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    bufferDst = ( unsigned char * ) dst;
680c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    bufferSrc = ( unsigned char * ) y_uv[0];
681c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    row = width*bytesPerPixel;
682c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    alignedRow = ( row + ( stride -1 ) ) & ( ~ ( stride -1 ) );
683c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
684c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    //iterate through each row
685c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    for ( int i = 0 ; i < height ; i++,  bufferSrc += alignedRow, bufferDst += row) {
686c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        memcpy(bufferDst, bufferSrc, row);
687c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
688c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
689c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
69026d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luuvoid AppCallbackNotifier::copyAndSendPictureFrame(CameraFrame* frame, int32_t msgType)
69126d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu{
69226d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu    camera_memory_t* picture = NULL;
69326d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu    void *dest = NULL, *src = NULL;
69426d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu
69526d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu    // scope for lock
69626d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu    {
69726d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu        Mutex::Autolock lock(mLock);
69826d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu
69926d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu        if(mNotifierState != AppCallbackNotifier::NOTIFIER_STARTED) {
70026d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu            goto exit;
70126d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu        }
70226d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu
70326d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu        picture = mRequestMemory(-1, frame->mLength, 1, NULL);
70426d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu
70526d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu        if (NULL != picture) {
70626d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu            dest = picture->data;
70726d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu            if (NULL != dest) {
70826d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu                src = (void *) ((unsigned int) frame->mBuffer + frame->mOffset);
70926d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu                memcpy(dest, src, frame->mLength);
71026d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu            }
71126d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu        }
71226d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu    }
71326d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu
71426d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu exit:
71526d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu    mFrameProvider->returnFrame(frame->mBuffer, (CameraFrame::FrameType) frame->mFrameType);
71626d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu
71726d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu    if(picture) {
71826d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu        if((mNotifierState == AppCallbackNotifier::NOTIFIER_STARTED) &&
71926d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu           mCameraHal->msgTypeEnabled(msgType)) {
72026d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu            mDataCb(msgType, picture, 0, NULL, mCallbackCookie);
72126d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu        }
72226d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu        picture->release(picture);
72326d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu    }
72426d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu}
72526d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu
72626d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luuvoid AppCallbackNotifier::copyAndSendPreviewFrame(CameraFrame* frame, int32_t msgType)
72726d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu{
72826d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu    camera_memory_t* picture = NULL;
72926d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu    void* dest = NULL;
73026d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu
73126d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu    // scope for lock
73226d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu    {
73326d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu        Mutex::Autolock lock(mLock);
73426d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu
73526d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu        if(mNotifierState != AppCallbackNotifier::NOTIFIER_STARTED) {
73626d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu            goto exit;
73726d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu        }
73826d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu
73926d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu        if (!mPreviewMemory || !frame->mBuffer) {
74026d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu            CAMHAL_LOGDA("Error! One of the buffer is NULL");
74126d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu            goto exit;
74226d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu        }
74326d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu
74426d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu
74526d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu        dest = (void*) mPreviewBufs[mPreviewBufCount];
74626d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu
74726d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu        CAMHAL_LOGVB("%d:copy2Dto1D(%p, %p, %d, %d, %d, %d, %d,%s)",
74826d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu                     __LINE__,
74926d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu                      buf,
75026d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu                      frame->mBuffer,
75126d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu                      frame->mWidth,
75226d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu                      frame->mHeight,
75326d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu                      frame->mAlignment,
75426d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu                      2,
75526d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu                      frame->mLength,
75626d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu                      mPreviewPixelFormat);
75726d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu
75826d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu        if ( NULL != dest ) {
75926d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu            // data sync frames don't need conversion
76026d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu            if (CameraFrame::FRAME_DATA_SYNC == frame->mFrameType) {
76126d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu                if ( (mPreviewMemory->size / MAX_BUFFERS) >= frame->mLength ) {
76226d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu                    memcpy(dest, (void*) frame->mBuffer, frame->mLength);
76326d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu                } else {
76426d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu                    memset(dest, 0, (mPreviewMemory->size / MAX_BUFFERS));
76526d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu                }
76626d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu            } else {
7678e88af31129b8cc09675279ca2eac88256d8526bAkwasi Boateng              if ((NULL == frame->mYuv[0]) || (NULL == frame->mYuv[1])){
7688e88af31129b8cc09675279ca2eac88256d8526bAkwasi Boateng                CAMHAL_LOGEA("Error! One of the YUV Pointer is NULL");
7698e88af31129b8cc09675279ca2eac88256d8526bAkwasi Boateng                goto exit;
7708e88af31129b8cc09675279ca2eac88256d8526bAkwasi Boateng              }
7718e88af31129b8cc09675279ca2eac88256d8526bAkwasi Boateng              else{
77226d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu                copy2Dto1D(dest,
7738e88af31129b8cc09675279ca2eac88256d8526bAkwasi Boateng                           frame->mYuv,
77426d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu                           frame->mWidth,
77526d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu                           frame->mHeight,
77626d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu                           frame->mAlignment,
77726d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu                           frame->mOffset,
77826d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu                           2,
77926d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu                           frame->mLength,
78026d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu                           mPreviewPixelFormat);
7818e88af31129b8cc09675279ca2eac88256d8526bAkwasi Boateng              }
78226d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu            }
78326d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu        }
78426d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu    }
78526d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu
78626d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu exit:
78726d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu    mFrameProvider->returnFrame(frame->mBuffer, (CameraFrame::FrameType) frame->mFrameType);
78826d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu
78926d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu    if((mNotifierState == AppCallbackNotifier::NOTIFIER_STARTED) &&
79026d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu       mCameraHal->msgTypeEnabled(msgType) &&
79126d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu       (dest != NULL)) {
79226d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu        mDataCb(msgType, mPreviewMemory, mPreviewBufCount, NULL, mCallbackCookie);
79326d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu    }
79426d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu
79526d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu    // increment for next buffer
79626d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu    mPreviewBufCount = (mPreviewBufCount + 1) % AppCallbackNotifier::MAX_BUFFERS;
79726d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu}
79826d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu
799e6cf8e95b3192621d3b992fbb09df8c58b1a1e5fSundar Ramanstatus_t AppCallbackNotifier::dummyRaw()
800e6cf8e95b3192621d3b992fbb09df8c58b1a1e5fSundar Raman{
801e6cf8e95b3192621d3b992fbb09df8c58b1a1e5fSundar Raman    LOG_FUNCTION_NAME;
802e6cf8e95b3192621d3b992fbb09df8c58b1a1e5fSundar Raman
803e6cf8e95b3192621d3b992fbb09df8c58b1a1e5fSundar Raman    if ( NULL == mRequestMemory ) {
804e6cf8e95b3192621d3b992fbb09df8c58b1a1e5fSundar Raman        CAMHAL_LOGEA("Can't allocate memory for dummy raw callback!");
805e6cf8e95b3192621d3b992fbb09df8c58b1a1e5fSundar Raman        return NO_INIT;
806e6cf8e95b3192621d3b992fbb09df8c58b1a1e5fSundar Raman    }
807e6cf8e95b3192621d3b992fbb09df8c58b1a1e5fSundar Raman
808e6cf8e95b3192621d3b992fbb09df8c58b1a1e5fSundar Raman    if ( ( NULL != mCameraHal ) &&
809e6cf8e95b3192621d3b992fbb09df8c58b1a1e5fSundar Raman         ( NULL != mDataCb) &&
810e6cf8e95b3192621d3b992fbb09df8c58b1a1e5fSundar Raman         ( NULL != mNotifyCb ) ){
811e6cf8e95b3192621d3b992fbb09df8c58b1a1e5fSundar Raman
812e6cf8e95b3192621d3b992fbb09df8c58b1a1e5fSundar Raman        if ( mCameraHal->msgTypeEnabled(CAMERA_MSG_RAW_IMAGE) ) {
813e6cf8e95b3192621d3b992fbb09df8c58b1a1e5fSundar Raman            camera_memory_t *dummyRaw = mRequestMemory(-1, 1, 1, NULL);
814e6cf8e95b3192621d3b992fbb09df8c58b1a1e5fSundar Raman
815e6cf8e95b3192621d3b992fbb09df8c58b1a1e5fSundar Raman            if ( NULL == dummyRaw ) {
816e6cf8e95b3192621d3b992fbb09df8c58b1a1e5fSundar Raman                CAMHAL_LOGEA("Dummy raw buffer allocation failed!");
817e6cf8e95b3192621d3b992fbb09df8c58b1a1e5fSundar Raman                return NO_MEMORY;
818e6cf8e95b3192621d3b992fbb09df8c58b1a1e5fSundar Raman            }
819e6cf8e95b3192621d3b992fbb09df8c58b1a1e5fSundar Raman
820e6cf8e95b3192621d3b992fbb09df8c58b1a1e5fSundar Raman            mDataCb(CAMERA_MSG_RAW_IMAGE, dummyRaw, 0, NULL, mCallbackCookie);
821e6cf8e95b3192621d3b992fbb09df8c58b1a1e5fSundar Raman
822e6cf8e95b3192621d3b992fbb09df8c58b1a1e5fSundar Raman            dummyRaw->release(dummyRaw);
823e6cf8e95b3192621d3b992fbb09df8c58b1a1e5fSundar Raman        } else if ( mCameraHal->msgTypeEnabled(CAMERA_MSG_RAW_IMAGE_NOTIFY) ) {
824e6cf8e95b3192621d3b992fbb09df8c58b1a1e5fSundar Raman            mNotifyCb(CAMERA_MSG_RAW_IMAGE_NOTIFY, 0, 0, mCallbackCookie);
825e6cf8e95b3192621d3b992fbb09df8c58b1a1e5fSundar Raman        }
826e6cf8e95b3192621d3b992fbb09df8c58b1a1e5fSundar Raman    }
827e6cf8e95b3192621d3b992fbb09df8c58b1a1e5fSundar Raman
828e6cf8e95b3192621d3b992fbb09df8c58b1a1e5fSundar Raman    LOG_FUNCTION_NAME_EXIT;
829e6cf8e95b3192621d3b992fbb09df8c58b1a1e5fSundar Raman
830e6cf8e95b3192621d3b992fbb09df8c58b1a1e5fSundar Raman    return NO_ERROR;
831e6cf8e95b3192621d3b992fbb09df8c58b1a1e5fSundar Raman}
832e6cf8e95b3192621d3b992fbb09df8c58b1a1e5fSundar Raman
833c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevvoid AppCallbackNotifier::notifyFrame()
834c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
835c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    ///Receive and send the frame notifications to app
836c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    TIUTILS::Message msg;
837c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    CameraFrame *frame;
838c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    MemoryHeapBase *heap;
839c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    MemoryBase *buffer = NULL;
840c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    sp<MemoryBase> memBase;
841c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    void *buf = NULL;
842c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
843c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
844c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
8457207ddb84b57c01ea50c5af85dc4a3984b364deaSundar Raman    {
84626d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu        Mutex::Autolock lock(mLock);
84726d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu        if(!mFrameQ.isEmpty()) {
84826d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu            mFrameQ.get(&msg);
84926d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu        } else {
85026d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu            return;
85126d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu        }
852c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
853c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
8547207ddb84b57c01ea50c5af85dc4a3984b364deaSundar Raman    bool ret = true;
8557207ddb84b57c01ea50c5af85dc4a3984b364deaSundar Raman
856c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    frame = NULL;
857c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    switch(msg.command)
858c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
859c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        case AppCallbackNotifier::NOTIFIER_CMD_PROCESS_FRAME:
860c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
861c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                frame = (CameraFrame *) msg.arg1;
862c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                if(!frame)
863c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    {
864c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    break;
865c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    }
866c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
867c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                if ( (CameraFrame::RAW_FRAME == frame->mFrameType )&&
868c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    ( NULL != mCameraHal ) &&
869c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    ( NULL != mDataCb) &&
870e6cf8e95b3192621d3b992fbb09df8c58b1a1e5fSundar Raman                    ( NULL != mNotifyCb ) )
871c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    {
872c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
873e6cf8e95b3192621d3b992fbb09df8c58b1a1e5fSundar Raman                    if ( mCameraHal->msgTypeEnabled(CAMERA_MSG_RAW_IMAGE) )
874e6cf8e95b3192621d3b992fbb09df8c58b1a1e5fSundar Raman                        {
875c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#ifdef COPY_IMAGE_BUFFER
87626d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu                        copyAndSendPictureFrame(frame, CAMERA_MSG_RAW_IMAGE);
877c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#else
878e6cf8e95b3192621d3b992fbb09df8c58b1a1e5fSundar Raman                        //TODO: Find a way to map a Tiler buffer to a MemoryHeapBase
879c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#endif
880e6cf8e95b3192621d3b992fbb09df8c58b1a1e5fSundar Raman                        }
88126d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu                    else {
88226d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu                        if ( mCameraHal->msgTypeEnabled(CAMERA_MSG_RAW_IMAGE_NOTIFY) ) {
88326d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu                            mNotifyCb(CAMERA_MSG_RAW_IMAGE_NOTIFY, 0, 0, mCallbackCookie);
884c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                        }
88526d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu                        mFrameProvider->returnFrame(frame->mBuffer,
88626d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu                                                    (CameraFrame::FrameType) frame->mFrameType);
88726d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu                    }
888c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
889e6cf8e95b3192621d3b992fbb09df8c58b1a1e5fSundar Raman                    mRawAvailable = true;
890e6cf8e95b3192621d3b992fbb09df8c58b1a1e5fSundar Raman
891c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    }
892ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu                else if ( (CameraFrame::IMAGE_FRAME == frame->mFrameType) &&
893ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu                          (NULL != mCameraHal) &&
894ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu                          (NULL != mDataCb) &&
895ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu                          (CameraFrame::ENCODE_RAW_YUV422I_TO_JPEG & frame->mQuirks) )
896ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu                    {
897ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu
898c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu                    int encode_quality = 100, tn_quality = 100;
899c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu                    int tn_width, tn_height;
900c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu                    unsigned int current_snapshot = 0;
901c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu                    Encoder_libjpeg::params *main_jpeg = NULL, *tn_jpeg = NULL;
90236e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu                    void* exif_data = NULL;
903ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu                    camera_memory_t* raw_picture = mRequestMemory(-1, frame->mLength, 1, NULL);
904ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu
905ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu                    if(raw_picture) {
906ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu                        buf = raw_picture->data;
907ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu                    }
908ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu
9093ec18006399d61e97382601d14aaa43ee339c8b6Sundar Raman                    CameraParameters parameters;
910cb1183d6c3c8894fa09ad3ff7952388f6e7bec94Akwasi Boateng                    char *params = mCameraHal->getParameters();
911cb1183d6c3c8894fa09ad3ff7952388f6e7bec94Akwasi Boateng                    const String8 strParams(params);
9123ec18006399d61e97382601d14aaa43ee339c8b6Sundar Raman                    parameters.unflatten(strParams);
9133ec18006399d61e97382601d14aaa43ee339c8b6Sundar Raman
9143ec18006399d61e97382601d14aaa43ee339c8b6Sundar Raman                    encode_quality = parameters.getInt(CameraParameters::KEY_JPEG_QUALITY);
915c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu                    if (encode_quality < 0 || encode_quality > 100) {
916c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu                        encode_quality = 100;
917c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu                    }
918c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu
9193ec18006399d61e97382601d14aaa43ee339c8b6Sundar Raman                    tn_quality = parameters.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY);
920c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu                    if (tn_quality < 0 || tn_quality > 100) {
921c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu                        tn_quality = 100;
922ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu                    }
923ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu
92436e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu                    if (CameraFrame::HAS_EXIF_DATA & frame->mQuirks) {
92536e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu                        exif_data = frame->mCookie2;
92636e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu                    }
92736e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu
928c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu                    main_jpeg = (Encoder_libjpeg::params*)
929c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu                                    malloc(sizeof(Encoder_libjpeg::params));
930d9520b9de06f01b9411307040cf245e6fc7fe361Milen Mitkov
931d9520b9de06f01b9411307040cf245e6fc7fe361Milen Mitkov                    // Video snapshot with LDCNSF on adds a few bytes start offset
932d9520b9de06f01b9411307040cf245e6fc7fe361Milen Mitkov                    // and a few bytes on every line. They must be skipped.
933d9520b9de06f01b9411307040cf245e6fc7fe361Milen Mitkov                    int rightCrop = frame->mAlignment/2 - frame->mWidth;
934d9520b9de06f01b9411307040cf245e6fc7fe361Milen Mitkov
935d9520b9de06f01b9411307040cf245e6fc7fe361Milen Mitkov                    CAMHAL_LOGDB("Video snapshot right crop = %d", rightCrop);
936d9520b9de06f01b9411307040cf245e6fc7fe361Milen Mitkov                    CAMHAL_LOGDB("Video snapshot offset = %d", frame->mOffset);
937d9520b9de06f01b9411307040cf245e6fc7fe361Milen Mitkov
938c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu                    if (main_jpeg) {
939c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu                        main_jpeg->src = (uint8_t*) frame->mBuffer;
940c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu                        main_jpeg->src_size = frame->mLength;
941c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu                        main_jpeg->dst = (uint8_t*) buf;
942c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu                        main_jpeg->dst_size = frame->mLength;
943c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu                        main_jpeg->quality = encode_quality;
944d9520b9de06f01b9411307040cf245e6fc7fe361Milen Mitkov                        main_jpeg->in_width = frame->mAlignment/2; // use stride here
945c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu                        main_jpeg->in_height = frame->mHeight;
946d9520b9de06f01b9411307040cf245e6fc7fe361Milen Mitkov                        main_jpeg->out_width = frame->mAlignment/2;
947c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu                        main_jpeg->out_height = frame->mHeight;
948d9520b9de06f01b9411307040cf245e6fc7fe361Milen Mitkov                        main_jpeg->right_crop = rightCrop;
949d9520b9de06f01b9411307040cf245e6fc7fe361Milen Mitkov                        main_jpeg->start_offset = frame->mOffset;
950c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu                        main_jpeg->format = CameraParameters::PIXEL_FORMAT_YUV422I;
951c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu                    }
952c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu
9533ec18006399d61e97382601d14aaa43ee339c8b6Sundar Raman                    tn_width = parameters.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH);
9543ec18006399d61e97382601d14aaa43ee339c8b6Sundar Raman                    tn_height = parameters.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT);
955c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu
956c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu                    if ((tn_width > 0) && (tn_height > 0)) {
957c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu                        tn_jpeg = (Encoder_libjpeg::params*)
958c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu                                      malloc(sizeof(Encoder_libjpeg::params));
959c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu                        // if malloc fails just keep going and encode main jpeg
960c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu                        if (!tn_jpeg) {
961c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu                            tn_jpeg = NULL;
962c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu                        }
963c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu                    }
964c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu
965c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu                    if (tn_jpeg) {
966c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu                        int width, height;
9673ec18006399d61e97382601d14aaa43ee339c8b6Sundar Raman                        parameters.getPreviewSize(&width,&height);
968c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu                        current_snapshot = (mPreviewBufCount + MAX_BUFFERS - 1) % MAX_BUFFERS;
969c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu                        tn_jpeg->src = (uint8_t*) mPreviewBufs[current_snapshot];
970c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu                        tn_jpeg->src_size = mPreviewMemory->size / MAX_BUFFERS;
971c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu                        tn_jpeg->dst = (uint8_t*) malloc(tn_jpeg->src_size);
972c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu                        tn_jpeg->dst_size = tn_jpeg->src_size;
973c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu                        tn_jpeg->quality = tn_quality;
974c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu                        tn_jpeg->in_width = width;
975c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu                        tn_jpeg->in_height = height;
976c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu                        tn_jpeg->out_width = tn_width;
977c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu                        tn_jpeg->out_height = tn_height;
978d9520b9de06f01b9411307040cf245e6fc7fe361Milen Mitkov                        tn_jpeg->right_crop = 0;
979d9520b9de06f01b9411307040cf245e6fc7fe361Milen Mitkov                        tn_jpeg->start_offset = 0;
980c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu                        tn_jpeg->format = CameraParameters::PIXEL_FORMAT_YUV420SP;;
981c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu                    }
982c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu
983c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu                    sp<Encoder_libjpeg> encoder = new Encoder_libjpeg(main_jpeg,
984c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu                                                      tn_jpeg,
985c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu                                                      AppCallbackNotifierEncoderCallback,
986c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu                                                      (CameraFrame::FrameType)frame->mFrameType,
987c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu                                                      this,
988c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu                                                      raw_picture,
989c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu                                                      exif_data);
990ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu                    encoder->run();
9918e52e3bcc31f65a699c25557cf3026d324e631b4Tyler Luu                    gEncoderQueue.add(frame->mBuffer, encoder);
992ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu                    encoder.clear();
993cb1183d6c3c8894fa09ad3ff7952388f6e7bec94Akwasi Boateng                    if (params != NULL)
994cb1183d6c3c8894fa09ad3ff7952388f6e7bec94Akwasi Boateng                      {
995cb1183d6c3c8894fa09ad3ff7952388f6e7bec94Akwasi Boateng                        mCameraHal->putParameters(params);
996cb1183d6c3c8894fa09ad3ff7952388f6e7bec94Akwasi Boateng                      }
997ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu                    }
998c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                else if ( ( CameraFrame::IMAGE_FRAME == frame->mFrameType ) &&
999c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                             ( NULL != mCameraHal ) &&
1000c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                             ( NULL != mDataCb) )
1001c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    {
10027207ddb84b57c01ea50c5af85dc4a3984b364deaSundar Raman
1003e6cf8e95b3192621d3b992fbb09df8c58b1a1e5fSundar Raman                    // CTS, MTS requirements: Every 'takePicture()' call
1004e6cf8e95b3192621d3b992fbb09df8c58b1a1e5fSundar Raman                    // who registers a raw callback should receive one
1005e6cf8e95b3192621d3b992fbb09df8c58b1a1e5fSundar Raman                    // as well. This is  not always the case with
1006e6cf8e95b3192621d3b992fbb09df8c58b1a1e5fSundar Raman                    // CameraAdapters though.
100726d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu                    if (!mRawAvailable) {
1008e6cf8e95b3192621d3b992fbb09df8c58b1a1e5fSundar Raman                        dummyRaw();
100926d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu                    } else {
1010e6cf8e95b3192621d3b992fbb09df8c58b1a1e5fSundar Raman                        mRawAvailable = false;
101126d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu                    }
1012e6cf8e95b3192621d3b992fbb09df8c58b1a1e5fSundar Raman
1013c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#ifdef COPY_IMAGE_BUFFER
101426d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu                    {
101526d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu                        Mutex::Autolock lock(mBurstLock);
1016c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#if 0 //TODO: enable burst mode later
101726d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu                        if ( mBurst )
101826d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu                        {
101926d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu                            `(CAMERA_MSG_BURST_IMAGE, JPEGPictureMemBase, mCallbackCookie);
102026d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu                        }
102126d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu                        else
1022c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#endif
102326d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu                        {
102426d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu                            copyAndSendPictureFrame(frame, CAMERA_MSG_COMPRESSED_IMAGE);
1025c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                        }
102626d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu                    }
1027c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#else
1028c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                     //TODO: Find a way to map a Tiler buffer to a MemoryHeapBase
1029c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#endif
1030c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    }
1031c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                else if ( ( CameraFrame::VIDEO_FRAME_SYNC == frame->mFrameType ) &&
1032c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                             ( NULL != mCameraHal ) &&
1033c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                             ( NULL != mDataCb) &&
1034c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                             ( mCameraHal->msgTypeEnabled(CAMERA_MSG_VIDEO_FRAME)  ) )
1035c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    {
1036c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    mRecordingLock.lock();
1037c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    if(mRecording)
1038c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                        {
1039c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                        if(mUseMetaDataBufferMode)
1040c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                            {
1041c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                            camera_memory_t *videoMedatadaBufferMemory =
1042c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                                             (camera_memory_t *) mVideoMetadataBufferMemoryMap.valueFor((uint32_t) frame->mBuffer);
1043c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                            video_metadata_t *videoMetadataBuffer = (video_metadata_t *) videoMedatadaBufferMemory->data;
1044c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1045c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                            if( (NULL == videoMedatadaBufferMemory) || (NULL == videoMetadataBuffer) || (NULL == frame->mBuffer) )
1046c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                                {
1047c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                                CAMHAL_LOGEA("Error! One of the video buffers is NULL");
1048c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                                break;
1049c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                                }
1050c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
105172b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng                            if ( mUseVideoBuffers )
105272b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng                              {
105372b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng                                int vBuf = mVideoMap.valueFor((uint32_t) frame->mBuffer);
105472b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng                                GraphicBufferMapper &mapper = GraphicBufferMapper::get();
105572b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng                                Rect bounds;
105672b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng                                bounds.left = 0;
105772b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng                                bounds.top = 0;
105872b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng                                bounds.right = mVideoWidth;
105972b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng                                bounds.bottom = mVideoHeight;
106072b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng
106172b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng                                void *y_uv[2];
106272b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng                                mapper.lock((buffer_handle_t)vBuf, CAMHAL_GRALLOC_USAGE, bounds, y_uv);
106372b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng
106472b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng                                structConvImage input =  {frame->mWidth,
106572b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng                                                          frame->mHeight,
1066c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu                                                          4096,
106772b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng                                                          IC_FORMAT_YCbCr420_lp,
106872b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng                                                          (mmByte *)frame->mYuv[0],
106972b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng                                                          (mmByte *)frame->mYuv[1],
107072b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng                                                          frame->mOffset};
107172b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng
107272b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng                                structConvImage output = {mVideoWidth,
107372b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng                                                          mVideoHeight,
1074c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu                                                          4096,
107572b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng                                                          IC_FORMAT_YCbCr420_lp,
107672b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng                                                          (mmByte *)y_uv[0],
107772b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng                                                          (mmByte *)y_uv[1],
107872b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng                                                          0};
107972b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng
108072b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng                                VT_resizeFrame_Video_opt2_lp(&input, &output, NULL, 0);
108172b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng                                mapper.unlock((buffer_handle_t)vBuf);
108272b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng                                videoMetadataBuffer->metadataBufferType = (int) kMetadataBufferTypeCameraSource;
108372b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng                                videoMetadataBuffer->handle = (void *)vBuf;
108472b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng                                videoMetadataBuffer->offset = 0;
108572b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng                              }
108672b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng                            else
108772b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng                              {
108872b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng                                videoMetadataBuffer->metadataBufferType = (int) kMetadataBufferTypeCameraSource;
108972b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng                                videoMetadataBuffer->handle = frame->mBuffer;
109072b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng                                videoMetadataBuffer->offset = frame->mOffset;
109172b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng                              }
1092c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1093c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                            CAMHAL_LOGVB("mDataCbTimestamp : frame->mBuffer=0x%x, videoMetadataBuffer=0x%x, videoMedatadaBufferMemory=0x%x",
1094c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                                            frame->mBuffer, videoMetadataBuffer, videoMedatadaBufferMemory);
1095c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1096c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                            mDataCbTimestamp(frame->mTimestamp, CAMERA_MSG_VIDEO_FRAME,
1097c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                                                videoMedatadaBufferMemory, 0, mCallbackCookie);
1098c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                            }
1099c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                        else
1100c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                            {
1101c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                            //TODO: Need to revisit this, should ideally be mapping the TILER buffer using mRequestMemory
1102c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                            camera_memory_t* fakebuf = mRequestMemory(-1, 4, 1, NULL);
1103c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                            if( (NULL == fakebuf) || ( NULL == fakebuf->data) || ( NULL == frame->mBuffer))
1104c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                                {
1105c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                                CAMHAL_LOGEA("Error! One of the video buffers is NULL");
1106c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                                break;
1107c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                                }
1108c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1109c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                            fakebuf->data = frame->mBuffer;
1110c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                            mDataCbTimestamp(frame->mTimestamp, CAMERA_MSG_VIDEO_FRAME, fakebuf, 0, mCallbackCookie);
1111c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                            fakebuf->release(fakebuf);
1112c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                            }
1113c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                        }
1114c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    mRecordingLock.unlock();
1115c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1116c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    }
1117c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                else if(( CameraFrame::SNAPSHOT_FRAME == frame->mFrameType ) &&
1118c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                             ( NULL != mCameraHal ) &&
1119c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                             ( NULL != mDataCb) &&
1120c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                             ( NULL != mNotifyCb)) {
1121c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    //When enabled, measurement data is sent instead of video data
1122c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    if ( !mMeasurementEnabled ) {
112326d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu                        copyAndSendPreviewFrame(frame, CAMERA_MSG_POSTVIEW_FRAME);
112426d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu                    } else {
112526d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu                        mFrameProvider->returnFrame(frame->mBuffer,
112626d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu                                                    (CameraFrame::FrameType) frame->mFrameType);
1127c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    }
11287207ddb84b57c01ea50c5af85dc4a3984b364deaSundar Raman                }
11297207ddb84b57c01ea50c5af85dc4a3984b364deaSundar Raman                else if ( ( CameraFrame::PREVIEW_FRAME_SYNC== frame->mFrameType ) &&
1130c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                            ( NULL != mCameraHal ) &&
1131c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                            ( NULL != mDataCb) &&
1132c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                            ( mCameraHal->msgTypeEnabled(CAMERA_MSG_PREVIEW_FRAME)) ) {
1133c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    //When enabled, measurement data is sent instead of video data
1134c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    if ( !mMeasurementEnabled ) {
113526d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu                        copyAndSendPreviewFrame(frame, CAMERA_MSG_PREVIEW_FRAME);
113626d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu                    } else {
113726d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu                         mFrameProvider->returnFrame(frame->mBuffer,
113826d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu                                                     (CameraFrame::FrameType) frame->mFrameType);
1139c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    }
11407207ddb84b57c01ea50c5af85dc4a3984b364deaSundar Raman                }
11417207ddb84b57c01ea50c5af85dc4a3984b364deaSundar Raman                else if ( ( CameraFrame::FRAME_DATA_SYNC == frame->mFrameType ) &&
1142c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                            ( NULL != mCameraHal ) &&
1143c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                            ( NULL != mDataCb) &&
1144c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                            ( mCameraHal->msgTypeEnabled(CAMERA_MSG_PREVIEW_FRAME)) ) {
114526d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu                    copyAndSendPreviewFrame(frame, CAMERA_MSG_PREVIEW_FRAME);
1146c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                } else {
1147c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    mFrameProvider->returnFrame(frame->mBuffer,
1148c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                                                ( CameraFrame::FrameType ) frame->mFrameType);
1149c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    CAMHAL_LOGDB("Frame type 0x%x is still unsupported!", frame->mFrameType);
1150c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                }
1151c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1152c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                break;
1153c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1154c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        default:
1155c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1156c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            break;
1157c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1158c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        };
1159c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1160c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevexit:
1161c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1162c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( NULL != frame )
1163c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
1164c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        delete frame;
1165c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
1166c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1167c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
1168c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
1169c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1170c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevvoid AppCallbackNotifier::frameCallbackRelay(CameraFrame* caFrame)
1171c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
1172c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
1173c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    AppCallbackNotifier *appcbn = (AppCallbackNotifier*) (caFrame->mCookie);
1174c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    appcbn->frameCallback(caFrame);
1175c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
1176c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
1177c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1178c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevvoid AppCallbackNotifier::frameCallback(CameraFrame* caFrame)
1179c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
1180c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    ///Post the event to the event queue of AppCallbackNotifier
1181c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    TIUTILS::Message msg;
1182c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    CameraFrame *frame;
1183c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1184c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
1185c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1186c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( NULL != caFrame )
1187c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
1188c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1189c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        frame = new CameraFrame(*caFrame);
1190c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        if ( NULL != frame )
1191c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            {
11928e88af31129b8cc09675279ca2eac88256d8526bAkwasi Boateng              msg.command = AppCallbackNotifier::NOTIFIER_CMD_PROCESS_FRAME;
11938e88af31129b8cc09675279ca2eac88256d8526bAkwasi Boateng              msg.arg1 = frame;
11948e88af31129b8cc09675279ca2eac88256d8526bAkwasi Boateng              mFrameQ.put(&msg);
1195c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            }
1196c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        else
1197c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            {
1198c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            CAMHAL_LOGEA("Not enough resources to allocate CameraFrame");
1199c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            }
1200c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1201c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
1202c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1203c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
1204c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
1205c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
120626d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luuvoid AppCallbackNotifier::flushAndReturnFrames()
120726d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu{
120826d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu    TIUTILS::Message msg;
120926d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu    CameraFrame *frame;
121026d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu
121126d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu    Mutex::Autolock lock(mLock);
121226d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu    while (!mFrameQ.isEmpty()) {
121326d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu        mFrameQ.get(&msg);
121426d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu        frame = (CameraFrame*) msg.arg1;
121526d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu        if (frame) {
121626d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu            mFrameProvider->returnFrame(frame->mBuffer,
121726d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu                                        (CameraFrame::FrameType) frame->mFrameType);
121826d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu        }
121926d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu    }
122026d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu
122126d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu    LOG_FUNCTION_NAME_EXIT;
122226d9a9166b81616d205eb9ebb49c18dac1f6c044Tyler Luu}
1223c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1224c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevvoid AppCallbackNotifier::eventCallbackRelay(CameraHalEvent* chEvt)
1225c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
1226c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
1227c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    AppCallbackNotifier *appcbn = (AppCallbackNotifier*) (chEvt->mCookie);
1228c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    appcbn->eventCallback(chEvt);
1229c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
1230c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
1231c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1232c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevvoid AppCallbackNotifier::eventCallback(CameraHalEvent* chEvt)
1233c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
1234c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1235c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    ///Post the event to the event queue of AppCallbackNotifier
1236c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    TIUTILS::Message msg;
1237c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    CameraHalEvent *event;
1238c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1239c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1240c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
1241c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1242c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( NULL != chEvt )
1243c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
1244c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1245c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        event = new CameraHalEvent(*chEvt);
1246c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        if ( NULL != event )
1247c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            {
1248c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            msg.command = AppCallbackNotifier::NOTIFIER_CMD_PROCESS_EVENT;
1249c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            msg.arg1 = event;
12503ec18006399d61e97382601d14aaa43ee339c8b6Sundar Raman            {
12513ec18006399d61e97382601d14aaa43ee339c8b6Sundar Raman            Mutex::Autolock lock(mLock);
1252c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            mEventQ.put(&msg);
1253c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            }
12543ec18006399d61e97382601d14aaa43ee339c8b6Sundar Raman            }
1255c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        else
1256c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            {
1257c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            CAMHAL_LOGEA("Not enough resources to allocate CameraHalEvent");
1258c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            }
1259c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1260c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
1261c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1262c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
1263c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
1264c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1265c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
12663ec18006399d61e97382601d14aaa43ee339c8b6Sundar Ramanvoid AppCallbackNotifier::flushEventQueue()
12673ec18006399d61e97382601d14aaa43ee339c8b6Sundar Raman{
12683ec18006399d61e97382601d14aaa43ee339c8b6Sundar Raman
12693ec18006399d61e97382601d14aaa43ee339c8b6Sundar Raman    {
12703ec18006399d61e97382601d14aaa43ee339c8b6Sundar Raman    Mutex::Autolock lock(mLock);
1271f9df3ee5cfb3c3177bcc630abf6d756e8a60254cSundar Raman    mEventQ.clear();
12723ec18006399d61e97382601d14aaa43ee339c8b6Sundar Raman    }
12733ec18006399d61e97382601d14aaa43ee339c8b6Sundar Raman}
12743ec18006399d61e97382601d14aaa43ee339c8b6Sundar Raman
12753ec18006399d61e97382601d14aaa43ee339c8b6Sundar Raman
1276c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevbool AppCallbackNotifier::processMessage()
1277c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
1278c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    ///Retrieve the command from the command queue and process it
1279c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    TIUTILS::Message msg;
1280c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1281c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
1282c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1283c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    CAMHAL_LOGDA("+Msg get...");
1284c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mNotificationThread->msgQ().get(&msg);
1285c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    CAMHAL_LOGDA("-Msg get...");
1286c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    bool ret = true;
1287c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1288c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    switch(msg.command)
1289c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev      {
1290c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        case NotificationThread::NOTIFIER_EXIT:
1291c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev          {
129241a31123a0fc59b8112460285d3f1ba73c5537c0Emilian Peev            CAMHAL_LOGDA("Received NOTIFIER_EXIT command from Camera HAL");
1293c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            mNotifierState = AppCallbackNotifier::NOTIFIER_EXITED;
1294c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            ret = false;
1295c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            break;
1296c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev          }
1297c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        default:
1298c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev          {
1299c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            CAMHAL_LOGEA("Error: ProcessMsg() command from Camera HAL");
1300c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            break;
1301c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev          }
1302c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev      }
1303c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1304c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
1305c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1306c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    return ret;
1307c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1308c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1309c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
1310c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1311c322989ae6ff6769490828de1b5eda12b749cce9Iliyan MalchevAppCallbackNotifier::~AppCallbackNotifier()
1312c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
1313c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
1314c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1315c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    ///Stop app callback notifier if not already stopped
1316c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    stop();
1317c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1318c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    ///Unregister with the frame provider
1319c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( NULL != mFrameProvider )
1320c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
1321c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mFrameProvider->disableFrameNotification(CameraFrame::ALL_FRAMES);
1322c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
1323c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1324c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    //unregister with the event provider
1325c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( NULL != mEventProvider )
1326c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
1327c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mEventProvider->disableEventNotification(CameraHalEvent::ALL_EVENTS);
1328c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
1329c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1330c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    TIUTILS::Message msg = {0,0,0,0,0,0};
1331c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    msg.command = NotificationThread::NOTIFIER_EXIT;
1332c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1333c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    ///Post the message to display thread
1334c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mNotificationThread->msgQ().put(&msg);
1335c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1336c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    //Exit and cleanup the thread
13373f75fa6e5edf504c155a357494ab77c59b6887b8Tyler Luu    mNotificationThread->requestExit();
13383f75fa6e5edf504c155a357494ab77c59b6887b8Tyler Luu    mNotificationThread->join();
1339c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1340c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    //Delete the display thread
1341c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mNotificationThread.clear();
1342c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1343c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1344c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    ///Free the event and frame providers
1345c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( NULL != mEventProvider )
1346c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
1347c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        ///Deleting the event provider
1348c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        CAMHAL_LOGDA("Stopping Event Provider");
1349c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        delete mEventProvider;
1350c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mEventProvider = NULL;
1351c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
1352c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1353c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( NULL != mFrameProvider )
1354c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
1355c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        ///Deleting the frame provider
1356c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        CAMHAL_LOGDA("Stopping Frame Provider");
1357c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        delete mFrameProvider;
1358c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mFrameProvider = NULL;
1359c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
1360c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1361c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    releaseSharedVideoBuffers();
1362c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1363c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
1364c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
1365c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1366c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev//Free all video heaps and buffers
1367c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevvoid AppCallbackNotifier::releaseSharedVideoBuffers()
1368c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
1369c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
1370c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1371c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if(mUseMetaDataBufferMode)
1372c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    {
1373c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        camera_memory_t* videoMedatadaBufferMemory;
1374c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        for (unsigned int i = 0; i < mVideoMetadataBufferMemoryMap.size();  i++)
1375c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            {
1376c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            videoMedatadaBufferMemory = (camera_memory_t*) mVideoMetadataBufferMemoryMap.valueAt(i);
1377c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            if(NULL != videoMedatadaBufferMemory)
1378c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                {
1379c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                videoMedatadaBufferMemory->release(videoMedatadaBufferMemory);
1380c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                CAMHAL_LOGDB("Released  videoMedatadaBufferMemory=0x%x", videoMedatadaBufferMemory);
1381c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                }
1382c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            }
1383c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1384c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mVideoMetadataBufferMemoryMap.clear();
1385c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mVideoMetadataBufferReverseMap.clear();
13863dcde7b7332edf04cd597b01d69950544dcd6589Akwasi Boateng        if (mUseVideoBuffers)
13873dcde7b7332edf04cd597b01d69950544dcd6589Akwasi Boateng            {
13883dcde7b7332edf04cd597b01d69950544dcd6589Akwasi Boateng            mVideoMap.clear();
13893dcde7b7332edf04cd597b01d69950544dcd6589Akwasi Boateng            }
1390c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
1391c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1392c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
1393c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
1394c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1395c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevvoid AppCallbackNotifier::setEventProvider(int32_t eventMask, MessageNotifier * eventNotifier)
1396c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
1397c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1398c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
1399c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    ///@remarks There is no NULL check here. We will check
1400c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    ///for NULL when we get start command from CameraHal
1401c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    ///@Remarks Currently only one event provider (CameraAdapter) is supported
1402c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    ///@todo Have an array of event providers for each event bitmask
1403c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mEventProvider = new EventProvider(eventNotifier, this, eventCallbackRelay);
1404c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( NULL == mEventProvider )
1405c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
1406c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        CAMHAL_LOGEA("Error in creating EventProvider");
1407c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
1408c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    else
1409c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
1410c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mEventProvider->enableEventNotification(eventMask);
1411c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
1412c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1413c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
1414c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
1415c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1416c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevvoid AppCallbackNotifier::setFrameProvider(FrameNotifier *frameNotifier)
1417c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
1418c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
1419c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    ///@remarks There is no NULL check here. We will check
1420c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    ///for NULL when we get the start command from CameraAdapter
1421c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mFrameProvider = new FrameProvider(frameNotifier, this, frameCallbackRelay);
1422c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( NULL == mFrameProvider )
1423c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
1424c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        CAMHAL_LOGEA("Error in creating FrameProvider");
1425c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
1426c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    else
1427c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
1428c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        //Register only for captured images and RAW for now
1429c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        //TODO: Register for and handle all types of frames
1430c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mFrameProvider->enableFrameNotification(CameraFrame::IMAGE_FRAME);
1431c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mFrameProvider->enableFrameNotification(CameraFrame::RAW_FRAME);
1432c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
1433c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1434c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
1435c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
1436c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1437c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevstatus_t AppCallbackNotifier::startPreviewCallbacks(CameraParameters &params, void *buffers, uint32_t *offsets, int fd, size_t length, size_t count)
1438c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
1439c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    sp<MemoryHeapBase> heap;
1440c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    sp<MemoryBase> buffer;
1441c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    unsigned int *bufArr;
1442d822531f1f2b4c0fea1cd971d28bd1e552ed67baEmilian Peev    int size = 0;
1443c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1444c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
1445c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1446c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    Mutex::Autolock lock(mLock);
1447c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1448c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( NULL == mFrameProvider )
1449c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
1450c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        CAMHAL_LOGEA("Trying to start video recording without FrameProvider");
1451c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        return -EINVAL;
1452c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
1453c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1454c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( mPreviewing )
1455c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
1456c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        CAMHAL_LOGDA("+Already previewing");
1457c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        return NO_INIT;
1458c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
1459c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1460c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    int w,h;
1461c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    ///Get preview size
1462c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    params.getPreviewSize(&w, &h);
1463c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1464c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    //Get the preview pixel format
1465c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mPreviewPixelFormat = params.getPreviewFormat();
1466c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1467c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev     if(strcmp(mPreviewPixelFormat, (const char *) CameraParameters::PIXEL_FORMAT_YUV422I) == 0)
1468c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
1469c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        size = w*h*2;
1470c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mPreviewPixelFormat = CameraParameters::PIXEL_FORMAT_YUV422I;
1471c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
14722dc9bc1f87be40c2e4903b97a3df353d0f7c6781Emilian Peev    else if(strcmp(mPreviewPixelFormat, (const char *) CameraParameters::PIXEL_FORMAT_YUV420SP) == 0 )
1473c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
1474c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        size = (w*h*3)/2;
1475c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mPreviewPixelFormat = CameraParameters::PIXEL_FORMAT_YUV420SP;
1476c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
1477c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    else if(strcmp(mPreviewPixelFormat, (const char *) CameraParameters::PIXEL_FORMAT_RGB565) == 0)
1478c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
1479c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        size = w*h*2;
1480c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mPreviewPixelFormat = CameraParameters::PIXEL_FORMAT_RGB565;
1481c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
14822dc9bc1f87be40c2e4903b97a3df353d0f7c6781Emilian Peev    else if(strcmp(mPreviewPixelFormat, (const char *) CameraParameters::PIXEL_FORMAT_YUV420P) == 0)
14832dc9bc1f87be40c2e4903b97a3df353d0f7c6781Emilian Peev        {
1484d822531f1f2b4c0fea1cd971d28bd1e552ed67baEmilian Peev        int yStride, uvStride, ySize, uvSize;
1485d822531f1f2b4c0fea1cd971d28bd1e552ed67baEmilian Peev        alignYV12(w, h, yStride, uvStride, ySize, uvSize, size);
14862dc9bc1f87be40c2e4903b97a3df353d0f7c6781Emilian Peev        mPreviewPixelFormat = CameraParameters::PIXEL_FORMAT_YUV420P;
14872dc9bc1f87be40c2e4903b97a3df353d0f7c6781Emilian Peev        }
1488c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1489c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mPreviewMemory = mRequestMemory(-1, size, AppCallbackNotifier::MAX_BUFFERS, NULL);
1490c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if (!mPreviewMemory) {
1491c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        return NO_MEMORY;
1492c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
1493c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1494c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    for (int i=0; i < AppCallbackNotifier::MAX_BUFFERS; i++) {
1495c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mPreviewBufs[i] = (unsigned char*) mPreviewMemory->data + (i*size);
1496c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
1497c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1498c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( mCameraHal->msgTypeEnabled(CAMERA_MSG_PREVIEW_FRAME ) ) {
1499c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev         mFrameProvider->enableFrameNotification(CameraFrame::PREVIEW_FRAME_SYNC);
1500c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
1501c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1502c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mPreviewBufCount = 0;
1503c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1504c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mPreviewing = true;
1505c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1506c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
1507c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1508c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    return NO_ERROR;
1509c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
1510c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1511c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevvoid AppCallbackNotifier::setBurst(bool burst)
1512c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
1513c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
1514c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1515c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    Mutex::Autolock lock(mBurstLock);
1516c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1517c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mBurst = burst;
1518c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1519c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
1520c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
1521c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
152272b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boatengvoid AppCallbackNotifier::useVideoBuffers(bool useVideoBuffers)
152372b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng{
152472b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng  LOG_FUNCTION_NAME;
152572b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng
152672b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng  mUseVideoBuffers = useVideoBuffers;
152772b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng
152872b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng  LOG_FUNCTION_NAME_EXIT;
152972b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng}
153072b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng
153172b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boatengbool AppCallbackNotifier::getUesVideoBuffers()
153272b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng{
153372b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng    return mUseVideoBuffers;
153472b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng}
153572b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng
153672b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boatengvoid AppCallbackNotifier::setVideoRes(int width, int height)
153772b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng{
153872b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng  LOG_FUNCTION_NAME;
153972b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng
154072b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng  mVideoWidth = width;
154172b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng  mVideoHeight = height;
154272b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng
154372b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng  LOG_FUNCTION_NAME_EXIT;
154472b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng}
154572b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng
1546c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevstatus_t AppCallbackNotifier::stopPreviewCallbacks()
1547c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
1548c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    sp<MemoryHeapBase> heap;
1549c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    sp<MemoryBase> buffer;
1550c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1551c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
1552c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1553c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( NULL == mFrameProvider )
1554c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
1555c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        CAMHAL_LOGEA("Trying to stop preview callbacks without FrameProvider");
1556c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        return -EINVAL;
1557c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
1558c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1559c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( !mPreviewing )
1560c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
1561c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        return NO_INIT;
1562c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
1563c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1564c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mFrameProvider->disableFrameNotification(CameraFrame::PREVIEW_FRAME_SYNC);
1565c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
15667207ddb84b57c01ea50c5af85dc4a3984b364deaSundar Raman    {
15677207ddb84b57c01ea50c5af85dc4a3984b364deaSundar Raman    Mutex::Autolock lock(mLock);
1568c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mPreviewMemory->release(mPreviewMemory);
15697207ddb84b57c01ea50c5af85dc4a3984b364deaSundar Raman    }
1570c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1571c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mPreviewing = false;
1572c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1573c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
1574c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1575c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    return NO_ERROR;
1576c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1577c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
1578c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1579c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevstatus_t AppCallbackNotifier::useMetaDataBufferMode(bool enable)
1580c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
1581c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mUseMetaDataBufferMode = enable;
1582c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1583c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    return NO_ERROR;
1584c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
1585c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1586c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1587c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevstatus_t AppCallbackNotifier::startRecording()
1588c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
1589c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    status_t ret = NO_ERROR;
1590c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1591c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
1592c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1593c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev   Mutex::Autolock lock(mRecordingLock);
1594c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1595c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( NULL == mFrameProvider )
1596c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
1597c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        CAMHAL_LOGEA("Trying to start video recording without FrameProvider");
1598c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        ret = -1;
1599c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
1600c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1601c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if(mRecording)
1602c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
1603c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        return NO_INIT;
1604c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
1605c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1606c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( NO_ERROR == ret )
1607c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
1608c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev         mFrameProvider->enableFrameNotification(CameraFrame::VIDEO_FRAME_SYNC);
1609c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
1610c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1611c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mRecording = true;
1612c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1613c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
1614c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1615c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    return ret;
1616c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
1617c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1618c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev//Allocate metadata buffers for video recording
161972b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boatengstatus_t AppCallbackNotifier::initSharedVideoBuffers(void *buffers, uint32_t *offsets, int fd, size_t length, size_t count, void *vidBufs)
1620c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
1621c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    status_t ret = NO_ERROR;
1622c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
1623c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1624c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if(mUseMetaDataBufferMode)
1625c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
1626c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        uint32_t *bufArr = NULL;
1627c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        camera_memory_t* videoMedatadaBufferMemory = NULL;
1628c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1629c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        if(NULL == buffers)
1630c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            {
1631c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            CAMHAL_LOGEA("Error! Video buffers are NULL");
1632c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            return BAD_VALUE;
1633c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            }
1634c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        bufArr = (uint32_t *) buffers;
1635c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1636c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        for (uint32_t i = 0; i < count; i++)
1637c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            {
1638c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            videoMedatadaBufferMemory = mRequestMemory(-1, sizeof(video_metadata_t), 1, NULL);
1639c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            if((NULL == videoMedatadaBufferMemory) || (NULL == videoMedatadaBufferMemory->data))
1640c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                {
1641c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                CAMHAL_LOGEA("Error! Could not allocate memory for Video Metadata Buffers");
1642c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                return NO_MEMORY;
1643c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                }
1644c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1645c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            mVideoMetadataBufferMemoryMap.add(bufArr[i], (uint32_t)(videoMedatadaBufferMemory));
1646c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            mVideoMetadataBufferReverseMap.add((uint32_t)(videoMedatadaBufferMemory->data), bufArr[i]);
1647c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            CAMHAL_LOGDB("bufArr[%d]=0x%x, videoMedatadaBufferMemory=0x%x, videoMedatadaBufferMemory->data=0x%x",
1648c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                    i, bufArr[i], videoMedatadaBufferMemory, videoMedatadaBufferMemory->data);
164972b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng
165072b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng            if (vidBufs != NULL)
165172b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng              {
165272b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng                uint32_t *vBufArr = (uint32_t *) vidBufs;
165372b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng                mVideoMap.add(bufArr[i], vBufArr[i]);
165472b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng                CAMHAL_LOGVB("bufArr[%d]=0x%x, vBuffArr[%d]=0x%x", i, bufArr[i], i, vBufArr[i]);
165572b0d2814165e633385bd87a838fc9c3a8250113Akwasi Boateng              }
1656c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            }
1657c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
1658c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1659c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevexit:
1660c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
1661c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1662c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    return ret;
1663c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
1664c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1665c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevstatus_t AppCallbackNotifier::stopRecording()
1666c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
1667c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    status_t ret = NO_ERROR;
1668c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1669c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
1670c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1671c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    Mutex::Autolock lock(mRecordingLock);
1672c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1673c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( NULL == mFrameProvider )
1674c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
1675c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        CAMHAL_LOGEA("Trying to stop video recording without FrameProvider");
1676c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        ret = -1;
1677c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
1678c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1679c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if(!mRecording)
1680c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
1681c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        return NO_INIT;
1682c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
1683c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1684c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( NO_ERROR == ret )
1685c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
1686c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev         mFrameProvider->disableFrameNotification(CameraFrame::VIDEO_FRAME_SYNC);
1687c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
1688c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1689c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    ///Release the shared video buffers
1690c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    releaseSharedVideoBuffers();
1691c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1692c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mRecording = false;
1693c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1694c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
1695c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1696c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    return ret;
1697c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
1698c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1699c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevstatus_t AppCallbackNotifier::releaseRecordingFrame(const void* mem)
1700c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
1701c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    status_t ret = NO_ERROR;
1702c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    void *frame = NULL;
1703c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1704c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
1705c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( NULL == mFrameProvider )
1706c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
1707c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        CAMHAL_LOGEA("Trying to stop video recording without FrameProvider");
1708c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        ret = -1;
1709c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
1710c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1711c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( NULL == mem )
1712c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
1713c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        CAMHAL_LOGEA("Video Frame released is invalid");
1714c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        ret = -1;
1715c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
1716c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1717c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if( NO_ERROR != ret )
1718c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
1719c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        return ret;
1720c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
1721c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1722c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if(mUseMetaDataBufferMode)
1723c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
1724c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        video_metadata_t *videoMetadataBuffer = (video_metadata_t *) mem ;
1725c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        frame = (void*) mVideoMetadataBufferReverseMap.valueFor((uint32_t) videoMetadataBuffer);
1726c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        CAMHAL_LOGVB("Releasing frame with videoMetadataBuffer=0x%x, videoMetadataBuffer->handle=0x%x & frame handle=0x%x\n",
1727c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev                       videoMetadataBuffer, videoMetadataBuffer->handle, frame);
1728c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
1729c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    else
1730c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
1731c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        frame = (void*)(*((uint32_t *)mem));
1732c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
1733c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1734c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( NO_ERROR == ret )
1735c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
1736c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev         ret = mFrameProvider->returnFrame(frame, CameraFrame::VIDEO_FRAME_SYNC);
1737c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
1738c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1739c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
1740c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1741c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    return ret;
1742c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
1743c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1744c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevstatus_t AppCallbackNotifier::enableMsgType(int32_t msgType)
1745c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
17468a01f97380aad5b6a30a2d248aa07af4d92373d0Tyler Luu    if( msgType & (CAMERA_MSG_POSTVIEW_FRAME | CAMERA_MSG_PREVIEW_FRAME) ) {
17478a01f97380aad5b6a30a2d248aa07af4d92373d0Tyler Luu        mFrameProvider->enableFrameNotification(CameraFrame::PREVIEW_FRAME_SYNC);
17488a01f97380aad5b6a30a2d248aa07af4d92373d0Tyler Luu    }
1749c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1750c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    return NO_ERROR;
1751c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
1752c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1753c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevstatus_t AppCallbackNotifier::disableMsgType(int32_t msgType)
1754c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
175580a2eeb9c95c24e0dd69e61c3f58e6da36cf703dAkwasi Boateng    if( msgType & (CAMERA_MSG_PREVIEW_FRAME | CAMERA_MSG_POSTVIEW_FRAME) ) {
1756c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mFrameProvider->disableFrameNotification(CameraFrame::PREVIEW_FRAME_SYNC);
17578a01f97380aad5b6a30a2d248aa07af4d92373d0Tyler Luu    }
1758c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1759c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    return NO_ERROR;
1760c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1761c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
1762c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1763c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevstatus_t AppCallbackNotifier::start()
1764c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
1765c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
1766c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if(mNotifierState==AppCallbackNotifier::NOTIFIER_STARTED)
1767c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
1768c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        CAMHAL_LOGDA("AppCallbackNotifier already running");
1769c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        LOG_FUNCTION_NAME_EXIT;
1770c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        return ALREADY_EXISTS;
1771c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
1772c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1773c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    ///Check whether initial conditions are met for us to start
1774c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    ///A frame provider should be available, if not return error
1775c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if(!mFrameProvider)
1776c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
1777c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        ///AppCallbackNotifier not properly initialized
1778c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        CAMHAL_LOGEA("AppCallbackNotifier not properly initialized - Frame provider is NULL");
1779c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        LOG_FUNCTION_NAME_EXIT;
1780c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        return NO_INIT;
1781c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
1782c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1783c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    ///At least one event notifier should be available, if not return error
1784c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    ///@todo Modify here when there is an array of event providers
1785c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if(!mEventProvider)
1786c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
1787c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        CAMHAL_LOGEA("AppCallbackNotifier not properly initialized - Event provider is NULL");
1788c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        LOG_FUNCTION_NAME_EXIT;
1789c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        ///AppCallbackNotifier not properly initialized
1790c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        return NO_INIT;
1791c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
1792c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1793c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mNotifierState = AppCallbackNotifier::NOTIFIER_STARTED;
1794c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    CAMHAL_LOGDA(" --> AppCallbackNotifier NOTIFIER_STARTED \n");
1795c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
17968e52e3bcc31f65a699c25557cf3026d324e631b4Tyler Luu    gEncoderQueue.clear();
17978e52e3bcc31f65a699c25557cf3026d324e631b4Tyler Luu
1798c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
1799c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1800c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    return NO_ERROR;
1801c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1802c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
1803c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1804c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevstatus_t AppCallbackNotifier::stop()
1805c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
1806c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
1807c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1808c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if(mNotifierState!=AppCallbackNotifier::NOTIFIER_STARTED)
1809c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
1810c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        CAMHAL_LOGDA("AppCallbackNotifier already in stopped state");
1811c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        LOG_FUNCTION_NAME_EXIT;
1812c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        return ALREADY_EXISTS;
1813c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
18147207ddb84b57c01ea50c5af85dc4a3984b364deaSundar Raman    {
18157207ddb84b57c01ea50c5af85dc4a3984b364deaSundar Raman    Mutex::Autolock lock(mLock);
1816c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1817c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mNotifierState = AppCallbackNotifier::NOTIFIER_STOPPED;
1818c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    CAMHAL_LOGDA(" --> AppCallbackNotifier NOTIFIER_STOPPED \n");
18197207ddb84b57c01ea50c5af85dc4a3984b364deaSundar Raman    }
1820c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
18218e52e3bcc31f65a699c25557cf3026d324e631b4Tyler Luu    while(!gEncoderQueue.isEmpty()) {
18228e52e3bcc31f65a699c25557cf3026d324e631b4Tyler Luu        sp<Encoder_libjpeg> encoder = gEncoderQueue.valueAt(0);
18230c7ae887ee41852f275887fd543fae810668e2d1Tyler Luu        camera_memory_t* encoded_mem = NULL;
18240c7ae887ee41852f275887fd543fae810668e2d1Tyler Luu        ExifElementsTable* exif = NULL;
18250c7ae887ee41852f275887fd543fae810668e2d1Tyler Luu
18268e52e3bcc31f65a699c25557cf3026d324e631b4Tyler Luu        if(encoder.get()) {
18278e52e3bcc31f65a699c25557cf3026d324e631b4Tyler Luu            encoder->cancel();
18280c7ae887ee41852f275887fd543fae810668e2d1Tyler Luu
18290c7ae887ee41852f275887fd543fae810668e2d1Tyler Luu            encoder->getCookies(NULL, (void**) &encoded_mem, (void**) &exif);
18300c7ae887ee41852f275887fd543fae810668e2d1Tyler Luu            if (encoded_mem) {
18310c7ae887ee41852f275887fd543fae810668e2d1Tyler Luu                encoded_mem->release(encoded_mem);
18320c7ae887ee41852f275887fd543fae810668e2d1Tyler Luu            }
18330c7ae887ee41852f275887fd543fae810668e2d1Tyler Luu            if (exif) {
18340c7ae887ee41852f275887fd543fae810668e2d1Tyler Luu                delete exif;
18350c7ae887ee41852f275887fd543fae810668e2d1Tyler Luu            }
18360c7ae887ee41852f275887fd543fae810668e2d1Tyler Luu
18378e52e3bcc31f65a699c25557cf3026d324e631b4Tyler Luu            encoder.clear();
18388e52e3bcc31f65a699c25557cf3026d324e631b4Tyler Luu        }
18398e52e3bcc31f65a699c25557cf3026d324e631b4Tyler Luu        gEncoderQueue.removeItemsAt(0);
18408e52e3bcc31f65a699c25557cf3026d324e631b4Tyler Luu    }
18418e52e3bcc31f65a699c25557cf3026d324e631b4Tyler Luu
1842c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
1843c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    return NO_ERROR;
1844c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
1845c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1846c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1847c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev/*--------------------NotificationHandler Class ENDS here-----------------------------*/
1848c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1849c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1850c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
1851c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev};
1852