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