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