<commit_before>#define USE_RECORDING_INSTEAD_PREVIEW 0

#if !defined(ANDROID_r2_2_2) && !defined(ANDROID_r2_3_3) && !defined(ANDROID_r3_0_1)
#error unsupported version of Android
#endif

#include <camera/CameraHardwareInterface.h>
#include "camera_wrapper.h"
#include "../include/camera_properties.h"
#include <string>

using namespace android;

void debugShowFPS()
{
    static int mFrameCount = 0;
    static int mLastFrameCount = 0;
    static nsecs_t mLastFpsTime = systemTime();;
    static float mFps = 0;

    mFrameCount++;

    if ( ( mFrameCount % 30 ) == 0 ) {
        nsecs_t now = systemTime();
        nsecs_t diff = now - mLastFpsTime;
        if (diff==0)
            return;

        mFps =  ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff;
        mLastFpsTime = now;
        mLastFrameCount = mFrameCount;
        LOGI("####### [%d] Frames, %f FPS", mFrameCount, mFps);
    }
}

class CameraHandler: public CameraListener
{
protected:
    sp<Camera> camera;
    CameraCallback cameraCallback;
    CameraParameters params;
    void* userData;
    int cameraId;

    bool isEmptyCameraCallbackReported;
    virtual void doCall(void* buffer, size_t bufferSize)
    {
        if (cameraCallback == 0)
        {
            if (!isEmptyCameraCallbackReported)
                LOGE("Camera callback is empty!");

            isEmptyCameraCallbackReported = true;
            return;
        }

        bool res = (*cameraCallback)(buffer, bufferSize, userData);

        if(!res) closeCameraConnect();
    }

    virtual void doCall(const sp<IMemory>& dataPtr)
    {
        LOGI("doCall started");

        if (dataPtr == NULL)
        {
            LOGE("CameraBuffer: dataPtr==NULL");
            return;
        }

        size_t size = dataPtr->size();
        if (size <= 0)
        {
            LOGE("CameraBuffer: IMemory object is of zero size");
            return;
        }

        unsigned char* buffer = (unsigned char *)dataPtr->pointer();
        if (!buffer)
        {
            LOGE("CameraBuffer: Buffer pointer is invalid");
            return;
        }

        doCall(buffer, size);
    }

public:
    CameraHandler(CameraCallback callback = 0, void* _userData = 0):cameraCallback(callback), userData(_userData), cameraId(0),  isEmptyCameraCallbackReported(false) {}
    virtual ~CameraHandler()
    {
	    LOGW("CameraHandler destructor is called!");
    }

    virtual void notify(int32_t msgType, int32_t ext1, int32_t ext2)
    {
        LOGE("Notify cb: %d %d %d\n", msgType, ext1, ext2);
#if 0
        if ( msgType & CAMERA_MSG_FOCUS )
            LOGE("AutoFocus %s in %llu us\n", (ext1) ? "OK" : "FAIL", timevalDelay(&autofocus_start));

        if ( msgType & CAMERA_MSG_SHUTTER )
            LOGE("Shutter done in %llu us\n", timeval_delay(&picture_start));
#endif
    }

    virtual void postData(int32_t msgType, const sp<IMemory>& dataPtr)
    {
        debugShowFPS();

        if ( msgType & CAMERA_MSG_PREVIEW_FRAME )
        {
            doCall(dataPtr);
            return;
        }

        if (msgType != CAMERA_MSG_PREVIEW_FRAME)
            LOGE("Recieved not CAMERA_MSG_PREVIEW_FRAME message %d", (int) msgType);

        if ( msgType & CAMERA_MSG_RAW_IMAGE )
            LOGE("Unexpected data format: RAW\n");

        if (msgType & CAMERA_MSG_POSTVIEW_FRAME)
            LOGE("Unexpected data format: Postview frame\n");

        if (msgType & CAMERA_MSG_COMPRESSED_IMAGE )
            LOGE("Unexpected data format: JPEG");
    }

    virtual void postDataTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr)
    {
        static uint32_t count = 0;
        count++;

        LOGE("Recording cb: %d %lld %%p Offset:%%d Stride:%%d\n", msgType, timestamp);

        if (dataPtr == NULL)
        {
            LOGE("postDataTimestamp: dataPtr IS ZERO -- returning");
            camera->releaseRecordingFrame(dataPtr);
            LOGE("postDataTimestamp:  camera->releaseRecordingFrame(dataPtr) is done");
            return;
        }

        uint8_t *ptr = (uint8_t*) dataPtr->pointer();
        if (ptr)
            LOGE("VID_CB: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x", ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6], ptr[7], ptr[8], ptr[9]);
        else
            LOGE("postDataTimestamp: Ptr is zero");

        camera->releaseRecordingFrame(dataPtr);
    }

    static CameraHandler* initCameraConnect(const CameraCallback& callback, int cameraId, void* userData, CameraParameters* prevCameraParameters);
    void closeCameraConnect();
    double getProperty(int propIdx);
    void setProperty(int propIdx, double value);
    static void applyProperties(CameraHandler** ppcameraHandler);

    std::string cameraPropertySupportedPreviewSizesString;
};

