JpegProcessor.cpp revision ecf17e82505fdb60d59e00b6dd59036df93de655
1ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala/* 2ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala * Copyright (C) 2012 The Android Open Source Project 3ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala * 4ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala * Licensed under the Apache License, Version 2.0 (the "License"); 5ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala * you may not use this file except in compliance with the License. 6ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala * You may obtain a copy of the License at 7ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala * 8ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala * http://www.apache.org/licenses/LICENSE-2.0 9ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala * 10ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala * Unless required by applicable law or agreed to in writing, software 11ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala * distributed under the License is distributed on an "AS IS" BASIS, 12ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala * See the License for the specific language governing permissions and 14ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala * limitations under the License. 15ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala */ 16ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala 174bb8118816874c696d9f1adab48490df1da365f7Eino-Ville Talvala#define LOG_TAG "Camera2-JpegProcessor" 18ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala#define ATRACE_TAG ATRACE_TAG_CAMERA 19ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala//#define LOG_NDEBUG 0 20ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala 21a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray#include <netinet/in.h> 22a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray 2373bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala#include <binder/MemoryBase.h> 2473bbd1f1c493835f191ea2b0b72439292496b40aEino-Ville Talvala#include <binder/MemoryHeapBase.h> 25ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala#include <utils/Log.h> 26ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala#include <utils/Trace.h> 27ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala 28da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala#include "JpegProcessor.h" 29ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala#include <gui/SurfaceTextureClient.h> 30ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala#include "../Camera2Device.h" 31ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala#include "../Camera2Client.h" 32ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala 33ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala 34ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvalanamespace android { 35ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvalanamespace camera2 { 36ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala 37da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville TalvalaJpegProcessor::JpegProcessor( 38da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala wp<Camera2Client> client, 39da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala wp<CaptureSequencer> sequencer): 40ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala Thread(false), 41ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala mClient(client), 42da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvala mSequencer(sequencer), 43ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala mCaptureAvailable(false), 44ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala mCaptureStreamId(NO_STREAM) { 45ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala} 46ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala 47da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville TalvalaJpegProcessor::~JpegProcessor() { 48ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala ALOGV("%s: Exit", __FUNCTION__); 49cf70d3469332445dc3ffd09729da3538612b1bb2Eino-Ville Talvala deleteStream(); 50ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala} 51ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala 52da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvalavoid JpegProcessor::onFrameAvailable() { 53ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala Mutex::Autolock l(mInputMutex); 54ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala if (!mCaptureAvailable) { 55ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala mCaptureAvailable = true; 56ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala mCaptureAvailableSignal.signal(); 57ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala } 58ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala} 59ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala 60da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvalastatus_t JpegProcessor::updateStream(const Parameters ¶ms) { 61ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala ATRACE_CALL(); 62ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala ALOGV("%s", __FUNCTION__); 63ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala status_t res; 64ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala 65ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala Mutex::Autolock l(mInputMutex); 66ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala 67ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala sp<Camera2Client> client = mClient.promote(); 68ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala if (client == 0) return OK; 69ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala sp<Camera2Device> device = client->getCameraDevice(); 70ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala 71ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala // Find out buffer size for JPEG 72ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala camera_metadata_ro_entry_t maxJpegSize = 73ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala params.staticInfo(ANDROID_JPEG_MAX_SIZE); 74ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala if (maxJpegSize.count == 0) { 75ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala ALOGE("%s: Camera %d: Can't find ANDROID_JPEG_MAX_SIZE!", 76ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala __FUNCTION__, client->getCameraId()); 77ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala return INVALID_OPERATION; 78ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala } 79ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala 80ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala if (mCaptureConsumer == 0) { 81ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala // Create CPU buffer queue endpoint 82ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala mCaptureConsumer = new CpuConsumer(1); 83ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala mCaptureConsumer->setFrameAvailableListener(this); 84ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala mCaptureConsumer->setName(String8("Camera2Client::CaptureConsumer")); 85ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala mCaptureWindow = new SurfaceTextureClient( 86ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala mCaptureConsumer->getProducerInterface()); 87ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala // Create memory for API consumption 88a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray mCaptureHeap = new MemoryHeapBase(maxJpegSize.data.i32[0], 0, 89ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala "Camera2Client::CaptureHeap"); 90a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray if (mCaptureHeap->getSize() == 0) { 91ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala ALOGE("%s: Camera %d: Unable to allocate memory for capture", 92ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala __FUNCTION__, client->getCameraId()); 93ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala return NO_MEMORY; 94ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala } 95ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala } 96ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala 97ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala if (mCaptureStreamId != NO_STREAM) { 98ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala // Check if stream parameters have to change 99ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala uint32_t currentWidth, currentHeight; 100ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala res = device->getStreamInfo(mCaptureStreamId, 101ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala ¤tWidth, ¤tHeight, 0); 102ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala if (res != OK) { 103ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala ALOGE("%s: Camera %d: Error querying capture output stream info: " 104ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala "%s (%d)", __FUNCTION__, 105ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala client->getCameraId(), strerror(-res), res); 106ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala return res; 107ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala } 108ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala if (currentWidth != (uint32_t)params.pictureWidth || 109ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala currentHeight != (uint32_t)params.pictureHeight) { 110ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin ALOGV("%s: Camera %d: Deleting stream %d since the buffer dimensions changed", 111ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin __FUNCTION__, client->getCameraId(), mCaptureStreamId); 112ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala res = device->deleteStream(mCaptureStreamId); 113ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala if (res != OK) { 114ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala ALOGE("%s: Camera %d: Unable to delete old output stream " 115ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala "for capture: %s (%d)", __FUNCTION__, 116ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala client->getCameraId(), strerror(-res), res); 117ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala return res; 118ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala } 119ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala mCaptureStreamId = NO_STREAM; 120ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala } 121ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala } 122ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala 123ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala if (mCaptureStreamId == NO_STREAM) { 124ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala // Create stream for HAL production 125ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala res = device->createStream(mCaptureWindow, 126ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala params.pictureWidth, params.pictureHeight, 127ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala HAL_PIXEL_FORMAT_BLOB, maxJpegSize.data.i32[0], 128ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala &mCaptureStreamId); 129ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala if (res != OK) { 130ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala ALOGE("%s: Camera %d: Can't create output stream for capture: " 131ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala "%s (%d)", __FUNCTION__, client->getCameraId(), 132ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala strerror(-res), res); 133ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala return res; 134ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala } 135ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala 136ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala } 137ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala return OK; 138ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala} 139ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala 140da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvalastatus_t JpegProcessor::deleteStream() { 141ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala ATRACE_CALL(); 142ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala status_t res; 143ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala 144ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala Mutex::Autolock l(mInputMutex); 145ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala 146ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala if (mCaptureStreamId != NO_STREAM) { 147ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala sp<Camera2Client> client = mClient.promote(); 148ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala if (client == 0) return OK; 149ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala sp<Camera2Device> device = client->getCameraDevice(); 150ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala 151ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala device->deleteStream(mCaptureStreamId); 152cf70d3469332445dc3ffd09729da3538612b1bb2Eino-Ville Talvala 153cf70d3469332445dc3ffd09729da3538612b1bb2Eino-Ville Talvala mCaptureHeap.clear(); 154cf70d3469332445dc3ffd09729da3538612b1bb2Eino-Ville Talvala mCaptureWindow.clear(); 155cf70d3469332445dc3ffd09729da3538612b1bb2Eino-Ville Talvala mCaptureConsumer.clear(); 156cf70d3469332445dc3ffd09729da3538612b1bb2Eino-Ville Talvala 157ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala mCaptureStreamId = NO_STREAM; 158ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala } 159ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala return OK; 160ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala} 161ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala 162da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvalaint JpegProcessor::getStreamId() const { 163ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala Mutex::Autolock l(mInputMutex); 164ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala return mCaptureStreamId; 165ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala} 166ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala 167da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvalavoid JpegProcessor::dump(int fd, const Vector<String16>& args) const { 168ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala} 169ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala 170da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvalabool JpegProcessor::threadLoop() { 171ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala status_t res; 172ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala 173ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala { 174ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala Mutex::Autolock l(mInputMutex); 175ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala while (!mCaptureAvailable) { 176ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala res = mCaptureAvailableSignal.waitRelative(mInputMutex, 177ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala kWaitDuration); 178ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala if (res == TIMED_OUT) return true; 179ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala } 180ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala mCaptureAvailable = false; 181ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala } 182ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala 183ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala do { 184ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala sp<Camera2Client> client = mClient.promote(); 185ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala if (client == 0) return false; 186ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala res = processNewCapture(client); 187ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala } while (res == OK); 188ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala 189ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala return true; 190ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala} 191ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala 192da6665cbd06ca58d3357c3002b7366d13e23f152Eino-Ville Talvalastatus_t JpegProcessor::processNewCapture(sp<Camera2Client> &client) { 193ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala ATRACE_CALL(); 194ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala status_t res; 195ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala sp<Camera2Heap> captureHeap; 196ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala 197ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala CpuConsumer::LockedBuffer imgBuffer; 198ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala 199ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala res = mCaptureConsumer->lockNextBuffer(&imgBuffer); 200ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala if (res != OK) { 201ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala if (res != BAD_VALUE) { 202ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala ALOGE("%s: Camera %d: Error receiving still image buffer: " 203ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala "%s (%d)", __FUNCTION__, 204ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala client->getCameraId(), strerror(-res), res); 205ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala } 206ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala return res; 207ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala } 208ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala 209ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala ALOGV("%s: Camera %d: Still capture available", __FUNCTION__, 210ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala client->getCameraId()); 211ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala 212ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala // TODO: Signal errors here upstream 213ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala { 214ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala SharedParameters::Lock l(client->getParameters()); 215ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala 216ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala switch (l.mParameters.state) { 217ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala case Parameters::STILL_CAPTURE: 218ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala case Parameters::VIDEO_SNAPSHOT: 219ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala break; 220ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala default: 221ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala ALOGE("%s: Camera %d: Still image produced unexpectedly " 222ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala "in state %s!", 223ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala __FUNCTION__, client->getCameraId(), 224ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala Parameters::getStateName(l.mParameters.state)); 225ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala mCaptureConsumer->unlockBuffer(imgBuffer); 226ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala return BAD_VALUE; 227ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala } 228ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala } 229ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala 230ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala if (imgBuffer.format != HAL_PIXEL_FORMAT_BLOB) { 231ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala ALOGE("%s: Camera %d: Unexpected format for still image: " 232ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala "%x, expected %x", __FUNCTION__, client->getCameraId(), 233ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala imgBuffer.format, 234ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala HAL_PIXEL_FORMAT_BLOB); 235ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala mCaptureConsumer->unlockBuffer(imgBuffer); 236ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala return OK; 237ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala } 238ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala 239a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray // Find size of JPEG image 2400fa1e760f7093d025c977e5813e8d3a04c863ce3Alex Ray size_t jpegSize = findJpegSize(imgBuffer.data, imgBuffer.width); 241eb8a42b934f20a15f40d656e2bc90f384f1ccb10Alex Ray if (jpegSize == 0) { // failed to find size, default to whole buffer 242eb8a42b934f20a15f40d656e2bc90f384f1ccb10Alex Ray jpegSize = imgBuffer.width; 243eb8a42b934f20a15f40d656e2bc90f384f1ccb10Alex Ray } 244a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray size_t heapSize = mCaptureHeap->getSize(); 245a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray if (jpegSize > heapSize) { 246a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray ALOGW("%s: JPEG image is larger than expected, truncating " 247a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray "(got %d, expected at most %d bytes)", 248a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray __FUNCTION__, jpegSize, heapSize); 249a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray jpegSize = heapSize; 250a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray } 251a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray 252ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala // TODO: Optimize this to avoid memcopy 253a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray sp<MemoryBase> captureBuffer = new MemoryBase(mCaptureHeap, 0, jpegSize); 254a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray void* captureMemory = mCaptureHeap->getBase(); 2550fa1e760f7093d025c977e5813e8d3a04c863ce3Alex Ray memcpy(captureMemory, imgBuffer.data, jpegSize); 256ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala 257ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala mCaptureConsumer->unlockBuffer(imgBuffer); 258ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala 259fe580e57081885dd6059e0d407a6cd96a1be7e51Eino-Ville Talvala sp<CaptureSequencer> sequencer = mSequencer.promote(); 260fe580e57081885dd6059e0d407a6cd96a1be7e51Eino-Ville Talvala if (sequencer != 0) { 261a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray sequencer->onCaptureAvailable(imgBuffer.timestamp, captureBuffer); 262ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala } 263fe580e57081885dd6059e0d407a6cd96a1be7e51Eino-Ville Talvala 264ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala return OK; 265ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala} 266ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala 267a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray/* 268a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray * JPEG FILE FORMAT OVERVIEW. 269a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray * http://www.jpeg.org/public/jfif.pdf 270a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray * (JPEG is the image compression algorithm, actual file format is called JFIF) 271a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray * 272a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray * "Markers" are 2-byte patterns used to distinguish parts of JFIF files. The 273a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray * first byte is always 0xFF, and the second byte is between 0x01 and 0xFE 274a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray * (inclusive). Because every marker begins with the same byte, they are 275a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray * referred to by the second byte's value. 276a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray * 277a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray * JFIF files all begin with the Start of Image (SOI) marker, which is 0xD8. 278a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray * Following it, "segment" sections begin with other markers, followed by a 279a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray * 2-byte length (in network byte order), then the segment data. 280a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray * 281a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray * For our purposes we will ignore the data, and just use the length to skip to 282a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray * the next segment. This is necessary because the data inside segments are 283a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray * allowed to contain the End of Image marker (0xFF 0xD9), preventing us from 284a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray * naievely scanning until the end. 285a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray * 286a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray * After all the segments are processed, the jpeg compressed image stream begins. 287a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray * This can be considered an opaque format with one requirement: all 0xFF bytes 288a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray * in this stream must be followed with a 0x00 byte. This prevents any of the 289a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray * image data to be interpreted as a segment. The only exception to this is at 290a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray * the end of the image stream there is an End of Image (EOI) marker, which is 291a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray * 0xFF followed by a non-zero (0xD9) byte. 292a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray */ 293a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray 294a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Rayconst uint8_t MARK = 0xFF; // First byte of marker 295a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Rayconst uint8_t SOI = 0xD8; // Start of Image 296a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Rayconst uint8_t EOI = 0xD9; // End of Image 297a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Rayconst size_t MARKER_LENGTH = 2; // length of a marker 298a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray 299a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray#pragma pack(push) 300a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray#pragma pack(1) 301a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Raytypedef struct segment { 302a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray uint8_t marker[MARKER_LENGTH]; 303a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray uint16_t length; 304a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray} segment_t; 305a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray#pragma pack(pop) 306a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray 307a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray/* HELPER FUNCTIONS */ 308a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray 309a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray// check for Start of Image marker 310a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Raybool checkJpegStart(uint8_t* buf) { 311a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray return buf[0] == MARK && buf[1] == SOI; 312a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray} 313a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray// check for End of Image marker 314a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Raybool checkJpegEnd(uint8_t *buf) { 315a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray return buf[0] == MARK && buf[1] == EOI; 316a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray} 317a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray// check for arbitrary marker, returns marker type (second byte) 318a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray// returns 0 if no marker found. Note: 0x00 is not a valid marker type 319a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Rayuint8_t checkJpegMarker(uint8_t *buf) { 320a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray if (buf[0] == MARK && buf[1] > 0 && buf[1] < 0xFF) { 321a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray return buf[1]; 322a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray } 323a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray return 0; 324a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray} 325a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray 326a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray// Return the size of the JPEG, 0 indicates failure 3270fa1e760f7093d025c977e5813e8d3a04c863ce3Alex Raysize_t JpegProcessor::findJpegSize(uint8_t* jpegBuffer, size_t maxSize) { 328a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray size_t size; 329a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray 3300fa1e760f7093d025c977e5813e8d3a04c863ce3Alex Ray // First check for JPEG transport header at the end of the buffer 3310fa1e760f7093d025c977e5813e8d3a04c863ce3Alex Ray uint8_t *header = jpegBuffer + (maxSize - sizeof(struct camera2_jpeg_blob)); 3320fa1e760f7093d025c977e5813e8d3a04c863ce3Alex Ray struct camera2_jpeg_blob *blob = (struct camera2_jpeg_blob*)(header); 333a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray if (blob->jpeg_blob_id == CAMERA2_JPEG_BLOB_ID) { 334a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray size = blob->jpeg_size; 335a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray if (size > 0 && size <= maxSize - sizeof(struct camera2_jpeg_blob)) { 336a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray // Verify SOI and EOI markers 337a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray size_t offset = size - MARKER_LENGTH; 3380fa1e760f7093d025c977e5813e8d3a04c863ce3Alex Ray uint8_t *end = jpegBuffer + offset; 3390fa1e760f7093d025c977e5813e8d3a04c863ce3Alex Ray if (checkJpegStart(jpegBuffer) && checkJpegEnd(end)) { 340a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray ALOGV("Found JPEG transport header, img size %d", size); 341a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray return size; 342a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray } else { 343a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray ALOGW("Found JPEG transport header with bad Image Start/End"); 344a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray } 345a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray } else { 346a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray ALOGW("Found JPEG transport header with bad size %d", size); 347a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray } 348a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray } 349a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray 3500fa1e760f7093d025c977e5813e8d3a04c863ce3Alex Ray // Check Start of Image 3510fa1e760f7093d025c977e5813e8d3a04c863ce3Alex Ray if ( !checkJpegStart(jpegBuffer) ) { 352a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray ALOGE("Could not find start of JPEG marker"); 353a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray return 0; 354a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray } 355a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray 356a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray // Read JFIF segment markers, skip over segment data 357a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray size = 0; 358a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray while (size <= maxSize - MARKER_LENGTH) { 3590fa1e760f7093d025c977e5813e8d3a04c863ce3Alex Ray segment_t *segment = (segment_t*)(jpegBuffer + size); 360a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray uint8_t type = checkJpegMarker(segment->marker); 361a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray if (type == 0) { // invalid marker, no more segments, begin JPEG data 362a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray ALOGV("JPEG stream found beginning at offset %d", size); 363a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray break; 364a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray } 365a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray if (type == EOI || size > maxSize - sizeof(segment_t)) { 366a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray ALOGE("Got premature End before JPEG data, offset %d", size); 367a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray return 0; 368a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray } 369a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray size_t length = ntohs(segment->length); 370a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray ALOGV("JFIF Segment, type %x length %x", type, length); 371a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray size += length + MARKER_LENGTH; 372a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray } 373a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray 374a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray // Find End of Image 375a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray // Scan JPEG buffer until End of Image (EOI) 376a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray bool foundEnd = false; 3770fa1e760f7093d025c977e5813e8d3a04c863ce3Alex Ray for (size; size <= maxSize - MARKER_LENGTH; size++) { 3780fa1e760f7093d025c977e5813e8d3a04c863ce3Alex Ray if ( checkJpegEnd(jpegBuffer + size) ) { 379a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray foundEnd = true; 380a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray size += MARKER_LENGTH; 381a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray break; 382a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray } 383a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray } 384a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray if (!foundEnd) { 385a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray ALOGE("Could not find end of JPEG marker"); 386a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray return 0; 387a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray } 388a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray 389a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray if (size > maxSize) { 390a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray ALOGW("JPEG size %d too large, reducing to maxSize %d", size, maxSize); 391a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray size = maxSize; 392a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray } 3930fa1e760f7093d025c977e5813e8d3a04c863ce3Alex Ray ALOGV("Final JPEG size %d", size); 394a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray return size; 395a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray} 396a6b4c40e70eafc5aba16163999de6d3e26667b89Alex Ray 397ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala}; // namespace camera2 398ea0d51b5ed0b474433b02414f9133b835f972569Eino-Ville Talvala}; // namespace android 399