18a94683196406b83b14218d1beef66067f126a16keunyoung/*
28a94683196406b83b14218d1beef66067f126a16keunyoung * Copyright (C) 2012 The Android Open Source Project
38a94683196406b83b14218d1beef66067f126a16keunyoung *
48a94683196406b83b14218d1beef66067f126a16keunyoung * Licensed under the Apache License, Version 2.0 (the "License");
58a94683196406b83b14218d1beef66067f126a16keunyoung * you may not use this file except in compliance with the License.
68a94683196406b83b14218d1beef66067f126a16keunyoung * You may obtain a copy of the License at
78a94683196406b83b14218d1beef66067f126a16keunyoung *
88a94683196406b83b14218d1beef66067f126a16keunyoung *      http://www.apache.org/licenses/LICENSE-2.0
98a94683196406b83b14218d1beef66067f126a16keunyoung *
108a94683196406b83b14218d1beef66067f126a16keunyoung * Unless required by applicable law or agreed to in writing, software
118a94683196406b83b14218d1beef66067f126a16keunyoung * distributed under the License is distributed on an "AS IS" BASIS,
128a94683196406b83b14218d1beef66067f126a16keunyoung * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138a94683196406b83b14218d1beef66067f126a16keunyoung * See the License for the specific language governing permissions and
148a94683196406b83b14218d1beef66067f126a16keunyoung * limitations under the License.
158a94683196406b83b14218d1beef66067f126a16keunyoung */
168a94683196406b83b14218d1beef66067f126a16keunyoung
1757ac67ad91c44ffd875b186f124234c2ab1958f3Eino-Ville Talvala//#define LOG_NDEBUG 0
188a94683196406b83b14218d1beef66067f126a16keunyoung#define LOG_TAG "EmulatedCamera2_JpegCompressor"
198a94683196406b83b14218d1beef66067f126a16keunyoung
208a94683196406b83b14218d1beef66067f126a16keunyoung#include <utils/Log.h>
218a94683196406b83b14218d1beef66067f126a16keunyoung#include <ui/GraphicBufferMapper.h>
228a94683196406b83b14218d1beef66067f126a16keunyoung
238a94683196406b83b14218d1beef66067f126a16keunyoung#include "JpegCompressor.h"
248a94683196406b83b14218d1beef66067f126a16keunyoung#include "../EmulatedFakeCamera2.h"
2557ac67ad91c44ffd875b186f124234c2ab1958f3Eino-Ville Talvala#include "../EmulatedFakeCamera3.h"
268a94683196406b83b14218d1beef66067f126a16keunyoung
278a94683196406b83b14218d1beef66067f126a16keunyoungnamespace android {
288a94683196406b83b14218d1beef66067f126a16keunyoung
2957ac67ad91c44ffd875b186f124234c2ab1958f3Eino-Ville TalvalaJpegCompressor::JpegCompressor():
308a94683196406b83b14218d1beef66067f126a16keunyoung        Thread(false),
318a94683196406b83b14218d1beef66067f126a16keunyoung        mIsBusy(false),
3203a28bba9dcf5276cdf64408a648e1dddd2945baEino-Ville Talvala        mSynchronous(false),
338a94683196406b83b14218d1beef66067f126a16keunyoung        mBuffers(NULL),
3457ac67ad91c44ffd875b186f124234c2ab1958f3Eino-Ville Talvala        mListener(NULL) {
358a94683196406b83b14218d1beef66067f126a16keunyoung}
368a94683196406b83b14218d1beef66067f126a16keunyoung
378a94683196406b83b14218d1beef66067f126a16keunyoungJpegCompressor::~JpegCompressor() {
388a94683196406b83b14218d1beef66067f126a16keunyoung    Mutex::Autolock lock(mMutex);
398a94683196406b83b14218d1beef66067f126a16keunyoung}
408a94683196406b83b14218d1beef66067f126a16keunyoung
4157ac67ad91c44ffd875b186f124234c2ab1958f3Eino-Ville Talvalastatus_t JpegCompressor::start(Buffers *buffers, JpegListener *listener) {
4257ac67ad91c44ffd875b186f124234c2ab1958f3Eino-Ville Talvala    if (listener == NULL) {
4357ac67ad91c44ffd875b186f124234c2ab1958f3Eino-Ville Talvala        ALOGE("%s: NULL listener not allowed!", __FUNCTION__);
4457ac67ad91c44ffd875b186f124234c2ab1958f3Eino-Ville Talvala        return BAD_VALUE;
4557ac67ad91c44ffd875b186f124234c2ab1958f3Eino-Ville Talvala    }
468a94683196406b83b14218d1beef66067f126a16keunyoung    Mutex::Autolock lock(mMutex);
478a94683196406b83b14218d1beef66067f126a16keunyoung    {
488a94683196406b83b14218d1beef66067f126a16keunyoung        Mutex::Autolock busyLock(mBusyMutex);
498a94683196406b83b14218d1beef66067f126a16keunyoung
508a94683196406b83b14218d1beef66067f126a16keunyoung        if (mIsBusy) {
518a94683196406b83b14218d1beef66067f126a16keunyoung            ALOGE("%s: Already processing a buffer!", __FUNCTION__);
528a94683196406b83b14218d1beef66067f126a16keunyoung            return INVALID_OPERATION;
538a94683196406b83b14218d1beef66067f126a16keunyoung        }
548a94683196406b83b14218d1beef66067f126a16keunyoung
558a94683196406b83b14218d1beef66067f126a16keunyoung        mIsBusy = true;
5603a28bba9dcf5276cdf64408a648e1dddd2945baEino-Ville Talvala        mSynchronous = false;
578a94683196406b83b14218d1beef66067f126a16keunyoung        mBuffers = buffers;
5857ac67ad91c44ffd875b186f124234c2ab1958f3Eino-Ville Talvala        mListener = listener;
598a94683196406b83b14218d1beef66067f126a16keunyoung    }
608a94683196406b83b14218d1beef66067f126a16keunyoung
618a94683196406b83b14218d1beef66067f126a16keunyoung    status_t res;
628a94683196406b83b14218d1beef66067f126a16keunyoung    res = run("EmulatedFakeCamera2::JpegCompressor");
638a94683196406b83b14218d1beef66067f126a16keunyoung    if (res != OK) {
648a94683196406b83b14218d1beef66067f126a16keunyoung        ALOGE("%s: Unable to start up compression thread: %s (%d)",
658a94683196406b83b14218d1beef66067f126a16keunyoung                __FUNCTION__, strerror(-res), res);
668a94683196406b83b14218d1beef66067f126a16keunyoung        delete mBuffers;
678a94683196406b83b14218d1beef66067f126a16keunyoung    }
688a94683196406b83b14218d1beef66067f126a16keunyoung    return res;
698a94683196406b83b14218d1beef66067f126a16keunyoung}
708a94683196406b83b14218d1beef66067f126a16keunyoung
7103a28bba9dcf5276cdf64408a648e1dddd2945baEino-Ville Talvalastatus_t JpegCompressor::compressSynchronous(Buffers *buffers) {
7203a28bba9dcf5276cdf64408a648e1dddd2945baEino-Ville Talvala    status_t res;
7303a28bba9dcf5276cdf64408a648e1dddd2945baEino-Ville Talvala
7403a28bba9dcf5276cdf64408a648e1dddd2945baEino-Ville Talvala    Mutex::Autolock lock(mMutex);
7503a28bba9dcf5276cdf64408a648e1dddd2945baEino-Ville Talvala    {
7603a28bba9dcf5276cdf64408a648e1dddd2945baEino-Ville Talvala        Mutex::Autolock busyLock(mBusyMutex);
7703a28bba9dcf5276cdf64408a648e1dddd2945baEino-Ville Talvala
7803a28bba9dcf5276cdf64408a648e1dddd2945baEino-Ville Talvala        if (mIsBusy) {
7903a28bba9dcf5276cdf64408a648e1dddd2945baEino-Ville Talvala            ALOGE("%s: Already processing a buffer!", __FUNCTION__);
8003a28bba9dcf5276cdf64408a648e1dddd2945baEino-Ville Talvala            return INVALID_OPERATION;
8103a28bba9dcf5276cdf64408a648e1dddd2945baEino-Ville Talvala        }
8203a28bba9dcf5276cdf64408a648e1dddd2945baEino-Ville Talvala
8303a28bba9dcf5276cdf64408a648e1dddd2945baEino-Ville Talvala        mIsBusy = true;
8403a28bba9dcf5276cdf64408a648e1dddd2945baEino-Ville Talvala        mSynchronous = true;
8503a28bba9dcf5276cdf64408a648e1dddd2945baEino-Ville Talvala        mBuffers = buffers;
8603a28bba9dcf5276cdf64408a648e1dddd2945baEino-Ville Talvala    }
8703a28bba9dcf5276cdf64408a648e1dddd2945baEino-Ville Talvala
8803a28bba9dcf5276cdf64408a648e1dddd2945baEino-Ville Talvala    res = compress();
8957ac67ad91c44ffd875b186f124234c2ab1958f3Eino-Ville Talvala
9057ac67ad91c44ffd875b186f124234c2ab1958f3Eino-Ville Talvala    cleanUp();
9157ac67ad91c44ffd875b186f124234c2ab1958f3Eino-Ville Talvala
9203a28bba9dcf5276cdf64408a648e1dddd2945baEino-Ville Talvala    return res;
9303a28bba9dcf5276cdf64408a648e1dddd2945baEino-Ville Talvala}
9403a28bba9dcf5276cdf64408a648e1dddd2945baEino-Ville Talvala
958a94683196406b83b14218d1beef66067f126a16keunyoungstatus_t JpegCompressor::cancel() {
968a94683196406b83b14218d1beef66067f126a16keunyoung    requestExitAndWait();
978a94683196406b83b14218d1beef66067f126a16keunyoung    return OK;
988a94683196406b83b14218d1beef66067f126a16keunyoung}
998a94683196406b83b14218d1beef66067f126a16keunyoung
1008a94683196406b83b14218d1beef66067f126a16keunyoungstatus_t JpegCompressor::readyToRun() {
1018a94683196406b83b14218d1beef66067f126a16keunyoung    return OK;
1028a94683196406b83b14218d1beef66067f126a16keunyoung}
1038a94683196406b83b14218d1beef66067f126a16keunyoung
1048a94683196406b83b14218d1beef66067f126a16keunyoungbool JpegCompressor::threadLoop() {
10503a28bba9dcf5276cdf64408a648e1dddd2945baEino-Ville Talvala    status_t res;
1068a94683196406b83b14218d1beef66067f126a16keunyoung    ALOGV("%s: Starting compression thread", __FUNCTION__);
1078a94683196406b83b14218d1beef66067f126a16keunyoung
10803a28bba9dcf5276cdf64408a648e1dddd2945baEino-Ville Talvala    res = compress();
10903a28bba9dcf5276cdf64408a648e1dddd2945baEino-Ville Talvala
11057ac67ad91c44ffd875b186f124234c2ab1958f3Eino-Ville Talvala    mListener->onJpegDone(mJpegBuffer, res == OK);
11103a28bba9dcf5276cdf64408a648e1dddd2945baEino-Ville Talvala
11257ac67ad91c44ffd875b186f124234c2ab1958f3Eino-Ville Talvala    cleanUp();
11303a28bba9dcf5276cdf64408a648e1dddd2945baEino-Ville Talvala
11403a28bba9dcf5276cdf64408a648e1dddd2945baEino-Ville Talvala    return false;
11503a28bba9dcf5276cdf64408a648e1dddd2945baEino-Ville Talvala}
11603a28bba9dcf5276cdf64408a648e1dddd2945baEino-Ville Talvala
11703a28bba9dcf5276cdf64408a648e1dddd2945baEino-Ville Talvalastatus_t JpegCompressor::compress() {
1188a94683196406b83b14218d1beef66067f126a16keunyoung    // Find source and target buffers. Assumes only one buffer matches
1198a94683196406b83b14218d1beef66067f126a16keunyoung    // each condition!
1208a94683196406b83b14218d1beef66067f126a16keunyoung
1218a94683196406b83b14218d1beef66067f126a16keunyoung    bool foundJpeg = false, mFoundAux = false;
1228a94683196406b83b14218d1beef66067f126a16keunyoung    for (size_t i = 0; i < mBuffers->size(); i++) {
1238a94683196406b83b14218d1beef66067f126a16keunyoung        const StreamBuffer &b = (*mBuffers)[i];
1248a94683196406b83b14218d1beef66067f126a16keunyoung        if (b.format == HAL_PIXEL_FORMAT_BLOB) {
1258a94683196406b83b14218d1beef66067f126a16keunyoung            mJpegBuffer = b;
1268a94683196406b83b14218d1beef66067f126a16keunyoung            mFoundJpeg = true;
1278a94683196406b83b14218d1beef66067f126a16keunyoung        } else if (b.streamId <= 0) {
1288a94683196406b83b14218d1beef66067f126a16keunyoung            mAuxBuffer = b;
1298a94683196406b83b14218d1beef66067f126a16keunyoung            mFoundAux = true;
1308a94683196406b83b14218d1beef66067f126a16keunyoung        }
1318a94683196406b83b14218d1beef66067f126a16keunyoung        if (mFoundJpeg && mFoundAux) break;
1328a94683196406b83b14218d1beef66067f126a16keunyoung    }
1338a94683196406b83b14218d1beef66067f126a16keunyoung    if (!mFoundJpeg || !mFoundAux) {
1348a94683196406b83b14218d1beef66067f126a16keunyoung        ALOGE("%s: Unable to find buffers for JPEG source/destination",
1358a94683196406b83b14218d1beef66067f126a16keunyoung                __FUNCTION__);
13603a28bba9dcf5276cdf64408a648e1dddd2945baEino-Ville Talvala        return BAD_VALUE;
1378a94683196406b83b14218d1beef66067f126a16keunyoung    }
1388a94683196406b83b14218d1beef66067f126a16keunyoung
1398a94683196406b83b14218d1beef66067f126a16keunyoung    // Set up error management
1408a94683196406b83b14218d1beef66067f126a16keunyoung
1418a94683196406b83b14218d1beef66067f126a16keunyoung    mJpegErrorInfo = NULL;
1428a94683196406b83b14218d1beef66067f126a16keunyoung    JpegError error;
1438a94683196406b83b14218d1beef66067f126a16keunyoung    error.parent = this;
1448a94683196406b83b14218d1beef66067f126a16keunyoung
1458a94683196406b83b14218d1beef66067f126a16keunyoung    mCInfo.err = jpeg_std_error(&error);
1468a94683196406b83b14218d1beef66067f126a16keunyoung    mCInfo.err->error_exit = jpegErrorHandler;
1478a94683196406b83b14218d1beef66067f126a16keunyoung
1488a94683196406b83b14218d1beef66067f126a16keunyoung    jpeg_create_compress(&mCInfo);
14903a28bba9dcf5276cdf64408a648e1dddd2945baEino-Ville Talvala    if (checkError("Error initializing compression")) return NO_INIT;
1508a94683196406b83b14218d1beef66067f126a16keunyoung
1518a94683196406b83b14218d1beef66067f126a16keunyoung    // Route compressed data straight to output stream buffer
1528a94683196406b83b14218d1beef66067f126a16keunyoung
1538a94683196406b83b14218d1beef66067f126a16keunyoung    JpegDestination jpegDestMgr;
1548a94683196406b83b14218d1beef66067f126a16keunyoung    jpegDestMgr.parent = this;
1558a94683196406b83b14218d1beef66067f126a16keunyoung    jpegDestMgr.init_destination = jpegInitDestination;
1568a94683196406b83b14218d1beef66067f126a16keunyoung    jpegDestMgr.empty_output_buffer = jpegEmptyOutputBuffer;
1578a94683196406b83b14218d1beef66067f126a16keunyoung    jpegDestMgr.term_destination = jpegTermDestination;
1588a94683196406b83b14218d1beef66067f126a16keunyoung
1598a94683196406b83b14218d1beef66067f126a16keunyoung    mCInfo.dest = &jpegDestMgr;
1608a94683196406b83b14218d1beef66067f126a16keunyoung
1618a94683196406b83b14218d1beef66067f126a16keunyoung    // Set up compression parameters
1628a94683196406b83b14218d1beef66067f126a16keunyoung
1638a94683196406b83b14218d1beef66067f126a16keunyoung    mCInfo.image_width = mAuxBuffer.width;
1648a94683196406b83b14218d1beef66067f126a16keunyoung    mCInfo.image_height = mAuxBuffer.height;
1658a94683196406b83b14218d1beef66067f126a16keunyoung    mCInfo.input_components = 3;
1668a94683196406b83b14218d1beef66067f126a16keunyoung    mCInfo.in_color_space = JCS_RGB;
1678a94683196406b83b14218d1beef66067f126a16keunyoung
1688a94683196406b83b14218d1beef66067f126a16keunyoung    jpeg_set_defaults(&mCInfo);
16903a28bba9dcf5276cdf64408a648e1dddd2945baEino-Ville Talvala    if (checkError("Error configuring defaults")) return NO_INIT;
1708a94683196406b83b14218d1beef66067f126a16keunyoung
1718a94683196406b83b14218d1beef66067f126a16keunyoung    // Do compression
1728a94683196406b83b14218d1beef66067f126a16keunyoung
1738a94683196406b83b14218d1beef66067f126a16keunyoung    jpeg_start_compress(&mCInfo, TRUE);
17403a28bba9dcf5276cdf64408a648e1dddd2945baEino-Ville Talvala    if (checkError("Error starting compression")) return NO_INIT;
1758a94683196406b83b14218d1beef66067f126a16keunyoung
1768a94683196406b83b14218d1beef66067f126a16keunyoung    size_t rowStride = mAuxBuffer.stride * 3;
1778a94683196406b83b14218d1beef66067f126a16keunyoung    const size_t kChunkSize = 32;
1788a94683196406b83b14218d1beef66067f126a16keunyoung    while (mCInfo.next_scanline < mCInfo.image_height) {
1798a94683196406b83b14218d1beef66067f126a16keunyoung        JSAMPROW chunk[kChunkSize];
1808a94683196406b83b14218d1beef66067f126a16keunyoung        for (size_t i = 0 ; i < kChunkSize; i++) {
1818a94683196406b83b14218d1beef66067f126a16keunyoung            chunk[i] = (JSAMPROW)
1828a94683196406b83b14218d1beef66067f126a16keunyoung                    (mAuxBuffer.img + (i + mCInfo.next_scanline) * rowStride);
1838a94683196406b83b14218d1beef66067f126a16keunyoung        }
1848a94683196406b83b14218d1beef66067f126a16keunyoung        jpeg_write_scanlines(&mCInfo, chunk, kChunkSize);
18503a28bba9dcf5276cdf64408a648e1dddd2945baEino-Ville Talvala        if (checkError("Error while compressing")) return NO_INIT;
1868a94683196406b83b14218d1beef66067f126a16keunyoung        if (exitPending()) {
1878a94683196406b83b14218d1beef66067f126a16keunyoung            ALOGV("%s: Cancel called, exiting early", __FUNCTION__);
18803a28bba9dcf5276cdf64408a648e1dddd2945baEino-Ville Talvala            return TIMED_OUT;
1898a94683196406b83b14218d1beef66067f126a16keunyoung        }
1908a94683196406b83b14218d1beef66067f126a16keunyoung    }
1918a94683196406b83b14218d1beef66067f126a16keunyoung
1928a94683196406b83b14218d1beef66067f126a16keunyoung    jpeg_finish_compress(&mCInfo);
19303a28bba9dcf5276cdf64408a648e1dddd2945baEino-Ville Talvala    if (checkError("Error while finishing compression")) return NO_INIT;
1948a94683196406b83b14218d1beef66067f126a16keunyoung
1958a94683196406b83b14218d1beef66067f126a16keunyoung    // All done
1968a94683196406b83b14218d1beef66067f126a16keunyoung
19703a28bba9dcf5276cdf64408a648e1dddd2945baEino-Ville Talvala    return OK;
1988a94683196406b83b14218d1beef66067f126a16keunyoung}
1998a94683196406b83b14218d1beef66067f126a16keunyoung
2008a94683196406b83b14218d1beef66067f126a16keunyoungbool JpegCompressor::isBusy() {
2018a94683196406b83b14218d1beef66067f126a16keunyoung    Mutex::Autolock busyLock(mBusyMutex);
2028a94683196406b83b14218d1beef66067f126a16keunyoung    return mIsBusy;
2038a94683196406b83b14218d1beef66067f126a16keunyoung}
2048a94683196406b83b14218d1beef66067f126a16keunyoung
2058a94683196406b83b14218d1beef66067f126a16keunyoungbool JpegCompressor::isStreamInUse(uint32_t id) {
2068a94683196406b83b14218d1beef66067f126a16keunyoung    Mutex::Autolock lock(mBusyMutex);
2078a94683196406b83b14218d1beef66067f126a16keunyoung
2088a94683196406b83b14218d1beef66067f126a16keunyoung    if (mBuffers && mIsBusy) {
2098a94683196406b83b14218d1beef66067f126a16keunyoung        for (size_t i = 0; i < mBuffers->size(); i++) {
2108a94683196406b83b14218d1beef66067f126a16keunyoung            if ( (*mBuffers)[i].streamId == (int)id ) return true;
2118a94683196406b83b14218d1beef66067f126a16keunyoung        }
2128a94683196406b83b14218d1beef66067f126a16keunyoung    }
2138a94683196406b83b14218d1beef66067f126a16keunyoung    return false;
2148a94683196406b83b14218d1beef66067f126a16keunyoung}
2158a94683196406b83b14218d1beef66067f126a16keunyoung
2168a94683196406b83b14218d1beef66067f126a16keunyoungbool JpegCompressor::waitForDone(nsecs_t timeout) {
2178a94683196406b83b14218d1beef66067f126a16keunyoung    Mutex::Autolock lock(mBusyMutex);
2188a94683196406b83b14218d1beef66067f126a16keunyoung    status_t res = OK;
2198a94683196406b83b14218d1beef66067f126a16keunyoung    if (mIsBusy) {
2208a94683196406b83b14218d1beef66067f126a16keunyoung        res = mDone.waitRelative(mBusyMutex, timeout);
2218a94683196406b83b14218d1beef66067f126a16keunyoung    }
2228a94683196406b83b14218d1beef66067f126a16keunyoung    return (res == OK);
2238a94683196406b83b14218d1beef66067f126a16keunyoung}
2248a94683196406b83b14218d1beef66067f126a16keunyoung
2258a94683196406b83b14218d1beef66067f126a16keunyoungbool JpegCompressor::checkError(const char *msg) {
2268a94683196406b83b14218d1beef66067f126a16keunyoung    if (mJpegErrorInfo) {
2278a94683196406b83b14218d1beef66067f126a16keunyoung        char errBuffer[JMSG_LENGTH_MAX];
2288a94683196406b83b14218d1beef66067f126a16keunyoung        mJpegErrorInfo->err->format_message(mJpegErrorInfo, errBuffer);
2298a94683196406b83b14218d1beef66067f126a16keunyoung        ALOGE("%s: %s: %s",
2308a94683196406b83b14218d1beef66067f126a16keunyoung                __FUNCTION__, msg, errBuffer);
2318a94683196406b83b14218d1beef66067f126a16keunyoung        mJpegErrorInfo = NULL;
2328a94683196406b83b14218d1beef66067f126a16keunyoung        return true;
2338a94683196406b83b14218d1beef66067f126a16keunyoung    }
2348a94683196406b83b14218d1beef66067f126a16keunyoung    return false;
2358a94683196406b83b14218d1beef66067f126a16keunyoung}
2368a94683196406b83b14218d1beef66067f126a16keunyoung
2378a94683196406b83b14218d1beef66067f126a16keunyoungvoid JpegCompressor::cleanUp() {
2388a94683196406b83b14218d1beef66067f126a16keunyoung    status_t res;
2398a94683196406b83b14218d1beef66067f126a16keunyoung    jpeg_destroy_compress(&mCInfo);
2408a94683196406b83b14218d1beef66067f126a16keunyoung    Mutex::Autolock lock(mBusyMutex);
2418a94683196406b83b14218d1beef66067f126a16keunyoung
2428a94683196406b83b14218d1beef66067f126a16keunyoung    if (mFoundAux) {
2438a94683196406b83b14218d1beef66067f126a16keunyoung        if (mAuxBuffer.streamId == 0) {
2448a94683196406b83b14218d1beef66067f126a16keunyoung            delete[] mAuxBuffer.img;
24503a28bba9dcf5276cdf64408a648e1dddd2945baEino-Ville Talvala        } else if (!mSynchronous) {
24657ac67ad91c44ffd875b186f124234c2ab1958f3Eino-Ville Talvala            mListener->onJpegInputDone(mAuxBuffer);
2478a94683196406b83b14218d1beef66067f126a16keunyoung        }
2488a94683196406b83b14218d1beef66067f126a16keunyoung    }
24903a28bba9dcf5276cdf64408a648e1dddd2945baEino-Ville Talvala    if (!mSynchronous) {
25003a28bba9dcf5276cdf64408a648e1dddd2945baEino-Ville Talvala        delete mBuffers;
25103a28bba9dcf5276cdf64408a648e1dddd2945baEino-Ville Talvala    }
25203a28bba9dcf5276cdf64408a648e1dddd2945baEino-Ville Talvala
2538a94683196406b83b14218d1beef66067f126a16keunyoung    mBuffers = NULL;
2548a94683196406b83b14218d1beef66067f126a16keunyoung
2558a94683196406b83b14218d1beef66067f126a16keunyoung    mIsBusy = false;
2568a94683196406b83b14218d1beef66067f126a16keunyoung    mDone.signal();
2578a94683196406b83b14218d1beef66067f126a16keunyoung}
2588a94683196406b83b14218d1beef66067f126a16keunyoung
2598a94683196406b83b14218d1beef66067f126a16keunyoungvoid JpegCompressor::jpegErrorHandler(j_common_ptr cinfo) {
2608a94683196406b83b14218d1beef66067f126a16keunyoung    JpegError *error = static_cast<JpegError*>(cinfo->err);
2618a94683196406b83b14218d1beef66067f126a16keunyoung    error->parent->mJpegErrorInfo = cinfo;
2628a94683196406b83b14218d1beef66067f126a16keunyoung}
2638a94683196406b83b14218d1beef66067f126a16keunyoung
2648a94683196406b83b14218d1beef66067f126a16keunyoungvoid JpegCompressor::jpegInitDestination(j_compress_ptr cinfo) {
2658a94683196406b83b14218d1beef66067f126a16keunyoung    JpegDestination *dest= static_cast<JpegDestination*>(cinfo->dest);
2663725c7c982eac52ec64a625e82f306822452941cColin Cross    ALOGV("%s: Setting destination to %p, size %zu",
2678a94683196406b83b14218d1beef66067f126a16keunyoung            __FUNCTION__, dest->parent->mJpegBuffer.img, kMaxJpegSize);
2688a94683196406b83b14218d1beef66067f126a16keunyoung    dest->next_output_byte = (JOCTET*)(dest->parent->mJpegBuffer.img);
2698a94683196406b83b14218d1beef66067f126a16keunyoung    dest->free_in_buffer = kMaxJpegSize;
2708a94683196406b83b14218d1beef66067f126a16keunyoung}
2718a94683196406b83b14218d1beef66067f126a16keunyoung
2728a94683196406b83b14218d1beef66067f126a16keunyoungboolean JpegCompressor::jpegEmptyOutputBuffer(j_compress_ptr cinfo) {
2738a94683196406b83b14218d1beef66067f126a16keunyoung    ALOGE("%s: JPEG destination buffer overflow!",
2748a94683196406b83b14218d1beef66067f126a16keunyoung            __FUNCTION__);
2758a94683196406b83b14218d1beef66067f126a16keunyoung    return true;
2768a94683196406b83b14218d1beef66067f126a16keunyoung}
2778a94683196406b83b14218d1beef66067f126a16keunyoung
2788a94683196406b83b14218d1beef66067f126a16keunyoungvoid JpegCompressor::jpegTermDestination(j_compress_ptr cinfo) {
2793725c7c982eac52ec64a625e82f306822452941cColin Cross    ALOGV("%s: Done writing JPEG data. %zu bytes left in buffer",
2808a94683196406b83b14218d1beef66067f126a16keunyoung            __FUNCTION__, cinfo->dest->free_in_buffer);
2818a94683196406b83b14218d1beef66067f126a16keunyoung}
2828a94683196406b83b14218d1beef66067f126a16keunyoung
28357ac67ad91c44ffd875b186f124234c2ab1958f3Eino-Ville TalvalaJpegCompressor::JpegListener::~JpegListener() {
28457ac67ad91c44ffd875b186f124234c2ab1958f3Eino-Ville Talvala}
28557ac67ad91c44ffd875b186f124234c2ab1958f3Eino-Ville Talvala
2868a94683196406b83b14218d1beef66067f126a16keunyoung} // namespace android
287