10b167267bda99b68346045ccab14e810121d5de4Glenn Kasten/*
20b167267bda99b68346045ccab14e810121d5de4Glenn Kasten * Copyright (C) 2012 The Android Open Source Project
30b167267bda99b68346045ccab14e810121d5de4Glenn Kasten *
40b167267bda99b68346045ccab14e810121d5de4Glenn Kasten * Licensed under the Apache License, Version 2.0 (the "License");
50b167267bda99b68346045ccab14e810121d5de4Glenn Kasten * you may not use this file except in compliance with the License.
60b167267bda99b68346045ccab14e810121d5de4Glenn Kasten * You may obtain a copy of the License at
70b167267bda99b68346045ccab14e810121d5de4Glenn Kasten *
80b167267bda99b68346045ccab14e810121d5de4Glenn Kasten *      http://www.apache.org/licenses/LICENSE-2.0
90b167267bda99b68346045ccab14e810121d5de4Glenn Kasten *
100b167267bda99b68346045ccab14e810121d5de4Glenn Kasten * Unless required by applicable law or agreed to in writing, software
110b167267bda99b68346045ccab14e810121d5de4Glenn Kasten * distributed under the License is distributed on an "AS IS" BASIS,
120b167267bda99b68346045ccab14e810121d5de4Glenn Kasten * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130b167267bda99b68346045ccab14e810121d5de4Glenn Kasten * See the License for the specific language governing permissions and
140b167267bda99b68346045ccab14e810121d5de4Glenn Kasten * limitations under the License.
150b167267bda99b68346045ccab14e810121d5de4Glenn Kasten */
160b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
170b167267bda99b68346045ccab14e810121d5de4Glenn Kasten//#define LOG_NDEBUG 0
180b167267bda99b68346045ccab14e810121d5de4Glenn Kasten#define LOG_TAG "Camera2-JpegCompressor"
19979a3f8743646af9999a89dff9e13b972b7efd87Glenn Kasten
20979a3f8743646af9999a89dff9e13b972b7efd87Glenn Kasten#include <utils/Log.h>
21ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten#include <ui/GraphicBufferMapper.h>
22daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten
23daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten#include "JpegCompressor.h"
240b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
25ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kastennamespace android {
26ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kastennamespace camera2 {
27c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten
28928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn KastenJpegCompressor::JpegCompressor():
29ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        Thread(false),
30ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        mIsBusy(false),
31ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        mCaptureTime(0) {
32ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten}
33ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
34ed46c29d6a09112dbbf584c82953f63289596fd6Glenn KastenJpegCompressor::~JpegCompressor() {
35ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    ALOGV("%s", __FUNCTION__);
36ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    Mutex::Autolock lock(mMutex);
37ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten}
38ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
39ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kastenstatus_t JpegCompressor::start(Vector<CpuConsumer::LockedBuffer*> buffers,
40ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        nsecs_t captureTime) {
41ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    ALOGV("%s", __FUNCTION__);
42ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    Mutex::Autolock busyLock(mBusyMutex);
43ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
44ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    if (mIsBusy) {
45ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        ALOGE("%s: Already processing a buffer!", __FUNCTION__);
467a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten        return INVALID_OPERATION;
477a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten    }
487a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten
49ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    mIsBusy = true;
50ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
510b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    mBuffers = buffers;
520b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    mCaptureTime = captureTime;
53ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
54daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten    status_t res;
55daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten    res = run("JpegCompressor");
560b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    if (res != OK) {
57ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        ALOGE("%s: Unable to start up compression thread: %s (%d)",
58ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten                __FUNCTION__, strerror(-res), res);
59c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten        //delete mBuffers;  // necessary?
60928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten    }
61ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    return res;
62ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten}
63ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
64ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kastenstatus_t JpegCompressor::cancel() {
65ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    ALOGV("%s", __FUNCTION__);
66ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    requestExitAndWait();
67ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    return OK;
68ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten}
69ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
70ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kastenstatus_t JpegCompressor::readyToRun() {
71ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    ALOGV("%s", __FUNCTION__);
72ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    return OK;
73ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten}
74ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
75ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kastenbool JpegCompressor::threadLoop() {
76ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    ALOGV("%s", __FUNCTION__);
77ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
787a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten    mAuxBuffer = mBuffers[0];    // input
797a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten    mJpegBuffer = mBuffers[1];    // output
807a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten
81ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    // Set up error management
82ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    mJpegErrorInfo = NULL;
830b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    JpegError error;
840b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    error.parent = this;
85ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
860b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    mCInfo.err = jpeg_std_error(&error);
870b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    mCInfo.err->error_exit = jpegErrorHandler;
880b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
890b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    jpeg_create_compress(&mCInfo);
90ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    if (checkError("Error initializing compression")) return false;
91ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
92ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    // Route compressed data straight to output stream buffer
93ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    JpegDestination jpegDestMgr;
94ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    jpegDestMgr.parent = this;
95ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    jpegDestMgr.init_destination = jpegInitDestination;
96ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    jpegDestMgr.empty_output_buffer = jpegEmptyOutputBuffer;
97ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    jpegDestMgr.term_destination = jpegTermDestination;
98ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
99ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    mCInfo.dest = &jpegDestMgr;
100ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
101ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    // Set up compression parameters
102ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    mCInfo.image_width = mAuxBuffer->width;
103ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    mCInfo.image_height = mAuxBuffer->height;
104ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    mCInfo.input_components = 1; // 3;
105ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    mCInfo.in_color_space = JCS_GRAYSCALE; // JCS_RGB
106ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
107b91e32605ecf39e34ad39936b1ee193bb4e30225Glenn Kasten    ALOGV("%s: image_width = %d, image_height = %d", __FUNCTION__, mCInfo.image_width, mCInfo.image_height);
108ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
109daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten    jpeg_set_defaults(&mCInfo);
110ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    if (checkError("Error configuring defaults")) return false;
111343c522ebf4f9c321eef8c3b3b2945f1c1cb8846Glenn Kasten
112ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    // Do compression
113ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    jpeg_start_compress(&mCInfo, TRUE);
114ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    if (checkError("Error starting compression")) return false;
115ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
116ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    size_t rowStride = mAuxBuffer->stride;// * 3;
117daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten    const size_t kChunkSize = 32;
118ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    while (mCInfo.next_scanline < mCInfo.image_height) {
119ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        JSAMPROW chunk[kChunkSize];
120ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        for (size_t i = 0 ; i < kChunkSize; i++) {
121daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten            chunk[i] = (JSAMPROW)
122ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten                    (mAuxBuffer->data + (i + mCInfo.next_scanline) * rowStride);
1233c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi        }
1243c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi        jpeg_write_scanlines(&mCInfo, chunk, kChunkSize);
1253c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi        if (checkError("Error while compressing")) return false;
1263c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi        if (exitPending()) {
1273c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi            ALOGV("%s: Cancel called, exiting early", __FUNCTION__);
1283c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi            cleanUp();
1293c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi            return false;
130ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        }
1313c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi    }
132daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten
133712b490060e4164fbe47986be1d2584d1610d8ddJean-Michel Trivi    jpeg_finish_compress(&mCInfo);
1343c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi    if (checkError("Error while finishing compression")) return false;
135ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
1363c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi    cleanUp();
137daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten    return false;
1384b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten}
13918abcc4b70fab1f84d6fbebac3a8e34480a6c4d3Glenn Kasten
1404b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kastenbool JpegCompressor::isBusy() {
1414b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten    ALOGV("%s", __FUNCTION__);
14218abcc4b70fab1f84d6fbebac3a8e34480a6c4d3Glenn Kasten    Mutex::Autolock busyLock(mBusyMutex);
1434b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten    return mIsBusy;
1444b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten}
145928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten
146343c522ebf4f9c321eef8c3b3b2945f1c1cb8846Glenn Kasten// old function -- TODO: update for new buffer type
147343c522ebf4f9c321eef8c3b3b2945f1c1cb8846Glenn Kastenbool JpegCompressor::isStreamInUse(uint32_t id) {
148343c522ebf4f9c321eef8c3b3b2945f1c1cb8846Glenn Kasten    ALOGV("%s", __FUNCTION__);
149343c522ebf4f9c321eef8c3b3b2945f1c1cb8846Glenn Kasten    Mutex::Autolock lock(mBusyMutex);
150343c522ebf4f9c321eef8c3b3b2945f1c1cb8846Glenn Kasten
151ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    if (mBuffers.size() && mIsBusy) {
152ef8931ae547cd703e69df9ad350d69825da0f546Jean-Michel Trivi        for (size_t i = 0; i < mBuffers.size(); i++) {
153d739e18bea1deaf7c487f99a512c0ae7649615c2Jean-Michel Trivi//            if ( mBuffers[i].streamId == (int)id ) return true;
154928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten        }
155ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    }
156928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten    return false;
1570b167267bda99b68346045ccab14e810121d5de4Glenn Kasten}
158acd88797a1d3b8225bab888d29036e245f275be5Glenn Kasten
1590b167267bda99b68346045ccab14e810121d5de4Glenn Kastenbool JpegCompressor::waitForDone(nsecs_t timeout) {
160ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    ALOGV("%s", __FUNCTION__);
161928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten    Mutex::Autolock lock(mBusyMutex);
162ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    status_t res = OK;
163928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten    if (mIsBusy) {
1640b167267bda99b68346045ccab14e810121d5de4Glenn Kasten        res = mDone.waitRelative(mBusyMutex, timeout);
1650b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    }
1660b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    return (res == OK);
167ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten}
168928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten
169ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kastenbool JpegCompressor::checkError(const char *msg) {
170928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten    ALOGV("%s", __FUNCTION__);
171daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten    if (mJpegErrorInfo) {
1720b167267bda99b68346045ccab14e810121d5de4Glenn Kasten        char errBuffer[JMSG_LENGTH_MAX];
1733af2a8dd03f3113d5da1000dd79c143a9f0c4f36Jean-Michel Trivi        mJpegErrorInfo->err->format_message(mJpegErrorInfo, errBuffer);
174ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        ALOGE("%s: %s: %s",
1754b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten                __FUNCTION__, msg, errBuffer);
176ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        cleanUp();
177ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        mJpegErrorInfo = NULL;
178ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        return true;
179ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    }
180ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    return false;
181ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten}
182ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
183ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kastenvoid JpegCompressor::cleanUp() {
184ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    ALOGV("%s", __FUNCTION__);
185ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    jpeg_destroy_compress(&mCInfo);
186ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    Mutex::Autolock lock(mBusyMutex);
187ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    mIsBusy = false;
188ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    mDone.signal();
189ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten}
190ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
191ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kastenvoid JpegCompressor::jpegErrorHandler(j_common_ptr cinfo) {
192ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    ALOGV("%s", __FUNCTION__);
193ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    JpegError *error = static_cast<JpegError*>(cinfo->err);
194ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    error->parent->mJpegErrorInfo = cinfo;
195ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten}
196ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
197ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kastenvoid JpegCompressor::jpegInitDestination(j_compress_ptr cinfo) {
198ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    ALOGV("%s", __FUNCTION__);
199ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    JpegDestination *dest= static_cast<JpegDestination*>(cinfo->dest);
200ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    ALOGV("%s: Setting destination to %p, size %d",
201ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            __FUNCTION__, dest->parent->mJpegBuffer->data, kMaxJpegSize);
202ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    dest->next_output_byte = (JOCTET*)(dest->parent->mJpegBuffer->data);
203ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    dest->free_in_buffer = kMaxJpegSize;
204d739e18bea1deaf7c487f99a512c0ae7649615c2Jean-Michel Trivi}
205ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
2060b167267bda99b68346045ccab14e810121d5de4Glenn Kastenboolean JpegCompressor::jpegEmptyOutputBuffer(j_compress_ptr cinfo) {
207ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    ALOGV("%s", __FUNCTION__);
208ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    ALOGE("%s: JPEG destination buffer overflow!",
209daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten            __FUNCTION__);
210ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    return true;
211daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten}
212e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten
213ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kastenvoid JpegCompressor::jpegTermDestination(j_compress_ptr cinfo) {
214e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten    ALOGV("%s", __FUNCTION__);
215e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten    ALOGV("%s: Done writing JPEG data. %d bytes left in buffer",
216daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten            __FUNCTION__, cinfo->dest->free_in_buffer);
217ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten}
218ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
219acd88797a1d3b8225bab888d29036e245f275be5Glenn Kasten}; // namespace camera2
220ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten}; // namespace android
221ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten