133bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine/*
233bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine * Copyright (C) 2011 The Android Open Source Project
333bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine *
433bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine * Licensed under the Apache License, Version 2.0 (the "License");
533bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine * you may not use this file except in compliance with the License.
633bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine * You may obtain a copy of the License at
733bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine *
833bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine *      http://www.apache.org/licenses/LICENSE-2.0
933bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine *
1033bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine * Unless required by applicable law or agreed to in writing, software
1133bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine * distributed under the License is distributed on an "AS IS" BASIS,
1233bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1333bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine * See the License for the specific language governing permissions and
1433bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine * limitations under the License.
1533bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine */
1633bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine
1733bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine/*
1833bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine * Contains implementation of a class EmulatedQemuCameraDevice that encapsulates
1933bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine * an emulated camera device connected to the host.
2033bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine */
2133bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine
2233bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine#define LOG_NDEBUG 0
2333bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine#define LOG_TAG "EmulatedCamera_QemuDevice"
2433bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine#include <cutils/log.h>
255467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine#include "EmulatedQemuCamera.h"
265467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine#include "EmulatedQemuCameraDevice.h"
2733bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine
2833bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkinenamespace android {
2933bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine
3033bda475286a625337ed184e7053fc29e403d57bVladimir ChtchetkineEmulatedQemuCameraDevice::EmulatedQemuCameraDevice(EmulatedQemuCamera* camera_hal)
3133bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine    : EmulatedCameraDevice(camera_hal),
325467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine      mQemuClient(),
335467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine      mPreviewFrame(NULL)
3433bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine{
3533bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine}
3633bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine
3733bda475286a625337ed184e7053fc29e403d57bVladimir ChtchetkineEmulatedQemuCameraDevice::~EmulatedQemuCameraDevice()
3833bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine{
395467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine    if (mPreviewFrame != NULL) {
405467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine        delete[] mPreviewFrame;
4133bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine    }
4233bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine}
4333bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine
4433bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine/****************************************************************************
4533bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine * Public API
4633bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine ***************************************************************************/
4733bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine
4833bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkinestatus_t EmulatedQemuCameraDevice::Initialize(const char* device_name)
4933bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine{
5033bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine    /* Connect to the service. */
5133bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine    char connect_str[256];
5233bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine    snprintf(connect_str, sizeof(connect_str), "name=%s", device_name);
535467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine    status_t res = mQemuClient.connectClient(connect_str);
5433bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine    if (res != NO_ERROR) {
5533bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine        return res;
5633bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine    }
5733bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine
5833bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine    /* Initialize base class. */
5933bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine    res = EmulatedCameraDevice::Initialize();
6033bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine    if (res == NO_ERROR) {
61629719e390ce66be822c3563bbd248ce15eaae7bSteve Block        ALOGV("%s: Connected to the emulated camera service '%s'",
6233bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine             __FUNCTION__, device_name);
635467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine        mDeviceName = device_name;
6433bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine    } else {
6516232484c709c565adfbf557025c52f61295c058Vladimir Chtchetkine        mQemuClient.queryDisconnect();
6633bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine    }
6733bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine
6833bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine    return res;
6933bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine}
7033bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine
7133bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine/****************************************************************************
7233bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine * Emulated camera device abstract interface implementation.
7333bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine ***************************************************************************/
7433bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine
755467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkinestatus_t EmulatedQemuCameraDevice::connectDevice()
7633bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine{
77629719e390ce66be822c3563bbd248ce15eaae7bSteve Block    ALOGV("%s", __FUNCTION__);
7833bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine
795467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine    Mutex::Autolock locker(&mObjectLock);
805467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine    if (!isInitialized()) {
815a622cba8c5287d5e6577f940a22343a7cae977fSteve Block        ALOGE("%s: Qemu camera device is not initialized.", __FUNCTION__);
8233bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine        return EINVAL;
8333bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine    }
845467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine    if (isConnected()) {
856aff44c27ee487bd65d5a1c74faf4b7165530bd4Steve Block        ALOGW("%s: Qemu camera device '%s' is already connected.",
8649842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine             __FUNCTION__, (const char*)mDeviceName);
8733bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine        return NO_ERROR;
8833bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine    }
8933bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine
9049842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine    /* Connect to the camera device via emulator. */
915467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine    const status_t res = mQemuClient.queryConnect();
9233bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine    if (res == NO_ERROR) {
93629719e390ce66be822c3563bbd248ce15eaae7bSteve Block        ALOGV("%s: Connected to device '%s'",
9449842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine             __FUNCTION__, (const char*)mDeviceName);
955467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine        mState = ECDS_CONNECTED;
9633bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine    } else {
975a622cba8c5287d5e6577f940a22343a7cae977fSteve Block        ALOGE("%s: Connection to device '%s' failed",
9849842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine             __FUNCTION__, (const char*)mDeviceName);
9933bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine    }
10033bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine
10133bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine    return res;
10233bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine}
10333bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine
1045467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkinestatus_t EmulatedQemuCameraDevice::disconnectDevice()
10533bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine{
106629719e390ce66be822c3563bbd248ce15eaae7bSteve Block    ALOGV("%s", __FUNCTION__);
10733bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine
1085467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine    Mutex::Autolock locker(&mObjectLock);
1095467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine    if (!isConnected()) {
1106aff44c27ee487bd65d5a1c74faf4b7165530bd4Steve Block        ALOGW("%s: Qemu camera device '%s' is already disconnected.",
11149842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine             __FUNCTION__, (const char*)mDeviceName);
11233bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine        return NO_ERROR;
11333bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine    }
11449842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine    if (isStarted()) {
1155a622cba8c5287d5e6577f940a22343a7cae977fSteve Block        ALOGE("%s: Cannot disconnect from the started device '%s.",
11649842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine             __FUNCTION__, (const char*)mDeviceName);
11733bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine        return EINVAL;
11833bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine    }
11933bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine
12049842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine    /* Disconnect from the camera device via emulator. */
1215467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine    const status_t res = mQemuClient.queryDisconnect();
12233bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine    if (res == NO_ERROR) {
123629719e390ce66be822c3563bbd248ce15eaae7bSteve Block        ALOGV("%s: Disonnected from device '%s'",
12449842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine             __FUNCTION__, (const char*)mDeviceName);
1255467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine        mState = ECDS_INITIALIZED;
12633bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine    } else {
1275a622cba8c5287d5e6577f940a22343a7cae977fSteve Block        ALOGE("%s: Disconnection from device '%s' failed",
12849842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine             __FUNCTION__, (const char*)mDeviceName);
12933bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine    }
13033bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine
13133bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine    return res;
13233bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine}
13333bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine
13449842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkinestatus_t EmulatedQemuCameraDevice::startDevice(int width,
13549842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine                                               int height,
13649842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine                                               uint32_t pix_fmt)
13733bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine{
138629719e390ce66be822c3563bbd248ce15eaae7bSteve Block    ALOGV("%s", __FUNCTION__);
13933bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine
14049842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine    Mutex::Autolock locker(&mObjectLock);
1415467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine    if (!isConnected()) {
1425a622cba8c5287d5e6577f940a22343a7cae977fSteve Block        ALOGE("%s: Qemu camera device '%s' is not connected.",
14349842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine             __FUNCTION__, (const char*)mDeviceName);
14433bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine        return EINVAL;
14533bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine    }
14649842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine    if (isStarted()) {
1476aff44c27ee487bd65d5a1c74faf4b7165530bd4Steve Block        ALOGW("%s: Qemu camera device '%s' is already started.",
14849842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine             __FUNCTION__, (const char*)mDeviceName);
14933bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine        return NO_ERROR;
15033bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine    }
15133bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine
15249842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine    status_t res = EmulatedCameraDevice::commonStartDevice(width, height, pix_fmt);
15349842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine    if (res != NO_ERROR) {
1545a622cba8c5287d5e6577f940a22343a7cae977fSteve Block        ALOGE("%s: commonStartDevice failed", __FUNCTION__);
15549842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine        return res;
15649842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine    }
15749842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine
15833bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine    /* Allocate preview frame buffer. */
15933bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine    /* TODO: Watch out for preview format changes! At this point we implement
16033bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine     * RGB32 only.*/
16149842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine    mPreviewFrame = new uint32_t[mTotalPixels];
1625467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine    if (mPreviewFrame == NULL) {
1635a622cba8c5287d5e6577f940a22343a7cae977fSteve Block        ALOGE("%s: Unable to allocate %d bytes for preview frame",
16449842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine             __FUNCTION__, mTotalPixels);
16533bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine        return ENOMEM;
16633bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine    }
16733bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine
16833bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine    /* Start the actual camera device. */
16949842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine    res = mQemuClient.queryStart(mPixelFormat, mFrameWidth, mFrameHeight);
17033bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine    if (res == NO_ERROR) {
171629719e390ce66be822c3563bbd248ce15eaae7bSteve Block        ALOGV("%s: Qemu camera device '%s' is started for %.4s[%dx%d] frames",
17249842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine             __FUNCTION__, (const char*)mDeviceName,
17349842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine             reinterpret_cast<const char*>(&mPixelFormat),
17449842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine             mFrameWidth, mFrameHeight);
17549842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine        mState = ECDS_STARTED;
17633bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine    } else {
1775a622cba8c5287d5e6577f940a22343a7cae977fSteve Block        ALOGE("%s: Unable to start device '%s' for %.4s[%dx%d] frames",
17849842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine             __FUNCTION__, (const char*)mDeviceName,
17949842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine             reinterpret_cast<const char*>(&pix_fmt), width, height);
18033bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine    }
18133bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine
18233bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine    return res;
18333bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine}
18433bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine
1855467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkinestatus_t EmulatedQemuCameraDevice::stopDevice()
18633bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine{
187629719e390ce66be822c3563bbd248ce15eaae7bSteve Block    ALOGV("%s", __FUNCTION__);
18833bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine
18949842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine    Mutex::Autolock locker(&mObjectLock);
19049842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine    if (!isStarted()) {
1916aff44c27ee487bd65d5a1c74faf4b7165530bd4Steve Block        ALOGW("%s: Qemu camera device '%s' is not started.",
19249842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine             __FUNCTION__, (const char*)mDeviceName);
19333bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine        return NO_ERROR;
19433bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine    }
19533bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine
19649842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine    /* Stop the actual camera device. */
19749842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine    status_t res = mQemuClient.queryStop();
19833bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine    if (res == NO_ERROR) {
19949842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine        if (mPreviewFrame == NULL) {
20049842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine            delete[] mPreviewFrame;
20149842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine            mPreviewFrame = NULL;
20233bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine        }
20349842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine        EmulatedCameraDevice::commonStopDevice();
20449842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine        mState = ECDS_CONNECTED;
205629719e390ce66be822c3563bbd248ce15eaae7bSteve Block        ALOGV("%s: Qemu camera device '%s' is stopped",
20649842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine             __FUNCTION__, (const char*)mDeviceName);
20733bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine    } else {
2085a622cba8c5287d5e6577f940a22343a7cae977fSteve Block        ALOGE("%s: Unable to stop device '%s'",
20949842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine             __FUNCTION__, (const char*)mDeviceName);
21033bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine    }
21133bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine
21233bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine    return res;
21333bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine}
21433bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine
21533bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine/****************************************************************************
21633bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine * EmulatedCameraDevice virtual overrides
21733bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine ***************************************************************************/
21833bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine
2195467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkinestatus_t EmulatedQemuCameraDevice::getCurrentPreviewFrame(void* buffer)
22033bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine{
2216aff44c27ee487bd65d5a1c74faf4b7165530bd4Steve Block    ALOGW_IF(mPreviewFrame == NULL, "%s: No preview frame", __FUNCTION__);
2225467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine    if (mPreviewFrame != NULL) {
2235467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine        memcpy(buffer, mPreviewFrame, mTotalPixels * 4);
22433bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine        return 0;
22533bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine    } else {
2265467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine        return EmulatedCameraDevice::getCurrentPreviewFrame(buffer);
22733bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine    }
22833bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine}
22933bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine
23033bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine/****************************************************************************
23133bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine * Worker thread management overrides.
23233bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine ***************************************************************************/
23333bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine
2345467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkinebool EmulatedQemuCameraDevice::inWorkerThread()
23533bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine{
23633bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine    /* Wait till FPS timeout expires, or thread exit message is received. */
23733bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine    WorkerThread::SelectRes res =
2385467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine        getWorkerThread()->Select(-1, 1000000 / mEmulatedFPS);
23933bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine    if (res == WorkerThread::EXIT_THREAD) {
240629719e390ce66be822c3563bbd248ce15eaae7bSteve Block        ALOGV("%s: Worker thread has been terminated.", __FUNCTION__);
24133bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine        return false;
24233bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine    }
24333bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine
24433bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine    /* Query frames from the service. */
2455467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine    status_t query_res = mQemuClient.queryFrame(mCurrentFrame, mPreviewFrame,
2465467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine                                                 mFrameBufferSize,
247031b92f4c7edf17aa6e75e6c4ec3582e0413b744Vladimir Chtchetkine                                                 mTotalPixels * 4,
248031b92f4c7edf17aa6e75e6c4ec3582e0413b744Vladimir Chtchetkine                                                 mWhiteBalanceScale[0],
249031b92f4c7edf17aa6e75e6c4ec3582e0413b744Vladimir Chtchetkine                                                 mWhiteBalanceScale[1],
250031b92f4c7edf17aa6e75e6c4ec3582e0413b744Vladimir Chtchetkine                                                 mWhiteBalanceScale[2],
251031b92f4c7edf17aa6e75e6c4ec3582e0413b744Vladimir Chtchetkine                                                 mExposureCompensation);
25233bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine    if (query_res == NO_ERROR) {
25333bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine        /* Timestamp the current frame, and notify the camera HAL. */
2545467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine        mCurFrameTimestamp = systemTime(SYSTEM_TIME_MONOTONIC);
2555467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine        mCameraHAL->onNextFrameAvailable(mCurrentFrame, mCurFrameTimestamp, this);
256b3ea1716552f4bd4145db53be67c26242a5db50aVladimir Chtchetkine        return true;
25733bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine    } else {
2585a622cba8c5287d5e6577f940a22343a7cae977fSteve Block        ALOGE("%s: Unable to get current video frame: %s",
25933bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine             __FUNCTION__, strerror(query_res));
260b3ea1716552f4bd4145db53be67c26242a5db50aVladimir Chtchetkine        mCameraHAL->onCameraDeviceError(CAMERA_ERROR_SERVER_DIED);
261b3ea1716552f4bd4145db53be67c26242a5db50aVladimir Chtchetkine        return false;
26233bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine    }
26333bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine}
26433bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine
26533bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine}; /* namespace android */
266