int curl_fetch_read(CFContext * h, char * buf, int size)
{
    if (!h) {
        CLOGE("CFContext invalid\n");
        return C_ERROR_UNKNOW;
    }
    if (!h->cwh_h->cfifo) {
        CLOGE("CURLWHandle fifo invalid\n");
        return C_ERROR_UNKNOW;
    }
    int avail = 0;
    pthread_mutex_lock(&h->cwh_h->fifo_mutex);
    avail = curl_fifo_size(h->cwh_h->cfifo);
    if (avail) {
        size = CURLMIN(avail, size);
        curl_fifo_generic_read(h->cwh_h->cfifo, buf, size, NULL);
        pthread_cond_signal(&h->cwh_h->pthread_cond);
        pthread_mutex_unlock(&h->cwh_h->fifo_mutex);
        return size;
    } else if (h->thread_quited) {
        pthread_mutex_unlock(&h->cwh_h->fifo_mutex);
        return h->perform_retval;
    } else {
        pthread_mutex_unlock(&h->cwh_h->fifo_mutex);
        return C_ERROR_EAGAIN;
    }
    pthread_mutex_unlock(&h->cwh_h->fifo_mutex);
    return C_ERROR_OK;
}
Example #2
0
CFContext * curl_fetch_init(const char * uri, const char * headers, int flags)
{
    CLOGI("curl_fetch_init enter\n");
    if (!uri || strlen(uri) < 1 || strlen(uri) > MAX_CURL_URI_SIZE) {
        CLOGE("CFContext invalid uri path\n");
        return NULL;
    }
    CFContext * handle = (CFContext *)c_malloc(sizeof(CFContext));
    if (!handle) {
        CLOGE("CFContext invalid\n");
        return NULL;
    }
    handle->cwc_h = curl_wrapper_init(flags);
    if (!handle->cwc_h) {
        CLOGE("curl_wrapper_init failed\n");
        return NULL;
    }
#if 1
    if (c_stristart(uri, "http://", NULL) || c_stristart(uri, "shttp://", NULL)) {
        handle->prot_type = C_PROT_HTTP;
    } else if (c_stristart(uri, "https://", NULL) || c_stristart(uri, "shttps://", NULL)) {
        handle->prot_type = C_PROT_HTTPS;
    }
    memset(handle->uri, 0, sizeof(handle->uri));
    if (c_stristart(uri, "shttp://", NULL) || c_stristart(uri, "shttps://", NULL)) {
        c_strlcpy(handle->uri, uri + 1, sizeof(handle->uri));
    } else {
        c_strlcpy(handle->uri, uri, sizeof(handle->uri));
    }
    curl_fetch_url_process(handle);
    CLOGI("curl_fetch_init, uri:[%s]\n", handle->uri);
#endif
    handle->cwd = (Curl_Data *)c_malloc(sizeof(Curl_Data));
    if (!handle->cwd) {
        CLOGE("Failed to allocate memory for curl_data\n");
        return NULL;
    }
    handle->cwh_h = curl_wrapper_open(handle->cwc_h, handle->uri, headers, handle->cwd, handle->prot_type);
    if (!handle->cwh_h) {
        CLOGE("curl_wrapper_open failed\n");
        return NULL;
    }
    handle->chunk = NULL;
    handle->thread_quited = 0;
    handle->perform_retval = 0;
    handle->http_code = 0;
    handle->filesize = -1;
    handle->seekable = 0;
    handle->relocation = NULL;
    handle->headers = NULL;
    handle->interrupt = NULL;
    pthread_mutex_init(&handle->quit_mutex, NULL);
    pthread_cond_init(&handle->quit_cond, NULL);
    if (headers) {
        handle->headers = (char *)c_mallocz(strlen(headers) + 1);
        strcpy(handle->headers, headers);
    }
    return handle;
}
bool ExynosCameraPipeSCP::m_mainThreadFunc(void)
{
    int ret = 0;

#ifdef TEST_WATCHDOG_THREAD
    testErrorDetect++;
    if (testErrorDetect == 100)
        m_threadState = ERROR_POLLING_DETECTED;
#endif

    if  (m_flagTryStop == true)
        return true;

    if (m_numOfRunningFrame > 0) {
#ifndef SKIP_SCHECK_POLLING
        ret = m_checkPolling();
#endif

        if (ret < 0) {
            CLOGE("ERR(%s[%d]):m_checkPolling fail, ret(%d)", __FUNCTION__, __LINE__, ret);
            /* TODO: doing exception handling */
            // HACK: for panorama shot
            //return false;
        }

        ret = m_getBuffer();
        if (ret < 0) {
            CLOGE("ERR(%s):m_getBuffer fail", __FUNCTION__);
            /* TODO: doing exception handling */
            return true;
        }
    }

    m_timer.stop();
    m_timeInterval = m_timer.durationMsecs();
    m_timer.start();

    ret = m_putBuffer();
    if (ret < 0) {
        if (ret == TIMED_OUT)
            return true;
        CLOGE("ERR(%s):m_putBuffer fail", __FUNCTION__);
        /* TODO: doing exception handling */
        return true;
    }

    /* update renew count */
    if (ret >= 0)
        m_threadRenew = 0;

    return true;
}
/* defined for some abnormal uri, like ip port -> :80:80 */
static int curl_fetch_url_process(CFContext * h)
{
    if (!h) {
        CLOGE("CFContext invalid\n");
        return -1;
    }
    char t_uri[MAX_CURL_URI_SIZE] = {0};
    char ip[256] = {0};
    char * fptr = c_stristr(h->uri, "//");
    char * bptr = c_stristr(fptr + 2, "/");
    if(fptr && bptr) {
        int len1 = fptr - h->uri + 2;
        memcpy(t_uri, h->uri, len1);
        memcpy(ip, h->uri + len1, (bptr - h->uri - len1) > 256 ? 256 : (bptr - h->uri - len1));
        char * ip_ptr = c_stristr(ip, ":");
        if(ip_ptr) {
            int len2 = ip_ptr - ip;
            memcpy(t_uri + len1, ip, len2);
            len1 += len2;
            char * ip_rptr = c_strrstr(ip, ":");
            if(ip_ptr) {
                int len3 = strlen(ip) - (ip_rptr - ip);
                memcpy(t_uri + len1, ip_rptr, len3);
                len1 += len3;
            }
        } else {
            memcpy(t_uri + len1, ip, strlen(ip));
            len1 += strlen(ip);
        }
        int len4 = strlen(h->uri) - (bptr - h->uri);
        memcpy(t_uri + len1, bptr, len4);
        c_strlcpy(h->uri, t_uri, sizeof(h->uri));
    }
    return 0;
}
int curl_fetch_close(CFContext * h)
{
    CLOGI("curl_fetch_close enter\n");
    if (!h) {
        CLOGE("CFContext invalid\n");
        return -1;
    }
    curl_wrapper_set_to_quit(h->cwc_h, NULL);
    pthread_join(h->pid, NULL);
    curl_wrapper_clean_after_perform(h->cwc_h);
    pthread_mutex_destroy(&h->quit_mutex);
    pthread_cond_destroy(&h->quit_cond);
    curl_wrapper_close(h->cwc_h);
    if (h->cwd) {
        c_free(h->cwd);
        h->cwd = NULL;
    }
    if (h->headers) {
        c_free(h->headers);
        h->headers = NULL;
    }
    curl_slist_free_all(h->chunk);
    c_free(h);
    h = NULL;
    return 0;
}
status_t ExynosCameraPipeSCP::m_getBuffer(void)
{
    ExynosCameraFrame *curFrame = NULL;
    ExynosCameraBuffer curBuffer;
    int index = -1;
    int ret = 0;

    if (m_numOfRunningFrame <= 0 || m_flagStartPipe == false) {
        ALOGD("DEBUG(%s[%d]): skip getBuffer, flagStartPipe(%d), numOfRunningFrame = %d", __FUNCTION__, __LINE__, m_flagStartPipe, m_numOfRunningFrame);
        return NO_ERROR;
    }

    ret = m_mainNode->getBuffer(&curBuffer, &index);
    if (ret < 0) {
        CLOGE("ERR(%s[%d]):getBuffer fail", __FUNCTION__, __LINE__);
        /* TODO: doing exception handling */
        return ret;
    }

    if (index < 0) {
        CLOGE("ERR(%s[%d]):Invalid index(%d) fail", __FUNCTION__, __LINE__, index);
        return INVALID_OPERATION;
    }

    m_activityControl->activityAfterExecFunc(getPipeId(), (void *)&curBuffer);

    /* complete frame */
    ret = m_completeFrame(&curFrame, curBuffer);
    if (ret < 0) {
        CLOGE("ERR(%s):m_comleteFrame fail", __FUNCTION__);
        /* TODO: doing exception handling */
    }

    if (curFrame == NULL) {
        CLOGE("ERR(%s):curFrame is fail", __FUNCTION__);
    }

    ret = curFrame->setDstBufferState(getPipeId(), ENTITY_BUFFER_STATE_COMPLETE);
    if (ret < 0) {
        CLOGE("ERR(%s): setDstBuffer state fail", __FUNCTION__);
        return ret;
    }

    m_outputFrameQ->pushProcessQ(&curFrame);

    return NO_ERROR;
}
int curl_fetch_get_info(CFContext * h, curl_info cmd, uint32_t flag, void * info)
{
    if (!h) {
        CLOGE("CFContext invalid\n");
        return -1;
    }
    if(!curl_wrapper_get_info(h->cwh_h, cmd, flag, info)) {
        return 0;
    }
    return -1;
}
static int curl_fetch_start_local_run(CFContext * h)
{
    CLOGI("curl_fetch_start_local_run enter\n");
    int ret = -1;
    if (!h) {
        CLOGE("CFContext invalid\n");
        return ret;
    }
    ret = pthread_create(&h->pid, NULL, curl_fetch_thread_run, h);
    return ret;
}
int curl_fetch_http_set_cookie(CFContext * h, const char * cookie)
{
    CLOGI("curl_fetch_http_set_cookie enter\n");
    if (!h) {
        CLOGE("CFContext invalid\n");
        return -1;
    }
    int ret = 0;
    if (h->prot_type == C_PROT_HTTP) {
        ret = curl_wrapper_set_para(h->cwh_h, NULL, C_COOKIES, 0, cookie);
    }
    return ret;
}
status_t ExynosCameraPipeSCP::m_checkPolling(void)
{
    int ret = 0;

    ret = m_mainNode->polling();
    if (ret < 0) {
        CLOGE("ERR(%s[%d]):polling fail, ret(%d)", __FUNCTION__, __LINE__, ret);
        /* TODO: doing exception handling */

        m_threadState = ERROR_POLLING_DETECTED;
        return ERROR_POLLING_DETECTED;
    }

    return NO_ERROR;
}
status_t ExynosCameraPipeSCP::setupPipe(camera_pipe_info_t *pipeInfos)
{
    CLOGD("DEBUG(%s[%d])", __FUNCTION__, __LINE__);
    status_t ret = NO_ERROR;

    /* TODO: check node state stream on? */

    /* initialize node */
    int maxW = pipeInfos[0].rectInfo.fullW;
    int maxH = pipeInfos[0].rectInfo.fullH;
    int colorFormat = pipeInfos[0].rectInfo.colorFormat;
    enum v4l2_buf_type bufType = (enum v4l2_buf_type)pipeInfos[0].bufInfo.type;
    enum v4l2_memory memType = (enum v4l2_memory)pipeInfos[0].bufInfo.memory;
    m_numBuffers = pipeInfos[0].bufInfo.count;

    m_mainNode->setSize(maxW, maxH);
    m_mainNode->setColorFormat(colorFormat, 4);
    m_mainNode->setBufferType(m_numBuffers, bufType, memType);

    m_mainNode->setFormat();
    m_mainNode->reqBuffers();

    /* setfile setting */
#ifdef SET_SETFILE_BY_SHOT
    /* nop */
#else
#if SET_SETFILE_BY_SET_CTRL_SCP
    int setfile = 0;
    int yuvRange = 0;
    m_parameters->getSetfileYuvRange(m_reprocessing, &setfile, &yuvRange);
    ret = m_mainNode->setControl(V4L2_CID_IS_COLOR_RANGE, yuvRange);
    if (ret != NO_ERROR) {
        CLOGE("ERR(%s[%d]):setControl(%d) fail(ret = %d)", __FUNCTION__, __LINE__, setfile, ret);
        return ret;
    }
#endif
#endif

    for (uint32_t i = 0; i < m_numBuffers; i++) {
        m_runningFrameList[i] = NULL;
    }
    m_numOfRunningFrame = 0;

    m_prepareBufferCount = m_exynosconfig->current->pipeInfo.prepare[getPipeId()];
    ALOGI("INFO(%s[%d]):setupPipe() is succeed (%d) setupPipe (%d)", __FUNCTION__, __LINE__, getPipeId(), m_prepareBufferCount);

    return NO_ERROR;
}
/*
*   headers must composed of fields split with "\r\n".
*   This is just temporary, need to modify later
*/
int curl_fetch_http_set_headers(CFContext * h, const char * headers)
{
    CLOGI("curl_fetch_http_set_headers enter\n");
    if (!h) {
        CLOGE("CFContext invalid\n");
        return -1;
    }
    char fields[2048];
    char * end_ptr = headers;
    char * beg_ptr = headers;
    while (*beg_ptr != '\0') {
        if (!(end_ptr = strstr(beg_ptr, "\r\n"))) {
            break;
        }
        if (beg_ptr == end_ptr) {
            beg_ptr += 2;
            continue;
        }
        memset(fields, 0x00, sizeof(fields));
        int tmp = CURLMIN(end_ptr - beg_ptr + 1, sizeof(fields) - 1);
        c_strlcpy(fields, beg_ptr, tmp);
        fields[tmp] = '\0';
        /*
        char * tmp_ptr = c_strrstr(fields, "\r\n"); // must remove CRLF
        if(tmp_ptr) {
            *tmp_ptr = '\0';
        }
        beg_ptr = end_ptr + 5;
        */
        beg_ptr = end_ptr + 2;
#if 0
        if (c_stristart(fields, "Connection:", NULL) || c_stristart(fields, "X-Playback-Session-Id:", NULL)) {
            h->chunk = curl_slist_append(h->chunk, fields);
            CLOGI("curl_fetch_http_set_headers fields=[%s]", fields);
        }
#else
        h->chunk = curl_slist_append(h->chunk, fields);
        CLOGI("curl_fetch_http_set_headers fields=[%s]", fields);
#endif
    }
    int ret = 0;
    if (h->prot_type == C_PROT_HTTP) {
        ret = curl_wrapper_set_para(h->cwh_h, (void *)h->chunk, C_HTTPHEADER, 0, NULL);
    }
    return ret;
}
status_t ExynosCameraPipeSCP::destroy(void)
{
    CLOGD("DEBUG(%s[%d])", __FUNCTION__, __LINE__);
    if (m_mainNode != NULL) {
        if (m_mainNode->close() != NO_ERROR) {
            CLOGE("ERR(%s):close fail", __FUNCTION__);
            return INVALID_OPERATION;
        }
        delete m_mainNode;
        m_mainNode = NULL;
        ALOGD("DEBUG(%s):Node(%d) closed", __FUNCTION__, FIMC_IS_VIDEO_SCP_NUM);
    }

    if (m_inputFrameQ != NULL) {
        m_inputFrameQ->release();
        delete m_inputFrameQ;
        m_inputFrameQ = NULL;
    }

    ALOGI("INFO(%s[%d]):destroy() is succeed (%d)", __FUNCTION__, __LINE__, getPipeId());

    return NO_ERROR;
}
int64_t curl_fetch_seek(CFContext * h, int64_t off, int whence)
{
    CLOGI("curl_fetch_seek enter\n");
    if (!h) {
        CLOGE("CFContext invalid\n");
        return -1;
    }
    CLOGI("curl_fetch_seek: chunk_size=%lld, off=%lld, whence=%d\n", h->cwh_h->chunk_size, off, whence);
    if (SEEK_CUR != whence &&
        SEEK_SET != whence &&
        SEEK_END != whence) {
        CLOGE("curl_fetch_seek whence not support\n");
        return -1;
    }
    if (h->cwh_h->chunk_size == -1 && whence == SEEK_END) {
        return -1;
    }
    if (whence == SEEK_CUR && off == 0) {
        return h->cwd->size;        //just a approximate value, not exactly
    }
    if (whence == SEEK_CUR) {
        off += h->cwd->size;
    } else if (whence == SEEK_END) {
        off += h->cwh_h->chunk_size;
    }
    if (off >= h->cwh_h->chunk_size && h->cwh_h->chunk_size > 0) {
        CLOGE("curl_fetch_seek exceed chunk_size\n");
        return -2;
    }
    int ret = -1;
    //h->is_seeking = 1;
    curl_wrapper_set_to_quit(h->cwc_h, NULL);
    if (curl_fetch_waitthreadquit(h, 5000 * 1000)) {
        return -1;
    }
    curl_wrapper_clean_after_perform(h->cwc_h);
    h->thread_quited = 0;
    h->perform_retval = 0;
    if (h->cwh_h->cfifo) {
        curl_fifo_reset(h->cwh_h->cfifo);
    }
    ret = curl_wrapper_seek(h->cwc_h, h->cwh_h, off, h->cwd, h->prot_type);
    if (ret) {
        CLOGE("curl_wrapper_seek failed\n");
        return -1;
    }
    if (h->headers) {
        curl_fetch_http_set_headers(h, h->headers);
    }
#if 1
    if (h->prot_type == C_PROT_HTTP) {
        curl_wrapper_set_para(h->cwh_h, NULL, C_MAX_REDIRECTS, 10, NULL);
        curl_wrapper_set_para(h->cwh_h, NULL, C_USER_AGENT, 0, IPAD_IDENT);
        curl_wrapper_set_para(h->cwh_h, (void *)h->cwd, C_HEADERS, 0, NULL);
    }
#endif
    ret = curl_fetch_start_local_run(h);
    if (ret) {
        CLOGE("curl_fetch_start_local_run failed\n");
        return -1;
    }
    return off;
}
int curl_fetch_http_keepalive_open(CFContext * h, const char * uri)
{
    CLOGI("curl_fetch_http_keepalive_open enter\n");
    int ret = -1;
    if (!h) {
        CLOGE("CFContext invalid\n");
        return ret;
    }
    curl_wrapper_set_to_quit(h->cwc_h, NULL);
    if (curl_fetch_waitthreadquit(h, 5000 * 1000)) {
        return ret;
    }
    curl_wrapper_clean_after_perform(h->cwc_h);
    if (h->cwh_h->cfifo) {
        curl_fifo_reset(h->cwh_h->cfifo);
    }
    if (uri) {
        if (c_stristart(uri, "http://", NULL) || c_stristart(uri, "shttp://", NULL)) {
            h->prot_type = C_PROT_HTTP;
        }
        if (h->prot_type != C_PROT_HTTP) {
            return ret;
        }
        memset(h->uri, 0, sizeof(h->uri));
        if (c_stristart(uri, "shttp://", NULL)) {
            c_strlcpy(h->uri, uri + 1, sizeof(h->uri));
        } else {
            c_strlcpy(h->uri, uri, sizeof(h->uri));
        }
        curl_fetch_url_process(h);
        CLOGI("curl_fetch_http_keepalive_open, uri:[%s]\n", h->uri);
        ret = curl_wrapper_http_keepalive_open(h->cwc_h, h->cwh_h, h->uri);
    } else {
        ret = curl_wrapper_http_keepalive_open(h->cwc_h, h->cwh_h, uri);
    }
    if (-1 == ret) {
        CLOGE("curl_wrapper_http_keepalive_open failed\n");
        return ret;
    }
    h->thread_quited = 0;
    h->perform_retval = 0;
    h->http_code = 0;
    h->filesize = -1;
    h->seekable = 0;
    //h->is_seeking = 0;
    h->cwd->size = 0;

    curl_fetch_start_local_run(h);

#if 0
    struct timeval now;
    struct timespec timeout;
    int retcode = 0;
    gettimeofday(&now, NULL);
    timeout.tv_sec = now.tv_sec + (15000000 + now.tv_usec) / 1000000;
    timeout.tv_nsec = now.tv_usec * 1000;
    if(h->open_quited) {
        return -1;
    }
    pthread_mutex_lock(&h->cwh_h->info_mutex);
    retcode = pthread_cond_timedwait(&h->cwh_h->info_cond, &h->cwh_h->info_mutex, &timeout);
    if (retcode != ETIMEDOUT) {
        if (h->cwh_h->chunk_size > 0) {
            h->filesize = h->cwh_h->chunk_size;
        }
        if (h->cwh_h->relocation) {
            h->relocation = h->cwh_h->relocation;
        }
        h->http_code = h->cwh_h->http_code;
    }
    pthread_mutex_unlock(&h->cwh_h->info_mutex);
#endif

    int timeout = 0;
    while(!h->cwh_h->open_quited && timeout < CONNECT_TIMEOUT_THRESHOLD) {
        if(h->interrupt) {
            if((*(h->interrupt))()) {
                CLOGE("***** CURL INTERRUPTED *****");
                return -1;  // consider for seek interrupt
            }
        }
        usleep(SLEEP_TIME_UNIT);
        timeout += SLEEP_TIME_UNIT;
    }
    if(h->cwh_h->perform_error_code < C_ERROR_EAGAIN) {
        return -1;
    }
    if(h->cwh_h->open_quited) {
        if (h->cwh_h->chunk_size > 0) {
            h->filesize = h->cwh_h->chunk_size;
        }
        if (h->cwh_h->relocation) {
            h->relocation = h->cwh_h->relocation;
        }
        h->http_code = h->cwh_h->http_code;
    } else {
        h->http_code = ETIMEDOUT;
        return -1;
    }

    if (h->http_code >= 400 && h->http_code < 600 && h->http_code != 401) {
        return -1;
    }

    if (h->filesize > 0 || h->cwh_h->seekable) {
        h->seekable = 1;
    }

    return 0;
}
status_t ExynosCameraPipeJpeg::m_run(void)
{
    ExynosCameraAutoTimer autoTimer(__FUNCTION__);
    status_t ret = 0;
    ExynosCameraFrame *newFrame = NULL;

    ExynosCameraBuffer yuvBuf;
    ExynosCameraBuffer jpegBuf;

    ExynosRect pictureRect;
    int jpegQuality = m_parameters->getJpegQuality();

    ExynosRect thumbnailRect;
    int thumbnailQuality = m_parameters->getThumbnailQuality();

    exif_attribute_t exifInfo;
    m_parameters->getFixedExifInfo(&exifInfo);
    struct camera2_shot_ext shot_ext;
    memset(&shot_ext, 0x00, sizeof(struct camera2_shot_ext));

    pictureRect.colorFormat = m_parameters->getPictureFormat();
    m_parameters->getPictureSize(&pictureRect.w, &pictureRect.h);
    m_parameters->getThumbnailSize(&thumbnailRect.w, &thumbnailRect.h);

    ALOGI("DEBUG(%s[%d]): -IN-", __FUNCTION__, __LINE__);
    ALOGD("DEBUG(%s[%d]):picture size(%dx%d), thumbnail size(%dx%d)",
            __FUNCTION__, __LINE__, pictureRect.w, pictureRect.h, thumbnailRect.w, thumbnailRect.h);

    ret = m_inputFrameQ->waitAndPopProcessQ(&newFrame);
    if (ret < 0) {
        /* TODO: We need to make timeout duration depends on FPS */
        if (ret == TIMED_OUT) {
            ALOGW("WARN(%s):wait timeout", __FUNCTION__);
        } else {
            ALOGE("ERR(%s):wait and pop fail, ret(%d)", __FUNCTION__, ret);
            /* TODO: doing exception handling */
        }
        return ret;
    }

    if (newFrame == NULL) {
        ALOGE("ERR(%s):new frame is NULL", __FUNCTION__);
        return NO_ERROR;
    }

    ret = newFrame->getSrcBuffer(getPipeId(), &yuvBuf);
    if (ret < 0) {
        CLOGE("ERR(%s[%d]):frame get src buffer fail, ret(%d)", __FUNCTION__, __LINE__, ret);
        /* TODO: doing exception handling */
        return OK;
    }

    ret = newFrame->getDstBuffer(getPipeId(), &jpegBuf);
    if (ret < 0) {
        CLOGE("ERR(%s[%d]):frame get dst buffer fail, ret(%d)", __FUNCTION__, __LINE__, ret);
        /* TODO: doing exception handling */
        return OK;
    }

    if (m_jpegEnc.create()) {
        ALOGE("ERR(%s):m_jpegEnc.create() fail", __FUNCTION__);
        ret = INVALID_OPERATION;
        goto jpeg_encode_done;
    }

    if (m_jpegEnc.setQuality(jpegQuality)) {
        ALOGE("ERR(%s):m_jpegEnc.setQuality() fail", __FUNCTION__);
        ret = INVALID_OPERATION;
        goto jpeg_encode_done;
    }

    if (m_jpegEnc.setSize(pictureRect.w, pictureRect.h)) {
        ALOGE("ERR(%s):m_jpegEnc.setSize() fail", __FUNCTION__);
        ret = INVALID_OPERATION;
        goto jpeg_encode_done;
    }

    if (m_jpegEnc.setColorFormat(pictureRect.colorFormat)) {
        ALOGE("ERR(%s):m_jpegEnc.setColorFormat() fail", __FUNCTION__);
        ret = INVALID_OPERATION;
        goto jpeg_encode_done;
    }

    if (m_jpegEnc.setJpegFormat(V4L2_PIX_FMT_JPEG_422)) {
        ALOGE("ERR(%s):m_jpegEnc.setJpegFormat() fail", __FUNCTION__);
        ret = INVALID_OPERATION;
        goto jpeg_encode_done;
    }

    if (thumbnailRect.w != 0 && thumbnailRect.h != 0) {
        exifInfo.enableThumb = true;
        if (pictureRect.w < 320 || pictureRect.h < 240) {
            thumbnailRect.w = 160;
            thumbnailRect.h = 120;
        }
        if (m_jpegEnc.setThumbnailSize(thumbnailRect.w, thumbnailRect.h)) {
            ALOGE("ERR(%s):m_jpegEnc.setThumbnailSize(%d, %d) fail", __FUNCTION__, thumbnailRect.w, thumbnailRect.h);
            ret = INVALID_OPERATION;
            goto jpeg_encode_done;
        }
        if (0 < thumbnailQuality && thumbnailQuality <= 100) {
            if (m_jpegEnc.setThumbnailQuality(thumbnailQuality)) {
                ret = INVALID_OPERATION;
                ALOGE("ERR(%s):m_jpegEnc.setThumbnailQuality(%d) fail", __FUNCTION__, thumbnailQuality);
            }
        }
    } else {
        exifInfo.enableThumb = false;
    }

    /* wait for medata update */
    if(newFrame->getMetaDataEnable() == false) {
        CLOGD("DEBUG(%s[%d]): Waiting for update jpeg metadata failed (%d) ", __FUNCTION__, __LINE__, ret);
    }

    /* get dynamic meters for make exif info */
    newFrame->getDynamicMeta(&shot_ext);
    newFrame->getUserDynamicMeta(&shot_ext);

    m_parameters->setExifChangedAttribute(&exifInfo, &pictureRect, &thumbnailRect,&shot_ext.shot.dm, &shot_ext.shot.udm);

    if (m_jpegEnc.setInBuf((int *)&(yuvBuf.fd), (int *)yuvBuf.size)) {
        ALOGE("ERR(%s):m_jpegEnc.setInBuf() fail", __FUNCTION__);
        ret = INVALID_OPERATION;
        goto jpeg_encode_done;
    }

    if (m_jpegEnc.setOutBuf(jpegBuf.fd[0], jpegBuf.size[0] + jpegBuf.size[1] + jpegBuf.size[2])) {
        ALOGE("ERR(%s):m_jpegEnc.setOutBuf() fail", __FUNCTION__);
        ret = INVALID_OPERATION;
        goto jpeg_encode_done;
    }

    if (m_jpegEnc.updateConfig()) {
        ALOGE("ERR(%s):m_jpegEnc.updateConfig() fail", __FUNCTION__);
        ret = INVALID_OPERATION;
        goto jpeg_encode_done;
    }

    if (m_jpegEnc.encode((int *)&jpegBuf.size, &exifInfo, m_parameters->getDebugAttribute())) {
        ALOGE("ERR(%s):m_jpegEnc.encode() fail", __FUNCTION__);
        ret = INVALID_OPERATION;
        goto jpeg_encode_done;
    }

    newFrame->setJpegSize(jpegBuf.size[0]);

    ret = newFrame->setEntityState(getPipeId(), ENTITY_STATE_FRAME_DONE);
    if (ret < 0) {
        CLOGE("ERR(%s[%d]):set entity state fail, ret(%d)", __FUNCTION__, __LINE__, ret);
        /* TODO: doing exception handling */
        return OK;
    }

    m_outputFrameQ->pushProcessQ(&newFrame);

jpeg_encode_done:
    if (ret != NO_ERROR) {
        ALOGD("[jpegBuf.fd[0] %d][jpegBuf.size[0] + jpegBuf.size[1] + jpegBuf.size[2] %d]",
            jpegBuf.fd[0], jpegBuf.size[0] + jpegBuf.size[1] + jpegBuf.size[2]);
        ALOGD("[pictureW %d][pictureH %d][pictureFormat %d]",
            pictureRect.w, pictureRect.h, pictureRect.colorFormat);
    }

    if (m_jpegEnc.flagCreate() == true)
        m_jpegEnc.destroy();

    ALOGI("DEBUG(%s[%d]): -OUT-", __FUNCTION__, __LINE__);

    return ret;
}
int curl_fetch_open(CFContext * h)
{
    CLOGI("curl_fetch_open enter\n");
    if (!h) {
        CLOGE("CFContext invalid\n");
        return -1;
    }
#if 1
    if (h->prot_type == C_PROT_HTTP) {
        curl_wrapper_set_para(h->cwh_h, NULL, C_MAX_REDIRECTS, 10, NULL);
        curl_wrapper_set_para(h->cwh_h, NULL, C_USER_AGENT, 0, IPAD_IDENT);
        curl_wrapper_set_para(h->cwh_h, (void *)h->cwd, C_HEADERS, 0, NULL);
    }
#endif
    if (h->headers) {
        curl_fetch_http_set_headers(h, h->headers);
    }

#if 0
    int64_t tmp_size;
    if(!curl_wrapper_get_info_easy(h->cwh_h, C_INFO_CONTENT_LENGTH_DOWNLOAD, 0, &tmp_size, NULL)) {
        h->cwh_h->chunk_size = tmp_size;
    } else {
        h->cwh_h->chunk_size = -1;
    }
    h->filesize = h->cwh_h->chunk_size;
#endif

    //h->thread_first_run = 1;
    curl_fetch_start_local_run(h);

#if 0
    struct timeval now;
    struct timespec timeout;
    int retcode = 0;
    gettimeofday(&now, NULL);
    timeout.tv_sec = now.tv_sec + (15000000 + now.tv_usec) / 1000000;
    timeout.tv_nsec = now.tv_usec * 1000;
    if(h->open_quited) {
        return -1;
    }
    pthread_mutex_lock(&h->cwh_h->info_mutex);
    retcode = pthread_cond_timedwait(&h->cwh_h->info_cond, &h->cwh_h->info_mutex, &timeout);
    if (retcode != ETIMEDOUT) {
        if (h->cwh_h->chunk_size > 0) {
            h->filesize = h->cwh_h->chunk_size;
        }
        if (h->cwh_h->relocation) {
            h->relocation = h->cwh_h->relocation;
        }
        h->http_code = h->cwh_h->http_code;
    }
    pthread_mutex_unlock(&h->cwh_h->info_mutex);
#endif

    int timeout = 0;
    while(!h->cwh_h->open_quited && timeout < CONNECT_TIMEOUT_THRESHOLD) {
        if(h->interrupt) {
            if((*(h->interrupt))()) {
                CLOGE("***** CURL INTERRUPTED *****");
                return -1;  // consider for seek interrupt
            }
        }
        usleep(SLEEP_TIME_UNIT);
        timeout += SLEEP_TIME_UNIT;
    }
    if(h->cwh_h->perform_error_code < C_ERROR_EAGAIN) {
        return -1;
    }
    if(h->cwh_h->open_quited) {
        if (h->cwh_h->chunk_size > 0) {
            h->filesize = h->cwh_h->chunk_size;
        }
        if (h->cwh_h->relocation) {
            h->relocation = h->cwh_h->relocation;
        }
        h->http_code = h->cwh_h->http_code;
    } else {
        h->http_code = ETIMEDOUT;
        return -1;
    }

    if (h->http_code >= 400 && h->http_code < 600 && h->http_code != 401) {
        return -1;
    }

    if (h->filesize > 0 || h->cwh_h->seekable) {
        h->seekable = 1;
    }

    return 0;
}
status_t ExynosCameraPipeSCP::m_putBuffer(void)
{
    ExynosCameraFrame *newFrame = NULL;
    ExynosCameraBuffer newBuffer;
    int ret = 0;

retry:
    ret = m_inputFrameQ->waitAndPopProcessQ(&newFrame);
    if (ret < 0) {
        /* TODO: We need to make timeout duration depends on FPS */
        if (ret == TIMED_OUT) {
            CLOGW("WARN(%s):wait timeout", __FUNCTION__);
            m_mainNode->dumpState();
        } else {
            CLOGE("ERR(%s):wait and pop fail, ret(%d)", __FUNCTION__, ret);
            /* TODO: doing exception handling */
        }
        return ret;
    }

    if (newFrame == NULL) {
        CLOGE("ERR(%s):newFrame is NULL", __FUNCTION__);
        return INVALID_OPERATION;
    }

    ret = newFrame->getDstBuffer(getPipeId(), &newBuffer);
    if (ret < 0) {
        CLOGE("ERR(%s[%d]):frame get buffer fail, ret(%d)", __FUNCTION__, __LINE__, ret);
        /* TODO: doing exception handling */
        return OK;
    }

    /* check buffer index */
    if (newBuffer.index < 0) {
        CLOGD("DEBUG(%s[%d]): no buffer to QBUF (%d)", __FUNCTION__, __LINE__, newFrame->getFrameCount());

        ret = newFrame->setDstBufferState(getPipeId(), ENTITY_BUFFER_STATE_REQUESTED);
        if (ret < 0) {
            CLOGE("ERR(%s): setDstBuffer state fail", __FUNCTION__);
            return ret;
        }

        ret = newFrame->setEntityState(getPipeId(), ENTITY_STATE_FRAME_DONE);
        if (ret < 0) {
            CLOGE("ERR(%s[%d]):set entity state fail, ret(%d)", __FUNCTION__, __LINE__, ret);
            /* TODO: doing exception handling */
            return OK;
        }

        CLOGV("DEBUG(%s):entity pipeId(%d), frameCount(%d), numOfRunningFrame(%d), requestCount(%d)",
                __FUNCTION__, getPipeId(), newFrame->getFrameCount(), m_numOfRunningFrame, m_requestCount);

        usleep(33000);
        m_outputFrameQ->pushProcessQ(&newFrame);

        goto retry;
    } else {
        if (m_runningFrameList[newBuffer.index] != NULL) {
            CLOGE("ERR(%s):new buffer is invalid, we already get buffer index(%d), newFrame->frameCount(%d)",
                __FUNCTION__, newBuffer.index, newFrame->getFrameCount());
            m_dumpRunningFrameList();

            return BAD_VALUE;
        }

        camera2_shot_ext *shot_ext = (struct camera2_shot_ext *)(newBuffer.addr[1]);

        if (shot_ext != NULL) {
            newFrame->getMetaData(shot_ext);
            m_parameters->duplicateCtrlMetadata((void *)shot_ext);
            m_activityControl->activityBeforeExecFunc(getPipeId(), (void *)&newBuffer);

            if (m_perframeMainNodeGroupInfo.perFrameLeaderInfo.perFrameNodeType == PERFRAME_NODE_TYPE_LEADER) {
                camera2_node_group node_group_info;
                memset(&shot_ext->node_group, 0x0, sizeof(camera2_node_group));
                newFrame->getNodeGroupInfo(&node_group_info, m_perframeMainNodeGroupInfo.perFrameLeaderInfo.perframeInfoIndex);

                /* Per - Leader */
                if (node_group_info.leader.request == 1) {
                    setMetaNodeLeaderInputSize(shot_ext,
                        node_group_info.leader.input.cropRegion[0],
                        node_group_info.leader.input.cropRegion[1],
                        node_group_info.leader.input.cropRegion[2],
                        node_group_info.leader.input.cropRegion[3]);
                    setMetaNodeLeaderOutputSize(shot_ext,
                        node_group_info.leader.output.cropRegion[0],
                        node_group_info.leader.output.cropRegion[1],
                        node_group_info.leader.output.cropRegion[2],
                        node_group_info.leader.output.cropRegion[3]);
                    setMetaNodeLeaderRequest(shot_ext,
                        node_group_info.leader.request);
                    setMetaNodeLeaderVideoID(shot_ext,
                        m_perframeMainNodeGroupInfo.perFrameLeaderInfo.perFrameVideoID);
                }

                /* Per - Captures */
                for (int i = 0; i < m_perframeMainNodeGroupInfo.perframeSupportNodeNum - 1; i ++) {
                    if (node_group_info.capture[i].request == 1) {
                        setMetaNodeCaptureInputSize(shot_ext, i,
                            node_group_info.capture[i].input.cropRegion[0],
                            node_group_info.capture[i].input.cropRegion[1],
                            node_group_info.capture[i].input.cropRegion[2],
                            node_group_info.capture[i].input.cropRegion[3]);
                        setMetaNodeCaptureOutputSize(shot_ext, i,
                            node_group_info.capture[i].output.cropRegion[0],
                            node_group_info.capture[i].output.cropRegion[1],
                            node_group_info.capture[i].output.cropRegion[2],
                            node_group_info.capture[i].output.cropRegion[3]);
                        setMetaNodeCaptureRequest(shot_ext,  i, node_group_info.capture[i].request);
                        setMetaNodeCaptureVideoID(shot_ext, i, m_perframeMainNodeGroupInfo.perFrameCaptureInfo[i].perFrameVideoID);
                    }
                }
            }
        }

        ret = m_mainNode->putBuffer(&newBuffer);
        if (ret < 0) {
            CLOGE("ERR(%s):putBuffer fail", __FUNCTION__);
            return ret;
            /* TODO: doing exception handling */
        }

        ret = newFrame->setDstBufferState(getPipeId(), ENTITY_BUFFER_STATE_PROCESSING);
        if (ret < 0) {
            CLOGE("ERR(%s): setDstBuffer state fail", __FUNCTION__);
            return ret;
        }

        m_runningFrameList[newBuffer.index] = newFrame;
        m_numOfRunningFrame++;
    }

    return NO_ERROR;
}