CameraHandler* CameraHandler::initCameraConnect(const CameraCallback& callback, int cameraId, void* userData, CameraParameters* prevCameraParameters)
{
//    if (camera != NULL)
//    {
//        LOGE("initCameraConnect: camera have been connected already");
//        return false;
//    }

    sp<Camera> camera = 0;

#ifdef ANDROID_r2_2_2
    camera = Camera::connect();
#endif
#ifdef ANDROID_r2_3_3
    camera = Camera::connect(cameraId);
#endif

    if ( NULL == camera.get() )
    {
        LOGE("initCameraConnect: Unable to connect to CameraService\n");
        return 0;
    }

    CameraHandler* handler = new CameraHandler(callback, userData);
    camera->setListener(handler);

    handler->camera = camera;
    handler->cameraId=cameraId;
#if 1
    //setting paramers from previous camera handler
    if (prevCameraParameters != NULL) {
	    camera->setParameters(prevCameraParameters->flatten());
    }
#endif
    handler->params.unflatten(camera->getParameters());

    LOGD("Supported Cameras: %s", handler->params.get("camera-indexes"));
    LOGD("Supported Picture Sizes: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES));
    LOGD("Supported Picture Formats: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS));
    LOGD("Supported Preview Sizes: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES));
    LOGD("Supported Preview Formats: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS));
    LOGD("Supported Preview Frame Rates: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES));
    LOGD("Supported Thumbnail Sizes: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES));
    LOGD("Supported Whitebalance Modes: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE));
    LOGD("Supported Effects: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_EFFECTS));
    LOGD("Supported Scene Modes: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_SCENE_MODES));
    LOGD("Supported Focus Modes: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_FOCUS_MODES));
    LOGD("Supported Antibanding Options: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_ANTIBANDING));
    LOGD("Supported Flash Modes: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_FLASH_MODES));

    //TODO: check if yuv420i format available. Set this format as preview format.

#if USE_RECORDING_INSTEAD_PREVIEW
    status_t err = camera->setPreviewDisplay(sp<ISurface>(NULL /*new DummySurface1*/));
#endif

    ////ATTENTION: switching between two versions: with and without copying memory inside Android OS
    //// see the method  CameraService::Client::copyFrameAndPostCopiedFrame and where it is used
#if 1
    camera->setPreviewCallbackFlags( FRAME_CALLBACK_FLAG_ENABLE_MASK | FRAME_CALLBACK_FLAG_COPY_OUT_MASK);//with copy
#else
    camera->setPreviewCallbackFlags( FRAME_CALLBACK_FLAG_ENABLE_MASK );//without copy
#endif

#if USE_RECORDING_INSTEAD_PREVIEW
    status_t resStart = camera->startRecording();
#else
    status_t resStart = camera->startPreview();
#endif

    if (resStart != 0)
    {
        handler->closeCameraConnect();
        handler = 0;
    }
    return handler;
}

void CameraHandler::closeCameraConnect()
{
    if (camera == NULL)
    {
        LOGI("... camera is NULL");
        return;
    }

    //TODO: ATTENTION! should we do it ALWAYS???
#if USE_RECORDING_INSTEAD_PREVIEW
    camera->stopRecording();
#else
    camera->stopPreview();
#endif

    camera->disconnect();
    camera.clear();

    camera=NULL;
    // ATTENTION!!!!!!!!!!!!!!!!!!!!!!!!!!
    // When we set
    //    camera=NULL
    // above, the pointed instance of android::Camera object is destructed,
    // since this member `camera' has type android::sp<Camera> (android smart pointer template class),
    // and this is the only pointer to it.
    //
    // BUT this instance of CameraHandler is set as a listener for that android::Camera object
    // (see the function CameraHandler::initCameraConnect above),
    // so this instance of CameraHandler is pointed from that android::Camera object as
    //     sp<CameraListener>  mListener
    // and there is no other android smart pointers to this.
    //
    // It means, when that instance of the android::Camera object is destructed,
    // it calls destructor for this CameraHandler instance too.
    //
    // So, this line `camera=NULL' causes to the call `delete this'
    // (see destructor of the template class android::sp)
    //
    // So, we must not call `delete this' after the line, since it just has been called indeed
}

double CameraHandler::getProperty(int propIdx)
{
    switch (propIdx)
    {
    case ANDROID_CAMERA_PROPERTY_FRAMEWIDTH:
    {
        int w,h;
        params.getPreviewSize(&w,&h);
        return w;
    }
    case ANDROID_CAMERA_PROPERTY_FRAMEHEIGHT:
    {
        int w,h;
        params.getPreviewSize(&w,&h);
        return h;
    }
    case ANDROID_CAMERA_PROPERTY_SUPPORTED_PREVIEW_SIZES_STRING:
    {
	    cameraPropertySupportedPreviewSizesString=params.get(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES);
	    double res;
	    memset(&res, 0, sizeof(res));
	    (*( (void**)&res ))= (void*)( cameraPropertySupportedPreviewSizesString.c_str() );

	    return res;
    }

    };
    return -1;
}

void CameraHandler::setProperty(int propIdx, double value)
{
    switch (propIdx)
    {
    case ANDROID_CAMERA_PROPERTY_FRAMEWIDTH:
    {
        int w,h;
        params.getPreviewSize(&w,&h);
        w = (int)value;
        params.setPreviewSize(w,h);
    }
    break;
    case ANDROID_CAMERA_PROPERTY_FRAMEHEIGHT:
    {
        int w,h;
        params.getPreviewSize(&w,&h);
        h = (int)value;
        params.setPreviewSize(w,h);
    }
    break;
    };
}

void CameraHandler::applyProperties(CameraHandler** ppcameraHandler)
{
    LOGD("CameraHandler::applyProperties()");
    CameraHandler* previousCameraHandler=*ppcameraHandler;
    CameraParameters curCameraParameters(previousCameraHandler->params.flatten());

    CameraCallback cameraCallback=previousCameraHandler->cameraCallback;
    void* userData=previousCameraHandler->userData;
    int cameraId=previousCameraHandler->cameraId;

    LOGD("CameraHandler::applyProperties(): before previousCameraHandler->closeCameraConnect");
    previousCameraHandler->closeCameraConnect();
    LOGD("CameraHandler::applyProperties(): after previousCameraHandler->closeCameraConnect");

    LOGD("CameraHandler::applyProperties(): before initCameraConnect");
    CameraHandler* handler=initCameraConnect(cameraCallback, cameraId, userData, &curCameraParameters);
    LOGD("CameraHandler::applyProperties(): after initCameraConnect, handler=0x%x", (int)handler);
    if (handler == NULL) {
	    LOGE("ERROR in applyProperties --- cannot reinit camera");
	    handler=initCameraConnect(cameraCallback, cameraId, userData, NULL);
	    LOGD("CameraHandler::applyProperties(): repeate initCameraConnect after ERROR, handler=0x%x", (int)handler);
	    if (handler == NULL) {
		    LOGE("ERROR in applyProperties --- cannot reinit camera AGAIN --- cannot do anything else");
	    }
    }
    (*ppcameraHandler)=handler;
}

extern "C" {

void* initCameraConnectC(void* callback, int cameraId, void* userData)
{
    return CameraHandler::initCameraConnect((CameraCallback)callback, cameraId, userData, NULL);
}

void closeCameraConnectC(void** camera)
{
    CameraHandler** cc = (CameraHandler**)camera;
    (*cc)->closeCameraConnect();
    *cc = 0;
}

double getCameraPropertyC(void* camera, int propIdx)
{
    return ((CameraHandler*)camera)->getProperty(propIdx);
}

void setCameraPropertyC(void* camera, int propIdx, double value)
{
    ((CameraHandler*)camera)->setProperty(propIdx,value);
}

void applyCameraPropertiesC(void** camera)
{
	CameraHandler::applyProperties((CameraHandler**)camera);
}

}
<commit_msg>Refactoring of native camera implementation<commit_after>#if !defined(ANDROID_r2_2_2) && !defined(ANDROID_r2_3_3) && !defined(ANDROID_r3_0_1)
#error unsupported version of Android
#endif

#include <camera/CameraHardwareInterface.h>
#include "camera_wrapper.h"
#include "../include/camera_properties.h"
#include <string>

//undef logging macro from /system/core/libcutils/loghack.h
#ifdef LOGD
#undef LOGD
#endif

#ifdef LOGI
#undef LOGI
#endif

#ifdef LOGW
#undef LOGW
#endif

#ifdef LOGE
#undef LOGE
#endif

// LOGGING
#include <android/log.h>
#define CAMERA_LOG_TAG "OpenCV_NativeCamera"
#define LOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG, CAMERA_LOG_TAG, __VA_ARGS__))
#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, CAMERA_LOG_TAG, __VA_ARGS__))
#define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, CAMERA_LOG_TAG, __VA_ARGS__))
#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, CAMERA_LOG_TAG, __VA_ARGS__))

using namespace android;

void debugShowFPS()
{
    static int mFrameCount = 0;
    static int mLastFrameCount = 0;
    static nsecs_t mLastFpsTime = systemTime();
    static float mFps = 0;

    mFrameCount++;

    if (( mFrameCount % 30 ) != 0)
        return;

    nsecs_t now = systemTime();
    nsecs_t diff = now - mLastFpsTime;

    if (diff==0)
        return;

    mFps =  ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff;
    mLastFpsTime = now;
    mLastFrameCount = mFrameCount;
    LOGI("### Camera FPS ### [%d] Frames, %.2f FPS", mFrameCount, mFps);
}

class CameraHandler: public CameraListener
{
protected:
    int cameraId;
    sp<Camera> camera;
    CameraParameters params;
    CameraCallback cameraCallback;
    void* userData;

    int emptyCameraCallbackReported;

    void doCall(void* buffer, size_t bufferSize)
    {
        if (cameraCallback == 0)
        {
            if (!emptyCameraCallbackReported)
                LOGE("CameraHandler::doCall(void*, size_t): Camera callback is empty!");

            emptyCameraCallbackReported++;
        }
        else
        {
            bool res = (*cameraCallback)(buffer, bufferSize, userData);

            if(!res)
            {
                LOGE("CameraHandler::doCall(void*, size_t): cameraCallback returns false (camera connection will be closed)");
                closeCameraConnect();
            }
        }
    }

    void doCall(const sp<IMemory>& dataPtr)
    {
        if (dataPtr == NULL)
        {
            LOGE("CameraHandler::doCall(const sp<IMemory>&): dataPtr==NULL (no frame to handle)");
            return;
        }

        size_t size = dataPtr->size();
        if (size <= 0)
        {
            LOGE("CameraHandler::doCall(const sp<IMemory>&): IMemory object is of zero size");
            return;
        }

        void* buffer = (void *)dataPtr->pointer();
        if (!buffer)
        {
            LOGE("CameraHandler::doCall(const sp<IMemory>&): Buffer pointer is NULL");
            return;
        }

        doCall(buffer, size);
    }

    virtual void postDataTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr)
    {
        static uint32_t count = 0;
        count++;

        LOGE("Recording cb: %d %lld %%p Offset:%%d Stride:%%d\n", msgType, timestamp);

        if (dataPtr == NULL)
        {
            LOGE("postDataTimestamp: dataPtr IS ZERO -- returning");
            camera->releaseRecordingFrame(dataPtr);
            LOGE("postDataTimestamp:  camera->releaseRecordingFrame(dataPtr) is done");
            return;
        }

        uint8_t *ptr = (uint8_t*) dataPtr->pointer();
        if (ptr)
            LOGE("VID_CB: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x", ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6], ptr[7], ptr[8], ptr[9]);
        else
            LOGE("postDataTimestamp: Ptr is zero");

        camera->releaseRecordingFrame(dataPtr);
    }

public:
    CameraHandler(CameraCallback callback = 0, void* _userData = 0):
        cameraId(0),
        cameraCallback(callback),
        userData(_userData),
        emptyCameraCallbackReported(0)
    {
        LOGD("Instantiated new CameraHandler (%p, %p)", callback, _userData);
    }

    virtual ~CameraHandler()
    {
            LOGD("CameraHandler destructor is called");
    }

    virtual void notify(int32_t msgType, int32_t ext1, int32_t ext2)
    {
        LOGE("CameraHandler::Notify: msgType=%d ext1=%d ext2=%d\n", msgType, ext1, ext2);
#if 0
        if ( msgType & CAMERA_MSG_FOCUS )
            LOGE("CameraHandler::Notify  AutoFocus %s in %llu us\n", (ext1) ? "OK" : "FAIL", timevalDelay(&autofocus_start));

        if ( msgType & CAMERA_MSG_SHUTTER )
            LOGE("CameraHandler::Notify  Shutter done in %llu us\n", timeval_delay(&picture_start));
#endif
    }

    virtual void postData(int32_t msgType, const sp<IMemory>& dataPtr)
    {
        debugShowFPS();

        if ( msgType & CAMERA_MSG_PREVIEW_FRAME )
        {
            doCall(dataPtr);
            return;
        }

        if (msgType != CAMERA_MSG_PREVIEW_FRAME)
            LOGE("CameraHandler::postData  Recieved message %d is not equal to CAMERA_MSG_PREVIEW_FRAME (%d)", (int) msgType, CAMERA_MSG_PREVIEW_FRAME);

        if ( msgType & CAMERA_MSG_RAW_IMAGE )
            LOGE("CameraHandler::postData  Unexpected data format: RAW\n");

        if (msgType & CAMERA_MSG_POSTVIEW_FRAME)
            LOGE("CameraHandler::postData  Unexpected data format: Postview frame\n");

        if (msgType & CAMERA_MSG_COMPRESSED_IMAGE )
            LOGE("CameraHandler::postData  Unexpected data format: JPEG");
    }

    static CameraHandler* initCameraConnect(const CameraCallback& callback, int cameraId, void* userData, CameraParameters* prevCameraParameters);
    void closeCameraConnect();
    double getProperty(int propIdx);
    void setProperty(int propIdx, double value);
    static void applyProperties(CameraHandler** ppcameraHandler);

    std::string cameraPropertySupportedPreviewSizesString;
};

CameraHandler* CameraHandler::initCameraConnect(const CameraCallback& callback, int cameraId, void* userData, CameraParameters* prevCameraParameters)
{
    LOGD("CameraHandler::initCameraConnect(%p, %d, %p, %p)", callback, cameraId, userData, prevCameraParameters);

    sp<Camera> camera = 0;

#ifdef ANDROID_r2_2_2
    camera = Camera::connect();
#endif
#ifdef ANDROID_r2_3_3
    camera = Camera::connect(cameraId);
#endif

    if ( 0 == camera.get() )
    {
        LOGE("initCameraConnect: Unable to connect to CameraService\n");
        return 0;
    }

    CameraHandler* handler = new CameraHandler(callback, userData);
    camera->setListener(handler);

    handler->camera = camera;
    handler->cameraId = cameraId;

    if (prevCameraParameters != 0)
    {
        LOGI("initCameraConnect: Setting paramers from previous camera handler");
        camera->setParameters(prevCameraParameters->flatten());
    }

    android::String8 params_str = camera->getParameters();
    LOGI("initCameraConnect: [%s]", params_str.string());

    handler->params.unflatten(params_str);

    LOGD("Supported Cameras: %s", handler->params.get("camera-indexes"));
    LOGD("Supported Picture Sizes: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES));
    LOGD("Supported Picture Formats: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS));
    LOGD("Supported Preview Sizes: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES));
    LOGD("Supported Preview Formats: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS));
    LOGD("Supported Preview Frame Rates: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES));
    LOGD("Supported Thumbnail Sizes: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES));
    LOGD("Supported Whitebalance Modes: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE));
    LOGD("Supported Effects: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_EFFECTS));
    LOGD("Supported Scene Modes: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_SCENE_MODES));
    LOGD("Supported Focus Modes: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_FOCUS_MODES));
    LOGD("Supported Antibanding Options: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_ANTIBANDING));
    LOGD("Supported Flash Modes: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_FLASH_MODES));

    //TODO: check if yuv420i format available. Set this format as preview format.

    status_t pdstatus = camera->setPreviewDisplay(sp<ISurface>(0 /*new DummySurface*/));
    if (pdstatus != 0)
    {
        LOGE("initCameraConnect: failed setPreviewDisplay(0) call; camera migth not work correcttly on some devices");
    }

    ////ATTENTION: switching between two versions: with and without copying memory inside Android OS
    //// see the method  CameraService::Client::copyFrameAndPostCopiedFrame and where it is used
#if 1
    camera->setPreviewCallbackFlags( FRAME_CALLBACK_FLAG_ENABLE_MASK | FRAME_CALLBACK_FLAG_COPY_OUT_MASK);//with copy
#else
    camera->setPreviewCallbackFlags( FRAME_CALLBACK_FLAG_ENABLE_MASK );//without copy
#endif

    status_t resStart = camera->startPreview();

    if (resStart != 0)
    {
        LOGE("initCameraConnect: startPreview() fails. Closing camera connection...");
        handler->closeCameraConnect();
        handler = 0;
    }

    return handler;
}

void CameraHandler::closeCameraConnect()
{
    if (camera == NULL)
    {
        LOGI("... camera is already NULL");
        return;
    }

    camera->stopPreview();
    camera->disconnect();
    camera.clear();

    camera=NULL;
    // ATTENTION!!!!!!!!!!!!!!!!!!!!!!!!!!
    // When we set
    //    camera=NULL
    // above, the pointed instance of android::Camera object is destructed,
    // since this member `camera' has type android::sp<Camera> (android smart pointer template class),
    // and this is the only pointer to it.
    //
    // BUT this instance of CameraHandler is set as a listener for that android::Camera object
    // (see the function CameraHandler::initCameraConnect above),
    // so this instance of CameraHandler is pointed from that android::Camera object as
    //     sp<CameraListener>  mListener
    // and there is no other android smart pointers to this.
    //
    // It means, when that instance of the android::Camera object is destructed,
    // it calls destructor for this CameraHandler instance too.
    //
    // So, this line `camera=NULL' causes to the call `delete this'
    // (see destructor of the template class android::sp)
    //
    // So, we must not call `delete this' after the line, since it just has been called indeed
}

double CameraHandler::getProperty(int propIdx)
{
    switch (propIdx)
    {
    case ANDROID_CAMERA_PROPERTY_FRAMEWIDTH:
    {
        int w,h;
        params.getPreviewSize(&w, &h);
        return w;
    }
    case ANDROID_CAMERA_PROPERTY_FRAMEHEIGHT:
    {
        int w,h;
        params.getPreviewSize(&w, &h);
        return h;
    }
    case ANDROID_CAMERA_PROPERTY_SUPPORTED_PREVIEW_SIZES_STRING:
    {
            cameraPropertySupportedPreviewSizesString = params.get(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES);
	    double res;
	    memset(&res, 0, sizeof(res));
	    (*( (void**)&res ))= (void*)( cameraPropertySupportedPreviewSizesString.c_str() );

	    return res;
    }

    };
    return -1;
}

void CameraHandler::setProperty(int propIdx, double value)
{
    switch (propIdx)
    {
    case ANDROID_CAMERA_PROPERTY_FRAMEWIDTH:
    {
        int w,h;
        params.getPreviewSize(&w, &h);
        w = (int)value;
        params.setPreviewSize(w, h);
    }
    break;
    case ANDROID_CAMERA_PROPERTY_FRAMEHEIGHT:
    {
        int w,h;
        params.getPreviewSize(&w, &h);
        h = (int)value;
        params.setPreviewSize(w, h);
    }
    break;
    };
}

void CameraHandler::applyProperties(CameraHandler** ppcameraHandler)
{
    LOGD("CameraHandler::applyProperties()");
    CameraHandler* previousCameraHandler=*ppcameraHandler;
    CameraParameters curCameraParameters(previousCameraHandler->params.flatten());

    CameraCallback cameraCallback=previousCameraHandler->cameraCallback;
    void* userData=previousCameraHandler->userData;
    int cameraId=previousCameraHandler->cameraId;

    LOGD("CameraHandler::applyProperties(): before previousCameraHandler->closeCameraConnect");
    previousCameraHandler->closeCameraConnect();
    LOGD("CameraHandler::applyProperties(): after previousCameraHandler->closeCameraConnect");

    LOGD("CameraHandler::applyProperties(): before initCameraConnect");
    CameraHandler* handler=initCameraConnect(cameraCallback, cameraId, userData, &curCameraParameters);
    LOGD("CameraHandler::applyProperties(): after initCameraConnect, handler=0x%x", (int)handler);
    if (handler == NULL) {
	    LOGE("ERROR in applyProperties --- cannot reinit camera");
	    handler=initCameraConnect(cameraCallback, cameraId, userData, NULL);
	    LOGD("CameraHandler::applyProperties(): repeate initCameraConnect after ERROR, handler=0x%x", (int)handler);
	    if (handler == NULL) {
		    LOGE("ERROR in applyProperties --- cannot reinit camera AGAIN --- cannot do anything else");
	    }
    }
    (*ppcameraHandler)=handler;
}

extern "C" {

void* initCameraConnectC(void* callback, int cameraId, void* userData)
{
    return CameraHandler::initCameraConnect((CameraCallback)callback, cameraId, userData, NULL);
}

void closeCameraConnectC(void** camera)
{
    CameraHandler** cc = (CameraHandler**)camera;
    (*cc)->closeCameraConnect();
    *cc = 0;
}

double getCameraPropertyC(void* camera, int propIdx)
{
    return ((CameraHandler*)camera)->getProperty(propIdx);
}

void setCameraPropertyC(void* camera, int propIdx, double value)
{
    ((CameraHandler*)camera)->setProperty(propIdx,value);
}

void applyCameraPropertiesC(void** camera)
{
	CameraHandler::applyProperties((CameraHandler**)camera);
}

}
<|endoftext|>


<commit_before>// Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
// LICENSE and NOTICE for details. LLNL-CODE-806117.
//
// This file is part of the MFEM library. For more information and source code
// availability visit https://mfem.org.
//
// MFEM is free software; you can redistribute it and/or modify it under the
// terms of the BSD-3 license. We welcome feedback and contributions, see file
// CONTRIBUTING.md for details.

#include <mfem.hpp>

#include "materials/linear_elastic.hpp"
#include "materials/neohookean.hpp"
#include "operators/elasticity_gradient_operator.hpp"
#include "operators/elasticity_operator.hpp"
#include "preconditioners/diagonal_preconditioner.hpp"

using namespace std;
using namespace mfem;

/// This example only works in 3D.
constexpr int dimension = 3;

int main(int argc, char *argv[])
{
   MPI_Session mpi;
   int myid = mpi.WorldRank();

   int order = 1;
   const char *device_config = "cpu";
   int diagpc_type = ElasticityDiagonalPreconditioner::Type::Diagonal;
   int serial_refinement_levels = 0;
   bool paraview_save = false;

   OptionsParser args(argc, argv);
   args.AddOption(&order, "-o", "--order",
                  "Finite element order (polynomial degree).");
   args.AddOption(&device_config, "-d", "--device",
                  "Device configuration string, see Device::Configure().");
   args.AddOption(&diagpc_type, "-pc", "--pctype",
                  "Select diagonal preconditioner type"
                  " (0:Diagonal, 1:BlockDiagonal).");
   args.AddOption(&serial_refinement_levels, "-rs", "--ref-serial",
                  "Number of uniform refinements on the serial mesh.");
   args.AddOption(&paraview_save, "-pvs", "--paraview-save", "-no-pvs",
                  "--no-paraview-save",
                  "Enable or disable ParaView DataCollection save.");
   args.Parse();
   if (!args.Good())
   {
      if (myid == 0)
      {
         args.PrintUsage(cout);
      }
      return 1;
   }
   if (myid == 0)
   {
      args.PrintOptions(cout);
   }

   Device device(device_config);
   if (myid == 0)
   {
      device.Print();
   }

   auto mesh =
      Mesh::MakeCartesian3D(8, 1, 1, Element::HEXAHEDRON, 8.0, 1.0, 1.0);
   if (mesh.Dimension() != dimension)
   {
      MFEM_ABORT("This example only works in 3D.");
   }
   mesh.EnsureNodes();

   for (int l = 0; l < serial_refinement_levels; l++)
   {
      mesh.UniformRefinement();
   }

   ParMesh pmesh(MPI_COMM_WORLD, mesh);
   mesh.Clear();

   // Create the elasticity operator on the parallel mesh.
   ElasticityOperator elasticity_op(pmesh, order);

   // Create and set the material type. We define it's GradientType during
   // instantiation.
   const NeoHookeanMaterial<dimension, GradientType::DualNumbers> material{};
   elasticity_op.SetMaterial(material);

   // Define all essential boundaries. In this specific example, this includes
   // all fixed and statically displaced degrees of freedom on mesh entities in
   // the defined attributes.
   if (pmesh.bdr_attributes.Size())
   {
      Array<int> ess_attr(pmesh.bdr_attributes.Max());
      ess_attr = 0;
      ess_attr[4] = 1;
      ess_attr[2] = 1;
      elasticity_op.SetEssentialAttributes(ess_attr);
   }

   // Define all statically displaced mesh attributes. On these degrees of
   // freedom (determined from the mesh attributes), a fixed displacement is
   // prescribed.
   if (pmesh.bdr_attributes.Size())
   {
      Array<int> displaced_attr(pmesh.bdr_attributes.Max());
      displaced_attr = 0;
      displaced_attr[2] = 1;
      elasticity_op.SetDisplacedAttributes(displaced_attr);
   }

   ParGridFunction U_gf(&elasticity_op.h1_fes_);
   U_gf = 0.0;

   Vector U;
   U_gf.GetTrueDofs(U);

   // Prescribe a fixed displacement to the displaced degrees of freedom.
   U.SetSubVector(elasticity_op.GetDisplacedTDofs(), 1.0e-2);

   // Define the type of preconditioner to use for the linear solver.
   ElasticityDiagonalPreconditioner diagonal_pc(
      static_cast<ElasticityDiagonalPreconditioner::Type>(diagpc_type));

   CGSolver cg(MPI_COMM_WORLD);
   cg.SetRelTol(1e-1);
   cg.SetMaxIter(10000);
   cg.SetPrintLevel(2);
   cg.SetPreconditioner(diagonal_pc);

   NewtonSolver newton(MPI_COMM_WORLD);
   newton.SetSolver(cg);
   newton.SetOperator(elasticity_op);
   newton.SetRelTol(1e-6);
   newton.SetMaxIter(10);
   newton.SetPrintLevel(1);

   Vector zero;
   newton.Mult(zero, U);

   U_gf.Distribute(U);

   if (paraview_save)
   {
      ParaViewDataCollection *pd = NULL;
      pd = new ParaViewDataCollection("ex42_output", &pmesh);
      pd->RegisterField("solution", &U_gf);
      pd->SetLevelsOfDetail(order);
      pd->SetDataFormat(VTKFormat::BINARY);
      pd->SetHighOrderOutput(true);
      pd->SetCycle(0);
      pd->SetTime(0.0);
      pd->Save();
      delete pd;
   }

   return 0;
}
<commit_msg>little description of the miniapp<commit_after>// Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
// LICENSE and NOTICE for details. LLNL-CODE-806117.
//
// This file is part of the MFEM library. For more information and source code
// availability visit https://mfem.org.
//
// MFEM is free software; you can redistribute it and/or modify it under the
// terms of the BSD-3 license. We welcome feedback and contributions, see file
// CONTRIBUTING.md for details.

// This miniapp solves a quasistatic solid mechanics problem assuming an elastic
// material and no body forces.
//
// The equation
//                   ∇⋅σ(∇u) = 0
//
// with stress σ is solved for displacement u.
//
//             +----------+----------+
//   fixed --->|                     |<--- constant displacement
//             |                     |
//             +----------+----------+

#include <mfem.hpp>

#include "materials/linear_elastic.hpp"
#include "materials/neohookean.hpp"
#include "operators/elasticity_gradient_operator.hpp"
#include "operators/elasticity_operator.hpp"
#include "preconditioners/diagonal_preconditioner.hpp"

using namespace std;
using namespace mfem;

/// This example only works in 3D.
constexpr int dimension = 3;

int main(int argc, char *argv[])
{
   MPI_Session mpi;
   int myid = mpi.WorldRank();

   int order = 1;
   const char *device_config = "cpu";
   int diagpc_type = ElasticityDiagonalPreconditioner::Type::Diagonal;
   int serial_refinement_levels = 0;
   bool paraview_save = false;

   OptionsParser args(argc, argv);
   args.AddOption(&order, "-o", "--order",
                  "Finite element order (polynomial degree).");
   args.AddOption(&device_config, "-d", "--device",
                  "Device configuration string, see Device::Configure().");
   args.AddOption(&diagpc_type, "-pc", "--pctype",
                  "Select diagonal preconditioner type"
                  " (0:Diagonal, 1:BlockDiagonal).");
   args.AddOption(&serial_refinement_levels, "-rs", "--ref-serial",
                  "Number of uniform refinements on the serial mesh.");
   args.AddOption(&paraview_save, "-pvs", "--paraview-save", "-no-pvs",
                  "--no-paraview-save",
                  "Enable or disable ParaView DataCollection save.");
   args.Parse();
   if (!args.Good())
   {
      if (myid == 0)
      {
         args.PrintUsage(cout);
      }
      return 1;
   }
   if (myid == 0)
   {
      args.PrintOptions(cout);
   }

   Device device(device_config);
   if (myid == 0)
   {
      device.Print();
   }

   auto mesh =
      Mesh::MakeCartesian3D(8, 1, 1, Element::HEXAHEDRON, 8.0, 1.0, 1.0);
   if (mesh.Dimension() != dimension)
   {
      MFEM_ABORT("This example only works in 3D.");
   }
   mesh.EnsureNodes();

   for (int l = 0; l < serial_refinement_levels; l++)
   {
      mesh.UniformRefinement();
   }

   ParMesh pmesh(MPI_COMM_WORLD, mesh);
   mesh.Clear();

   // Create the elasticity operator on the parallel mesh.
   ElasticityOperator elasticity_op(pmesh, order);

   // Create and set the material type. We define it's GradientType during
   // instantiation.
   const NeoHookeanMaterial<dimension, GradientType::DualNumbers> material{};
   elasticity_op.SetMaterial(material);

   // Define all essential boundaries. In this specific example, this includes
   // all fixed and statically displaced degrees of freedom on mesh entities in
   // the defined attributes.
   if (pmesh.bdr_attributes.Size())
   {
      Array<int> ess_attr(pmesh.bdr_attributes.Max());
      ess_attr = 0;
      ess_attr[4] = 1;
      ess_attr[2] = 1;
      elasticity_op.SetEssentialAttributes(ess_attr);
   }

   // Define all statically displaced mesh attributes. On these degrees of
   // freedom (determined from the mesh attributes), a fixed displacement is
   // prescribed.
   if (pmesh.bdr_attributes.Size())
   {
      Array<int> displaced_attr(pmesh.bdr_attributes.Max());
      displaced_attr = 0;
      displaced_attr[2] = 1;
      elasticity_op.SetDisplacedAttributes(displaced_attr);
   }

   ParGridFunction U_gf(&elasticity_op.h1_fes_);
   U_gf = 0.0;

   Vector U;
   U_gf.GetTrueDofs(U);

   // Prescribe a fixed displacement to the displaced degrees of freedom.
   U.SetSubVector(elasticity_op.GetDisplacedTDofs(), 1.0e-2);

   // Define the type of preconditioner to use for the linear solver.
   ElasticityDiagonalPreconditioner diagonal_pc(
      static_cast<ElasticityDiagonalPreconditioner::Type>(diagpc_type));

   CGSolver cg(MPI_COMM_WORLD);
   cg.SetRelTol(1e-1);
   cg.SetMaxIter(10000);
   cg.SetPrintLevel(2);
   cg.SetPreconditioner(diagonal_pc);

   NewtonSolver newton(MPI_COMM_WORLD);
   newton.SetSolver(cg);
   newton.SetOperator(elasticity_op);
   newton.SetRelTol(1e-6);
   newton.SetMaxIter(10);
   newton.SetPrintLevel(1);

   Vector zero;
   newton.Mult(zero, U);

   U_gf.Distribute(U);

   if (paraview_save)
   {
      ParaViewDataCollection *pd = NULL;
      pd = new ParaViewDataCollection("ex42_output", &pmesh);
      pd->RegisterField("solution", &U_gf);
      pd->SetLevelsOfDetail(order);
      pd->SetDataFormat(VTKFormat::BINARY);
      pd->SetHighOrderOutput(true);
      pd->SetCycle(0);
      pd->SetTime(0.0);
      pd->Save();
      delete pd;
   }

   return 0;
}
<|endoftext|>


<commit_before>/*
 * redsea - RDS decoder
 * Copyright (c) Oona Räisänen OH2EIQ (windyoona@gmail.com)
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 */

#include "redsea.h"

#include <iostream>

#include "bits2blocks.h"
#include "groups.h"

namespace redsea {

void printShort(Station station) {
    printf("%s 0x%04x %s\n", station.getPS().c_str(), station.getPI(), station.getRT().c_str());

  //printf("%04x %2d%s TP:%d PTY:%d\n", station.pi, group.type, group.type_ab == 1 ? "B" : "A",
  //    group.tp, group.pty);
}

} // namespace redsea

int main() {
  redsea::BlockStream block_stream;
  std::map<uint16_t, redsea::Station> stations;

  uint16_t pi=0, prev_new_pi=0, new_pi=0;

  while (!block_stream.isEOF()) {
    auto blockbits = block_stream.getNextGroup();

    prev_new_pi = new_pi;
    new_pi = blockbits[0];

    if (new_pi == prev_new_pi) {
      pi = new_pi;

    } else if (new_pi != pi) {
      continue;
    }

    redsea::Group group(blockbits);

    if (stations.find(pi) != stations.end()) {
      stations[pi].update(group);
    } else {
      stations.insert({pi, redsea::Station(pi)});
    }

    //printShort(stations[pi]);
  }
}
<commit_msg>group counter<commit_after>/*
 * redsea - RDS decoder
 * Copyright (c) Oona Räisänen OH2EIQ (windyoona@gmail.com)
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 */

#include "redsea.h"

#include <iostream>

#include "bits2blocks.h"
#include "groups.h"

namespace redsea {

void printShort(Station station) {
    printf("%s 0x%04x %s\n", station.getPS().c_str(), station.getPI(), station.getRT().c_str());

  //printf("%04x %2d%s TP:%d PTY:%d\n", station.pi, group.type, group.type_ab == 1 ? "B" : "A",
  //    group.tp, group.pty);
}

} // namespace redsea

int main() {
  redsea::BlockStream block_stream;
  std::map<uint16_t, redsea::Station> stations;

  uint16_t pi=0, prev_new_pi=0, new_pi=0;

  int group_counter = 0;
  while (!block_stream.isEOF()) {
    auto blockbits = block_stream.getNextGroup();
    group_counter ++;

    prev_new_pi = new_pi;
    new_pi = blockbits[0];

    if (new_pi == prev_new_pi) {
      pi = new_pi;

    } else if (new_pi != pi) {
      continue;
    }

    redsea::Group group(blockbits);

    if (stations.find(pi) != stations.end()) {
      stations[pi].update(group);
    } else {
      stations.insert({pi, redsea::Station(pi)});
    }

    //printShort(stations[pi]);
  }
}
<|endoftext|>


<commit_before>#include "EM.h"
#include "MathFunctions.h"
#include <limits>
#include <iostream>
#include <fstream>
#include <sstream>
#include <algorithm>

namespace Terran {

using namespace std;

EM::~EM() {

}

EM::EM(const std::vector<double> &data) :
    data_(data),
    pikn_(data.size(), std::vector<double>(0)),
    maxSteps_(100),
    tolerance_(0.1) {
    if(data_.size() == 0)
        throw(std::runtime_error("Cannot initialize EM with empty dataset"));
}

EM::EM(const std::vector<double> &data, const std::vector<Param> &params) :
    data_(data),
    params_(params),
    pikn_(data.size(), std::vector<double>(params.size(),0)),
    maxSteps_(100),
    tolerance_(0.1) {

    if(data_.size() == 0)
        throw(std::runtime_error("Cannot initialize EM with empty dataset"));

    setParameters(params);
}

void EM::setParameters(const std::vector<Param> &input) {
    double psum = 0;
    for(int i=0; i<input.size(); i++) {
        psum += input[i].p;
        if(input[i].p <= 0)
            throw(std::runtime_error("Cannot have p <= 0 in parameters"));
        if(input[i].p > 1)
            throw(std::runtime_error("Cannot have p > 1 in parameters"));
        if(input[i].s <= 0)
            throw(std::runtime_error("Cannot have s <= 0 in parameters"));
    }
    if(psum > 1.0000001) {
        throw(std::runtime_error("Initial probabilities sum to greater than 1"));
    }
    params_ = input;
    vector<vector<double> > temp(data_.size(), std::vector<double>(params_.size(),0));
    pikn_ = temp;
}

std::vector<Param> EM::getParams() const {
    return params_;
}

int EM::getDataSize() const {
    return data_.size();
}

double EM::getLikelihood() const {
    double lambda = 0;
    for(int n=0; n<data_.size(); n++) {
        double sum = 0;
        for(int k=0; k<params_.size(); k++) {
            sum += qkn(k,n);
        }
        lambda += log(sum);
    }
    return lambda;
}

void EM::setMaxSteps(int maxSteps) {
    maxSteps_ = maxSteps;
}

int EM::getMaxSteps() const {
    return maxSteps_;
}

void EM::setTolerance(double tol) {
    tolerance_ = tol;
}

double EM::getTolerance() const {
    return tolerance_;
}

bool EM::run() {
    if(params_.size() == 0) {
        throw(std::runtime_error("EM::run(), parameters are not set"));
    }
    int steps = 0;
    double likelihood = getLikelihood();
    double likelihoodOld;
    // keep an old copy of params
    vector<Param> paramsOld;

    do {
        likelihoodOld = likelihood;
        paramsOld = params_;
        EStep();
        MStep();
        steps++;
        likelihood = getLikelihood();
        // if the likelihood increased, then we revert back to the old params right before
        // we took the step and break;
        // (the likelihood may increase due to convergence/numerical issues, and is
        // an indication of convergence)

        // likelihood decreases normally if a convergence criterion has been reached
        if(likelihood < likelihoodOld) {
            params_ = paramsOld;
            break;
        }
    // Stop EM if:
    // a. likelihood reaches the specified tolerance
    // b. maxmimum number of steps reached
    } while(likelihood - likelihoodOld > tolerance_ && steps < maxSteps_);

    return (steps < maxSteps_);
}

// the number of components decrease.
bool EM::adaptiveRun(double cutoff) {

    if(params_.size() == 0) {
        throw(std::runtime_error("EM::adaptiveRun(), parameters are not set"));
    }

	for(int i=0; i < data_.size(); i++) {
		pikn_[i].resize(params_.size(), 0);
	}

    int steps = 0;

    double likelihood = getLikelihood();
    double likelihoodOld;

    // keep an old copy of params
    vector<Param> paramsOld;

    do {
        likelihoodOld = getLikelihood();
        paramsOld = params_;
        EStep();
        MStep();
        steps++;
        likelihood = getLikelihood();
        vector<Param> newParams;
        for(int i=0; i < params_.size(); i++)
            if(params_[i].p > cutoff)
                newParams.push_back(params_[i]);

        if(newParams.size() != params_.size()) {
            params_ = newParams;
        } else if(likelihood < likelihoodOld) {
            params_ = paramsOld;
            break;
        }
    // Stop EM if:
    // a. likelihood reaches the specified tolerance
    // b. maximimum number of steps reached
    } while(likelihood-likelihoodOld > tolerance_ && steps < maxSteps_);

    return (steps < maxSteps_);
}

// TODO: set pikn size properly!!
void EM::multiAdaptiveRun(double cutoff, int numParams, int numTries) {
    vector<Param> bestParams;

    double bestLikelihood = -numeric_limits<double>::max();
    int attempts = 0;

    do {
        // initialize a set of random parameters
        vector<Param> params;
        vector<double> mean = sampleDomain(numParams);
        for(int i=0; i < mean.size(); i++) {
            Param p;
            p.p = 1.0/numParams;
            p.u = mean[i];
            // todo, should s be variable as well?
            p.s = 0.3;
            params.push_back(p);
        }
        setParameters(params);
        adaptiveRun(cutoff);
        double newLikelihood = getLikelihood();

        if(newLikelihood > bestLikelihood) {
            bestLikelihood = newLikelihood;
            bestParams = getParams();
        }
        /*
        vector<Param> testParams = getParams();
        for(int i=0; i < testParams.size(); i++) {
            cout << testParams[i].p << " " << testParams[i].u << " " << testParams[i].s << endl;
        }
        cout << "Likelihood: " << getLikelihood() << endl;
        */
        attempts++;
    } while(attempts < numTries);
    params_ = bestParams;
}

void EM::kernelAdaptiveRun() {

	cout << "starting KAR" << endl;

	// bandwidth estimation needs to be subclassed and computed
	// periodic and nonperiodic spaces compute differently presumably
	double bandwidth = 0.3;

	vector<double> randsample = data_;
	random_shuffle(randsample.begin(), randsample.end());
	unsigned int numParams = min((int)randsample.size(), 100);

	params_.resize(numParams);
	for(int k=0; k < numParams; k++) {
		Param p;
		p.u = data_[k];
		p.s = bandwidth;
		p.p = (double) 1 / (double) params_.size();
		params_[k] = p;
	}

	for(int i=0; i < data_.size(); i++) {
		pikn_[i].resize(params_.size(), 0);
	}

	// adaptive run using a varying cutoff (slowly increasing);
	// invariant: cutoff must always be > 1 / num_components
	// cutoff set cutoff to 1/10th of 1/num_components?

	int steps = 0;

    double likelihood = getLikelihood();
    double likelihoodOld;

    // keep an old copy of params
    vector<Param> paramsOld;

    do {
		// slowly increase params size as needed
		cout << steps << " " << params_.size() << endl;

		double cutoff = 0.5/params_.size();
        likelihoodOld = getLikelihood();
        paramsOld = params_;
		cout << "e" << endl;
        EStep();
		cout << "m" << endl;
        MStep();
        steps++;
        likelihood = getLikelihood();
        vector<Param> newParams;
		// slow as molasses - switch to linked list later so pruning is done instead
        for(int i=0; i < params_.size(); i++) {
			cout << params_[i].p << endl;
            if(params_[i].p > cutoff)
                newParams.push_back(params_[i]);
		}

        if(newParams.size() != params_.size()) {
			cout << "deleted " << params_.size() - newParams.size() << " components." << endl;
            params_ = newParams;
        } else if(likelihood < likelihoodOld) {
            params_ = paramsOld;
            break;
        }
    // Stop EM if:
    // a. likelihood reaches the specified tolerance
    // b. maximimum number of steps reached
    } while(likelihood-likelihoodOld > tolerance_ && steps < maxSteps_);

}

void EM::EStep() {
    for(int n=0; n<data_.size(); n++) {
        double sum = 0;
        for(int k=0; k<params_.size(); k++) {
            sum += qkn(k,n);
        }
        for(int k=0; k<params_.size(); k++) {
            pikn_[n][k] = qkn(k,n)/sum;
        }
    }
    testIntegrity();
}

void EM::testIntegrity() const {
    double sum = 0;
    for(int k=0; k<params_.size(); k++) {
        for(int n=0; n<data_.size(); n++) {
            sum += pikn_[n][k];
        }
        if(fabs(sum-1.0) < 1e-7)
            throw(std::runtime_error("pikn no longer sums to 1"));
    }
};

}
<commit_msg>Debugging kernelAdaptiveRun<commit_after>#include "EM.h"
#include "MathFunctions.h"
#include <limits>
#include <iostream>
#include <fstream>
#include <sstream>
#include <algorithm>

namespace Terran {

using namespace std;

EM::~EM() {

}

EM::EM(const std::vector<double> &data) :
    data_(data),
    pikn_(data.size(), std::vector<double>(0)),
    maxSteps_(100),
    tolerance_(0.1) {
    if(data_.size() == 0)
        throw(std::runtime_error("Cannot initialize EM with empty dataset"));
}

EM::EM(const std::vector<double> &data, const std::vector<Param> &params) :
    data_(data),
    params_(params),
    pikn_(data.size(), std::vector<double>(params.size(),0)),
    maxSteps_(100),
    tolerance_(0.1) {

    if(data_.size() == 0)
        throw(std::runtime_error("Cannot initialize EM with empty dataset"));

    setParameters(params);
}

void EM::setParameters(const std::vector<Param> &input) {
    double psum = 0;
    for(int i=0; i<input.size(); i++) {
        psum += input[i].p;
        if(input[i].p <= 0)
            throw(std::runtime_error("Cannot have p <= 0 in parameters"));
        if(input[i].p > 1)
            throw(std::runtime_error("Cannot have p > 1 in parameters"));
        if(input[i].s <= 0)
            throw(std::runtime_error("Cannot have s <= 0 in parameters"));
    }
    if(psum > 1.0000001) {
        throw(std::runtime_error("Initial probabilities sum to greater than 1"));
    }
    params_ = input;
    vector<vector<double> > temp(data_.size(), std::vector<double>(params_.size(),0));
    pikn_ = temp;
}

std::vector<Param> EM::getParams() const {
    return params_;
}

int EM::getDataSize() const {
    return data_.size();
}

double EM::getLikelihood() const {
    double lambda = 0;
    for(int n=0; n<data_.size(); n++) {
        double sum = 0;
        for(int k=0; k<params_.size(); k++) {
            sum += qkn(k,n);
        }
        lambda += log(sum);
    }
    return lambda;
}

void EM::setMaxSteps(int maxSteps) {
    maxSteps_ = maxSteps;
}

int EM::getMaxSteps() const {
    return maxSteps_;
}

void EM::setTolerance(double tol) {
    tolerance_ = tol;
}

double EM::getTolerance() const {
    return tolerance_;
}

bool EM::run() {
    if(params_.size() == 0) {
        throw(std::runtime_error("EM::run(), parameters are not set"));
    }
    int steps = 0;
    double likelihood = getLikelihood();
    double likelihoodOld;
    // keep an old copy of params
    vector<Param> paramsOld;

    do {
        likelihoodOld = likelihood;
        paramsOld = params_;
        EStep();
        MStep();
        steps++;
        likelihood = getLikelihood();
        // if the likelihood increased, then we revert back to the old params right before
        // we took the step and break;
        // (the likelihood may increase due to convergence/numerical issues, and is
        // an indication of convergence)

        // likelihood decreases normally if a convergence criterion has been reached
        if(likelihood < likelihoodOld) {
            params_ = paramsOld;
            break;
        }
    // Stop EM if:
    // a. likelihood reaches the specified tolerance
    // b. maxmimum number of steps reached
    } while(likelihood - likelihoodOld > tolerance_ && steps < maxSteps_);

    return (steps < maxSteps_);
}

// the number of components decrease.
bool EM::adaptiveRun(double cutoff) {

    if(params_.size() == 0) {
        throw(std::runtime_error("EM::adaptiveRun(), parameters are not set"));
    }

	for(int i=0; i < data_.size(); i++) {
		pikn_[i].resize(params_.size(), 0);
	}

    int steps = 0;

    double likelihood = getLikelihood();
    double likelihoodOld;

    // keep an old copy of params
    vector<Param> paramsOld;

    do {
        likelihoodOld = getLikelihood();
        paramsOld = params_;
        EStep();
        MStep();
        steps++;
        likelihood = getLikelihood();
        vector<Param> newParams;
        for(int i=0; i < params_.size(); i++)
            if(params_[i].p > cutoff)
                newParams.push_back(params_[i]);

        if(newParams.size() != params_.size()) {
            params_ = newParams;
        } else if(likelihood < likelihoodOld) {
            params_ = paramsOld;
            break;
        }
    // Stop EM if:
    // a. likelihood reaches the specified tolerance
    // b. maximimum number of steps reached
    } while(likelihood-likelihoodOld > tolerance_ && steps < maxSteps_);

    return (steps < maxSteps_);
}

// TODO: set pikn size properly!!
void EM::multiAdaptiveRun(double cutoff, int numParams, int numTries) {
    vector<Param> bestParams;

    double bestLikelihood = -numeric_limits<double>::max();
    int attempts = 0;

    do {
        // initialize a set of random parameters
        vector<Param> params;
        vector<double> mean = sampleDomain(numParams);
        for(int i=0; i < mean.size(); i++) {
            Param p;
            p.p = 1.0/numParams;
            p.u = mean[i];
            // todo, should s be variable as well?
            p.s = 0.3;
            params.push_back(p);
        }
        setParameters(params);
        adaptiveRun(cutoff);
        double newLikelihood = getLikelihood();

        if(newLikelihood > bestLikelihood) {
            bestLikelihood = newLikelihood;
            bestParams = getParams();
        }
        /*
        vector<Param> testParams = getParams();
        for(int i=0; i < testParams.size(); i++) {
            cout << testParams[i].p << " " << testParams[i].u << " " << testParams[i].s << endl;
        }
        cout << "Likelihood: " << getLikelihood() << endl;
        */
        attempts++;
    } while(attempts < numTries);
    params_ = bestParams;
}

void EM::kernelAdaptiveRun() {

	cout << "starting KAR" << endl;

	// bandwidth estimation needs to be subclassed and computed
	// periodic and nonperiodic spaces compute differently presumably
	double bandwidth = 0.3;

	vector<double> randsample = data_;
	random_shuffle(randsample.begin(), randsample.end());
	unsigned int numParams = min((int)randsample.size(), 100);

	params_.resize(numParams);
	for(int k=0; k < numParams; k++) {
		Param p;
		p.u = data_[k];
		p.s = bandwidth;
		p.p = (double) 1 / (double) params_.size();
		params_[k] = p;
	}

	for(int i=0; i < data_.size(); i++) {
		pikn_[i].resize(params_.size(), 0);
	}

	// adaptive run using a varying cutoff (slowly increasing);
	// invariant: cutoff must always be > 1 / num_components
	// cutoff set cutoff to 1/10th of 1/num_components?

	int steps = 0;

    double likelihood = getLikelihood();
    double likelihoodOld;

    // keep an old copy of params
    vector<Param> paramsOld;

	    for(int i=0; i < params_.size(); i++) {
			cout << params_[i].p << " " << params_[i].u << " " << params_[i].s <<  endl;
		}
		return;

    do {
		// slowly increase params size as needed
		cout << steps << " " << params_.size() << endl;

		double cutoff = 0.5/params_.size();
        likelihoodOld = getLikelihood();
        paramsOld = params_;
		cout << "e" << endl;
        EStep();
		cout << "m" << endl;
        MStep();
        steps++;
        likelihood = getLikelihood();
        vector<Param> newParams;
		// slow as molasses - switch to linked list later so pruning is done instead
        for(int i=0; i < params_.size(); i++) {
			cout << params_[i].p << endl;
            if(params_[i].p > cutoff)
                newParams.push_back(params_[i]);
		}

        if(newParams.size() != params_.size()) {
			cout << "deleted " << params_.size() - newParams.size() << " components." << endl;
            params_ = newParams;
        } else if(likelihood < likelihoodOld) {
            params_ = paramsOld;
            break;
        }
    // Stop EM if:
    // a. likelihood reaches the specified tolerance
    // b. maximimum number of steps reached
    } while(likelihood-likelihoodOld > tolerance_ && steps < maxSteps_);

}

void EM::EStep() {
    for(int n=0; n<data_.size(); n++) {
        double sum = 0;
        for(int k=0; k<params_.size(); k++) {
            sum += qkn(k,n);
        }
        for(int k=0; k<params_.size(); k++) {
            pikn_[n][k] = qkn(k,n)/sum;
        }
    }
    testIntegrity();
}

void EM::testIntegrity() const {
    double sum = 0;
    for(int k=0; k<params_.size(); k++) {
        for(int n=0; n<data_.size(); n++) {
            sum += pikn_[n][k];
        }
        if(fabs(sum-1.0) < 1e-7)
            throw(std::runtime_error("pikn no longer sums to 1"));
    }
};

}
<|endoftext|>


<commit_before>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "android_webview/lib/main/aw_main_delegate.h"

#include "android_webview/browser/aw_content_browser_client.h"
#include "android_webview/browser/browser_view_renderer.h"
#include "android_webview/browser/scoped_allow_wait_for_legacy_web_view_api.h"
#include "android_webview/crash_reporter/aw_microdump_crash_reporter.h"
#include "android_webview/lib/aw_browser_dependency_factory_impl.h"
#include "android_webview/native/aw_media_url_interceptor.h"
#include "android_webview/native/aw_message_port_service_impl.h"
#include "android_webview/native/aw_quota_manager_bridge_impl.h"
#include "android_webview/native/aw_web_contents_view_delegate.h"
#include "android_webview/native/aw_web_preferences_populater_impl.h"
#include "android_webview/renderer/aw_content_renderer_client.h"
#include "base/android/apk_assets.h"
#include "base/command_line.h"
#include "base/cpu.h"
#include "base/i18n/icu_util.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/threading/thread_restrictions.h"
#include "cc/base/switches.h"
#include "components/external_video_surface/browser/android/external_video_surface_container_impl.h"
#include "content/public/browser/android/browser_media_player_manager_register.h"
#include "content/public/browser/browser_main_runner.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/content_descriptors.h"
#include "content/public/common/content_switches.h"
#include "gin/public/isolate_holder.h"
#include "gpu/command_buffer/client/gl_in_process_context.h"
#include "gpu/command_buffer/service/gpu_switches.h"
#include "media/base/media_switches.h"

namespace android_webview {

namespace {

// TODO(boliu): Remove this global Allow once the underlying issues are
// resolved - http://crbug.com/240453. See AwMainDelegate::RunProcess below.
base::LazyInstance<scoped_ptr<ScopedAllowWaitForLegacyWebViewApi> >
    g_allow_wait_in_ui_thread = LAZY_INSTANCE_INITIALIZER;

}

AwMainDelegate::AwMainDelegate() {
}

AwMainDelegate::~AwMainDelegate() {
}

bool AwMainDelegate::BasicStartupComplete(int* exit_code) {
  content::SetContentClient(&content_client_);

  content::RegisterMediaUrlInterceptor(new AwMediaUrlInterceptor());

  BrowserViewRenderer::CalculateTileMemoryPolicy();

  base::CommandLine* cl = base::CommandLine::ForCurrentProcess();
  cl->AppendSwitch(cc::switches::kEnableBeginFrameScheduling);

  // WebView uses the Android system's scrollbars and overscroll glow.
  cl->AppendSwitch(switches::kDisableOverscrollEdgeEffect);

  // Pull-to-refresh should never be a default WebView action.
  cl->AppendSwitch(switches::kDisablePullToRefreshEffect);

  // Not yet supported in single-process mode.
  cl->AppendSwitch(switches::kDisableSharedWorkers);

  // File system API not supported (requires some new API; internal bug 6930981)
  cl->AppendSwitch(switches::kDisableFileSystem);

  // Web Notification API and the Push API are not supported (crbug.com/434712)
  cl->AppendSwitch(switches::kDisableNotifications);

  // WebRTC hardware decoding is not supported, internal bug 15075307
  cl->AppendSwitch(switches::kDisableWebRtcHWDecoding);
  cl->AppendSwitch(switches::kDisableAcceleratedVideoDecode);

  // This is needed for sharing textures across the different GL threads.
  cl->AppendSwitch(switches::kEnableThreadedTextureMailboxes);

  // WebView does not yet support screen orientation locking.
  cl->AppendSwitch(switches::kDisableScreenOrientationLock);

  // WebView does not currently support Web Speech API (crbug.com/487255)
  cl->AppendSwitch(switches::kDisableSpeechAPI);

  // WebView does not currently support the Permissions API (crbug.com/490120)
  cl->AppendSwitch(switches::kDisablePermissionsAPI);

  // WebView does not (yet) save Chromium data during shutdown, so add setting
  // for Chrome to aggressively persist DOM Storage to minimize data loss.
  // http://crbug.com/479767
  cl->AppendSwitch(switches::kEnableAggressiveDOMStorageFlushing);

  // This is needed to be able to mmap the V8 snapshot and ICU data file
  // directly from the WebView .apk.
  // This needs to be here so that it gets to run before the code in
  // content_main_runner that reads these values tries to do so.
  // In multi-process mode this code would live in
  // AwContentBrowserClient::GetAdditionalMappedFilesForChildProcess.
#ifdef __LP64__
  const char kNativesFileName[] = "assets/natives_blob_64.bin";
  const char kSnapshotFileName[] = "assets/snapshot_blob_64.bin";
#else
  const char kNativesFileName[] = "assets/natives_blob_32.bin";
  const char kSnapshotFileName[] = "assets/snapshot_blob_32.bin";
#endif // __LP64__
  // TODO(gsennton) we should use
  // gin::IsolateHolder::kNativesFileName/kSnapshotFileName
  // here when those files have arch specific names http://crbug.com/455699
  CHECK(base::android::RegisterApkAssetWithGlobalDescriptors(
      kV8NativesDataDescriptor, kNativesFileName));
  CHECK(base::android::RegisterApkAssetWithGlobalDescriptors(
      kV8SnapshotDataDescriptor, kSnapshotFileName));
  CHECK(base::android::RegisterApkAssetWithGlobalDescriptors(
      kAndroidICUDataDescriptor, "assets/icudtl.dat"));

  return false;
}

void AwMainDelegate::PreSandboxStartup() {
  // TODO(torne): When we have a separate renderer process, we need to handle
  // being passed open FDs for the resource paks here.
#if defined(ARCH_CPU_ARM_FAMILY)
  // Create an instance of the CPU class to parse /proc/cpuinfo and cache
  // cpu_brand info.
  base::CPU cpu_info;
#endif

  crash_reporter::EnableMicrodumpCrashReporter();
}

void AwMainDelegate::SandboxInitialized(const std::string& process_type) {
  // TODO(torne): Adjust linux OOM score here.
}

int AwMainDelegate::RunProcess(
    const std::string& process_type,
    const content::MainFunctionParams& main_function_params) {
  if (process_type.empty()) {
    AwBrowserDependencyFactoryImpl::InstallInstance();

    browser_runner_.reset(content::BrowserMainRunner::Create());
    int exit_code = browser_runner_->Initialize(main_function_params);
    DCHECK_LT(exit_code, 0);

    g_allow_wait_in_ui_thread.Get().reset(
        new ScopedAllowWaitForLegacyWebViewApi);

    // Return 0 so that we do NOT trigger the default behavior. On Android, the
    // UI message loop is managed by the Java application.
    return 0;
  }

  return -1;
}

void AwMainDelegate::ProcessExiting(const std::string& process_type) {
  // TODO(torne): Clean up resources when we handle them.

  logging::CloseLogFile();
}

content::ContentBrowserClient*
    AwMainDelegate::CreateContentBrowserClient() {
  content_browser_client_.reset(new AwContentBrowserClient(this));
  return content_browser_client_.get();
}

content::ContentRendererClient*
    AwMainDelegate::CreateContentRendererClient() {
  content_renderer_client_.reset(new AwContentRendererClient());
  return content_renderer_client_.get();
}

scoped_refptr<AwQuotaManagerBridge> AwMainDelegate::CreateAwQuotaManagerBridge(
    AwBrowserContext* browser_context) {
  return AwQuotaManagerBridgeImpl::Create(browser_context);
}

content::WebContentsViewDelegate* AwMainDelegate::CreateViewDelegate(
    content::WebContents* web_contents) {
  return AwWebContentsViewDelegate::Create(web_contents);
}

AwWebPreferencesPopulater* AwMainDelegate::CreateWebPreferencesPopulater() {
  return new AwWebPreferencesPopulaterImpl();
}

AwMessagePortService* AwMainDelegate::CreateAwMessagePortService() {
  return new AwMessagePortServiceImpl();
}

#if defined(VIDEO_HOLE)
content::ExternalVideoSurfaceContainer*
AwMainDelegate::CreateExternalVideoSurfaceContainer(
    content::WebContents* web_contents) {
  return external_video_surface::ExternalVideoSurfaceContainerImpl::Create(
      web_contents);
}
#endif

}  // namespace android_webview
<commit_msg>aw: Use ipc command buffer by default<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "android_webview/lib/main/aw_main_delegate.h"

#include "android_webview/browser/aw_content_browser_client.h"
#include "android_webview/browser/browser_view_renderer.h"
#include "android_webview/browser/scoped_allow_wait_for_legacy_web_view_api.h"
#include "android_webview/common/aw_switches.h"
#include "android_webview/crash_reporter/aw_microdump_crash_reporter.h"
#include "android_webview/lib/aw_browser_dependency_factory_impl.h"
#include "android_webview/native/aw_media_url_interceptor.h"
#include "android_webview/native/aw_message_port_service_impl.h"
#include "android_webview/native/aw_quota_manager_bridge_impl.h"
#include "android_webview/native/aw_web_contents_view_delegate.h"
#include "android_webview/native/aw_web_preferences_populater_impl.h"
#include "android_webview/renderer/aw_content_renderer_client.h"
#include "base/android/apk_assets.h"
#include "base/command_line.h"
#include "base/cpu.h"
#include "base/i18n/icu_util.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/threading/thread_restrictions.h"
#include "cc/base/switches.h"
#include "components/external_video_surface/browser/android/external_video_surface_container_impl.h"
#include "content/public/browser/android/browser_media_player_manager_register.h"
#include "content/public/browser/browser_main_runner.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/content_descriptors.h"
#include "content/public/common/content_switches.h"
#include "gin/public/isolate_holder.h"
#include "gpu/command_buffer/client/gl_in_process_context.h"
#include "gpu/command_buffer/service/gpu_switches.h"
#include "media/base/media_switches.h"

namespace android_webview {

namespace {

// TODO(boliu): Remove this global Allow once the underlying issues are
// resolved - http://crbug.com/240453. See AwMainDelegate::RunProcess below.
base::LazyInstance<scoped_ptr<ScopedAllowWaitForLegacyWebViewApi> >
    g_allow_wait_in_ui_thread = LAZY_INSTANCE_INITIALIZER;

}

AwMainDelegate::AwMainDelegate() {
}

AwMainDelegate::~AwMainDelegate() {
}

bool AwMainDelegate::BasicStartupComplete(int* exit_code) {
  content::SetContentClient(&content_client_);

  content::RegisterMediaUrlInterceptor(new AwMediaUrlInterceptor());

  BrowserViewRenderer::CalculateTileMemoryPolicy();

  base::CommandLine* cl = base::CommandLine::ForCurrentProcess();
  cl->AppendSwitch(switches::kUseIpcCommandBuffer);
  cl->AppendSwitch(cc::switches::kEnableBeginFrameScheduling);

  // WebView uses the Android system's scrollbars and overscroll glow.
  cl->AppendSwitch(switches::kDisableOverscrollEdgeEffect);

  // Pull-to-refresh should never be a default WebView action.
  cl->AppendSwitch(switches::kDisablePullToRefreshEffect);

  // Not yet supported in single-process mode.
  cl->AppendSwitch(switches::kDisableSharedWorkers);

  // File system API not supported (requires some new API; internal bug 6930981)
  cl->AppendSwitch(switches::kDisableFileSystem);

  // Web Notification API and the Push API are not supported (crbug.com/434712)
  cl->AppendSwitch(switches::kDisableNotifications);

  // WebRTC hardware decoding is not supported, internal bug 15075307
  cl->AppendSwitch(switches::kDisableWebRtcHWDecoding);
  cl->AppendSwitch(switches::kDisableAcceleratedVideoDecode);

  // This is needed for sharing textures across the different GL threads.
  cl->AppendSwitch(switches::kEnableThreadedTextureMailboxes);

  // WebView does not yet support screen orientation locking.
  cl->AppendSwitch(switches::kDisableScreenOrientationLock);

  // WebView does not currently support Web Speech API (crbug.com/487255)
  cl->AppendSwitch(switches::kDisableSpeechAPI);

  // WebView does not currently support the Permissions API (crbug.com/490120)
  cl->AppendSwitch(switches::kDisablePermissionsAPI);

  // WebView does not (yet) save Chromium data during shutdown, so add setting
  // for Chrome to aggressively persist DOM Storage to minimize data loss.
  // http://crbug.com/479767
  cl->AppendSwitch(switches::kEnableAggressiveDOMStorageFlushing);

  // This is needed to be able to mmap the V8 snapshot and ICU data file
  // directly from the WebView .apk.
  // This needs to be here so that it gets to run before the code in
  // content_main_runner that reads these values tries to do so.
  // In multi-process mode this code would live in
  // AwContentBrowserClient::GetAdditionalMappedFilesForChildProcess.
#ifdef __LP64__
  const char kNativesFileName[] = "assets/natives_blob_64.bin";
  const char kSnapshotFileName[] = "assets/snapshot_blob_64.bin";
#else
  const char kNativesFileName[] = "assets/natives_blob_32.bin";
  const char kSnapshotFileName[] = "assets/snapshot_blob_32.bin";
#endif // __LP64__
  // TODO(gsennton) we should use
  // gin::IsolateHolder::kNativesFileName/kSnapshotFileName
  // here when those files have arch specific names http://crbug.com/455699
  CHECK(base::android::RegisterApkAssetWithGlobalDescriptors(
      kV8NativesDataDescriptor, kNativesFileName));
  CHECK(base::android::RegisterApkAssetWithGlobalDescriptors(
      kV8SnapshotDataDescriptor, kSnapshotFileName));
  CHECK(base::android::RegisterApkAssetWithGlobalDescriptors(
      kAndroidICUDataDescriptor, "assets/icudtl.dat"));

  return false;
}

void AwMainDelegate::PreSandboxStartup() {
  // TODO(torne): When we have a separate renderer process, we need to handle
  // being passed open FDs for the resource paks here.
#if defined(ARCH_CPU_ARM_FAMILY)
  // Create an instance of the CPU class to parse /proc/cpuinfo and cache
  // cpu_brand info.
  base::CPU cpu_info;
#endif

  crash_reporter::EnableMicrodumpCrashReporter();
}

void AwMainDelegate::SandboxInitialized(const std::string& process_type) {
  // TODO(torne): Adjust linux OOM score here.
}

int AwMainDelegate::RunProcess(
    const std::string& process_type,
    const content::MainFunctionParams& main_function_params) {
  if (process_type.empty()) {
    AwBrowserDependencyFactoryImpl::InstallInstance();

    browser_runner_.reset(content::BrowserMainRunner::Create());
    int exit_code = browser_runner_->Initialize(main_function_params);
    DCHECK_LT(exit_code, 0);

    g_allow_wait_in_ui_thread.Get().reset(
        new ScopedAllowWaitForLegacyWebViewApi);

    // Return 0 so that we do NOT trigger the default behavior. On Android, the
    // UI message loop is managed by the Java application.
    return 0;
  }

  return -1;
}

void AwMainDelegate::ProcessExiting(const std::string& process_type) {
  // TODO(torne): Clean up resources when we handle them.

  logging::CloseLogFile();
}

content::ContentBrowserClient*
    AwMainDelegate::CreateContentBrowserClient() {
  content_browser_client_.reset(new AwContentBrowserClient(this));
  return content_browser_client_.get();
}

content::ContentRendererClient*
    AwMainDelegate::CreateContentRendererClient() {
  content_renderer_client_.reset(new AwContentRendererClient());
  return content_renderer_client_.get();
}

scoped_refptr<AwQuotaManagerBridge> AwMainDelegate::CreateAwQuotaManagerBridge(
    AwBrowserContext* browser_context) {
  return AwQuotaManagerBridgeImpl::Create(browser_context);
}

content::WebContentsViewDelegate* AwMainDelegate::CreateViewDelegate(
    content::WebContents* web_contents) {
  return AwWebContentsViewDelegate::Create(web_contents);
}

AwWebPreferencesPopulater* AwMainDelegate::CreateWebPreferencesPopulater() {
  return new AwWebPreferencesPopulaterImpl();
}

AwMessagePortService* AwMainDelegate::CreateAwMessagePortService() {
  return new AwMessagePortServiceImpl();
}

#if defined(VIDEO_HOLE)
content::ExternalVideoSurfaceContainer*
AwMainDelegate::CreateExternalVideoSurfaceContainer(
    content::WebContents* web_contents) {
  return external_video_surface::ExternalVideoSurfaceContainerImpl::Create(
      web_contents);
}
#endif

}  // namespace android_webview
<|endoftext|>


<commit_before>/*  cbr
 *  UniformServerMap.cpp
 *
 *  Copyright (c) 2009, Ewen Cheslack-Postava
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are
 *  met:
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *  * Neither the name of cbr nor the names of its contributors may
 *    be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#include "Network.hpp"
#include "UniformServerMap.hpp"

namespace CBR {

template<typename T>
T clamp(T val, T minval, T maxval) {
    if (val < minval) return minval;
    if (val > maxval) return maxval;
    return val;
}

UniformServerMap::UniformServerMap(LocationService* loc_service, const BandwidthFunction&bw, const BoundingBox3f& region, const Vector3ui32& perside)
 : ServerMap(loc_service,bw),
   mRegion(region),
   mServersPerDim(perside)
{
}

UniformServerMap::~UniformServerMap() {
}
void UniformServerMap::serverRegionLookup(ServerID sid, Vector3d &retmin, Vector3d&retmax)const {
    Vector3i32 server_dim_indices(sid%mServersPerDim.x,
                                  (sid/mServersPerDim.x)%mServersPerDim.y,
                                  (sid/mServersPerDim.x/mServersPerDim.y)%mServersPerDim.z);
    double xsize=mRegion.extents().x/mServersPerDim.x;
    double ysize=mRegion.extents().y/mServersPerDim.y;
    double zsize=mRegion.extents().z/mServersPerDim.z;
    retmin=Vector3d(server_dim_indices.x*xsize+mRegion.min().x,
                    server_dim_indices.y*ysize+mRegion.min().y,
                    server_dim_indices.z*zsize+mRegion.min().z);
    retmax=Vector3d((1+server_dim_indices.x)*xsize+mRegion.min().x,
                    (1+server_dim_indices.y)*ysize+mRegion.min().y,
                    (1+server_dim_indices.z)*zsize+mRegion.min().z);
}
double UniformServerMap::serverBandwidthRate(ServerID source, ServerID destination) const{

    Vector3d sourcemin;
    Vector3d sourcemax;
    Vector3d destmin;
    Vector3d destmax;
    serverRegionLookup(source,sourcemin,sourcemax);
    serverRegionLookup(source,destmin,destmax);
    return mBandwidthCap(sourcemin,sourcemax,destmin,destmax);
}
ServerID UniformServerMap::lookup(const Vector3f& pos) {
    Vector3f region_extents = mRegion.extents();
    Vector3f to_point = pos - mRegion.min();

    Vector3i32 server_dim_indices( (int32)((to_point.x/region_extents.x)*mServersPerDim.x),
                                   (int32)((to_point.y/region_extents.y)*mServersPerDim.y),
                                   (int32)((to_point.z/region_extents.z)*mServersPerDim.z) );

    server_dim_indices.x = clamp(server_dim_indices.x, 0, (int32)mServersPerDim.x-1);
    server_dim_indices.y = clamp(server_dim_indices.y, 0, (int32)mServersPerDim.y-1);
    server_dim_indices.z = clamp(server_dim_indices.z, 0, (int32)mServersPerDim.z-1);

    uint32 server_index = (uint32) server_dim_indices.z*mServersPerDim.x*mServersPerDim.y + server_dim_indices.y*mServersPerDim.x + server_dim_indices.x + 1;
    return ServerID(server_index);
}

ServerID UniformServerMap::lookup(const UUID& obj_id) {
    Vector3f pos = mLocationService->currentPosition(obj_id);
    return lookup(pos);
}

} // namespace CBR
<commit_msg>renormalized serverBandwidthRate to be 1 for the space of other servers in the whole mRegion<commit_after>/*  cbr
 *  UniformServerMap.cpp
 *
 *  Copyright (c) 2009, Ewen Cheslack-Postava
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are
 *  met:
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *  * Neither the name of cbr nor the names of its contributors may
 *    be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#include "Network.hpp"
#include "UniformServerMap.hpp"

namespace CBR {

template<typename T>
T clamp(T val, T minval, T maxval) {
    if (val < minval) return minval;
    if (val > maxval) return maxval;
    return val;
}

UniformServerMap::UniformServerMap(LocationService* loc_service, const BandwidthFunction&bw, const BoundingBox3f& region, const Vector3ui32& perside)
 : ServerMap(loc_service,bw),
   mRegion(region),
   mServersPerDim(perside)
{
}

UniformServerMap::~UniformServerMap() {
}
void UniformServerMap::serverRegionLookup(ServerID sid, Vector3d &retmin, Vector3d&retmax)const {
    Vector3i32 server_dim_indices(sid%mServersPerDim.x,
                                  (sid/mServersPerDim.x)%mServersPerDim.y,
                                  (sid/mServersPerDim.x/mServersPerDim.y)%mServersPerDim.z);
    double xsize=mRegion.extents().x/mServersPerDim.x;
    double ysize=mRegion.extents().y/mServersPerDim.y;
    double zsize=mRegion.extents().z/mServersPerDim.z;
    retmin=Vector3d(server_dim_indices.x*xsize+mRegion.min().x,
                    server_dim_indices.y*ysize+mRegion.min().y,
                    server_dim_indices.z*zsize+mRegion.min().z);
    retmax=Vector3d((1+server_dim_indices.x)*xsize+mRegion.min().x,
                    (1+server_dim_indices.y)*ysize+mRegion.min().y,
                    (1+server_dim_indices.z)*zsize+mRegion.min().z);
}
double UniformServerMap::serverBandwidthRate(ServerID source, ServerID destination) const{

    Vector3d sourcemin;
    Vector3d sourcemax;
    Vector3d destmin;
    Vector3d destmax;
    serverRegionLookup(source,sourcemin,sourcemax);
    serverRegionLookup(source,destmin,destmax);
    float totalFunctionBandwidth=mBandwidthCap(sourcemin,sourcemax,Vector3d(mRegion.min()),Vector3d(mRegion.max()))-mBandwidthCap(sourcemin,sourcemax,sourcemin,sourcemax);
    return mBandwidthCap(sourcemin,sourcemax,destmin,destmax)/totalFunctionBandwidth;
}
ServerID UniformServerMap::lookup(const Vector3f& pos) {
    Vector3f region_extents = mRegion.extents();
    Vector3f to_point = pos - mRegion.min();

    Vector3i32 server_dim_indices( (int32)((to_point.x/region_extents.x)*mServersPerDim.x),
                                   (int32)((to_point.y/region_extents.y)*mServersPerDim.y),
                                   (int32)((to_point.z/region_extents.z)*mServersPerDim.z) );

    server_dim_indices.x = clamp(server_dim_indices.x, 0, (int32)mServersPerDim.x-1);
    server_dim_indices.y = clamp(server_dim_indices.y, 0, (int32)mServersPerDim.y-1);
    server_dim_indices.z = clamp(server_dim_indices.z, 0, (int32)mServersPerDim.z-1);

    uint32 server_index = (uint32) server_dim_indices.z*mServersPerDim.x*mServersPerDim.y + server_dim_indices.y*mServersPerDim.x + server_dim_indices.x + 1;
    return ServerID(server_index);
}

ServerID UniformServerMap::lookup(const UUID& obj_id) {
    Vector3f pos = mLocationService->currentPosition(obj_id);
    return lookup(pos);
}

} // namespace CBR
<|endoftext|>