• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 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 #include <inttypes.h>
18 
19 //#define LOG_NDEBUG 0
20 #define LOG_TAG "NdkImage"
21 
22 #include "NdkImagePriv.h"
23 #include "NdkImageReaderPriv.h"
24 
25 #include <android_media_Utils.h>
26 #include <private/android/AHardwareBufferHelpers.h>
27 #include <ui/PublicFormat.h>
28 #include <utils/Log.h>
29 
30 using namespace android;
31 
32 #define ALIGN(x, mask) ( ((x) + (mask) - 1) & ~((mask) - 1) )
33 
AImage(AImageReader * reader,int32_t format,uint64_t usage,BufferItem * buffer,int64_t timestamp,int32_t width,int32_t height,int32_t numPlanes)34 AImage::AImage(AImageReader* reader, int32_t format, uint64_t usage, BufferItem* buffer,
35         int64_t timestamp, int32_t width, int32_t height, int32_t numPlanes) :
36         mReader(reader), mFormat(format), mUsage(usage), mBuffer(buffer), mLockedBuffer(nullptr),
37         mTimestamp(timestamp), mWidth(width), mHeight(height), mNumPlanes(numPlanes) {
38     PublicFormat publicFormat = static_cast<PublicFormat>(format);
39     mHalDataSpace = mapPublicFormatToHalDataspace(publicFormat);
40     LOG_FATAL_IF(reader == nullptr, "AImageReader shouldn't be null while creating AImage");
41 }
42 
~AImage()43 AImage::~AImage() {
44     Mutex::Autolock _l(mLock);
45     if (!mIsClosed) {
46         LOG_ALWAYS_FATAL(
47                 "Error: AImage %p is deleted before returning buffer to AImageReader!", this);
48     }
49 }
50 
51 bool
isClosed() const52 AImage::isClosed() const {
53     Mutex::Autolock _l(mLock);
54     return mIsClosed;
55 }
56 
57 void
close(int releaseFenceFd)58 AImage::close(int releaseFenceFd) {
59     Mutex::Autolock _l(mLock);
60     if (mIsClosed) {
61         return;
62     }
63     if (mReader->mIsOpen) {
64         mReader->releaseImageLocked(this, releaseFenceFd);
65     }
66     // Should have been set to nullptr in releaseImageLocked
67     // Set to nullptr here for extra safety only
68     mBuffer = nullptr;
69     mLockedBuffer = nullptr;
70     mIsClosed = true;
71 }
72 
73 void
free()74 AImage::free() {
75     if (!isClosed()) {
76         ALOGE("Cannot free AImage before close!");
77         return;
78     }
79     delete this;
80 }
81 
82 void
lockReader() const83 AImage::lockReader() const {
84     mReader->mLock.lock();
85 }
86 
87 void
unlockReader() const88 AImage::unlockReader() const {
89     mReader->mLock.unlock();
90 }
91 
92 media_status_t
getWidth(int32_t * width) const93 AImage::getWidth(int32_t* width) const {
94     if (width == nullptr) {
95         return AMEDIA_ERROR_INVALID_PARAMETER;
96     }
97     *width = -1;
98     if (isClosed()) {
99         ALOGE("%s: image %p has been closed!", __FUNCTION__, this);
100         return AMEDIA_ERROR_INVALID_OBJECT;
101     }
102     *width = mWidth;
103     return AMEDIA_OK;
104 }
105 
106 media_status_t
getHeight(int32_t * height) const107 AImage::getHeight(int32_t* height) const {
108     if (height == nullptr) {
109         return AMEDIA_ERROR_INVALID_PARAMETER;
110     }
111     *height = -1;
112     if (isClosed()) {
113         ALOGE("%s: image %p has been closed!", __FUNCTION__, this);
114         return AMEDIA_ERROR_INVALID_OBJECT;
115     }
116     *height = mHeight;
117     return AMEDIA_OK;
118 }
119 
120 media_status_t
getFormat(int32_t * format) const121 AImage::getFormat(int32_t* format) const {
122     if (format == nullptr) {
123         return AMEDIA_ERROR_INVALID_PARAMETER;
124     }
125     *format = -1;
126     if (isClosed()) {
127         ALOGE("%s: image %p has been closed!", __FUNCTION__, this);
128         return AMEDIA_ERROR_INVALID_OBJECT;
129     }
130     *format = mFormat;
131     return AMEDIA_OK;
132 }
133 
134 media_status_t
getNumPlanes(int32_t * numPlanes) const135 AImage::getNumPlanes(int32_t* numPlanes) const {
136     if (numPlanes == nullptr) {
137         return AMEDIA_ERROR_INVALID_PARAMETER;
138     }
139     *numPlanes = -1;
140     if (isClosed()) {
141         ALOGE("%s: image %p has been closed!", __FUNCTION__, this);
142         return AMEDIA_ERROR_INVALID_OBJECT;
143     }
144     *numPlanes = mNumPlanes;
145     return AMEDIA_OK;
146 }
147 
148 media_status_t
getTimestamp(int64_t * timestamp) const149 AImage::getTimestamp(int64_t* timestamp) const {
150     if (timestamp == nullptr) {
151         return AMEDIA_ERROR_INVALID_PARAMETER;
152     }
153     *timestamp = -1;
154     if (isClosed()) {
155         ALOGE("%s: image %p has been closed!", __FUNCTION__, this);
156         return AMEDIA_ERROR_INVALID_OBJECT;
157     }
158     *timestamp = mTimestamp;
159     return AMEDIA_OK;
160 }
161 
162 media_status_t
getDataSpace(android_dataspace * dataSpace) const163 AImage::getDataSpace(android_dataspace* dataSpace) const {
164     if (dataSpace == nullptr) {
165         return AMEDIA_ERROR_INVALID_PARAMETER;
166     }
167     *dataSpace = static_cast<android_dataspace>(-1);
168     if (isClosed()) {
169         ALOGE("%s: image %p has been closed!", __FUNCTION__, this);
170         return AMEDIA_ERROR_INVALID_OBJECT;
171     }
172     *dataSpace = mHalDataSpace;
173     return AMEDIA_OK;
174 }
175 
lockImage()176 media_status_t AImage::lockImage() {
177     if (mBuffer == nullptr || mBuffer->mGraphicBuffer == nullptr) {
178         LOG_ALWAYS_FATAL("%s: AImage %p has no buffer.", __FUNCTION__, this);
179         return AMEDIA_ERROR_INVALID_OBJECT;
180     }
181 
182     if ((mUsage & AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN) == 0) {
183         ALOGE("%s: AImage %p does not have any software read usage bits set, usage=%" PRIu64 "",
184               __FUNCTION__, this, mUsage);
185         return AMEDIA_IMGREADER_CANNOT_LOCK_IMAGE;
186     }
187 
188     if (mLockedBuffer != nullptr) {
189         // Return immediately if the image has already been locked.
190         return AMEDIA_OK;
191     }
192 
193     auto lockedBuffer = std::make_unique<CpuConsumer::LockedBuffer>();
194 
195     uint64_t grallocUsage = AHardwareBuffer_convertToGrallocUsageBits(mUsage);
196 
197     status_t ret =
198             lockImageFromBuffer(mBuffer, grallocUsage, mBuffer->mFence->dup(), lockedBuffer.get());
199     if (ret != OK) {
200         ALOGE("%s: AImage %p failed to lock, error=%d", __FUNCTION__, this, ret);
201         return AMEDIA_IMGREADER_CANNOT_LOCK_IMAGE;
202     }
203 
204     ALOGV("%s: Successfully locked the image %p.", __FUNCTION__, this);
205     mLockedBuffer = std::move(lockedBuffer);
206 
207     return AMEDIA_OK;
208 }
209 
unlockImageIfLocked(int * fenceFd)210 media_status_t AImage::unlockImageIfLocked(int* fenceFd) {
211     if (fenceFd == nullptr) {
212         LOG_ALWAYS_FATAL("%s: fenceFd cannot be null.", __FUNCTION__);
213         return AMEDIA_ERROR_INVALID_PARAMETER;
214     }
215 
216     if (mBuffer == nullptr || mBuffer->mGraphicBuffer == nullptr) {
217         LOG_ALWAYS_FATAL("%s: AImage %p has no buffer.", __FUNCTION__, this);
218         return AMEDIA_ERROR_INVALID_OBJECT;
219     }
220 
221     if (mLockedBuffer == nullptr) {
222         // This image hasn't been locked yet, no need to unlock.
223         *fenceFd = -1;
224         return AMEDIA_OK;
225     }
226 
227     // No fence by default.
228     int releaseFenceFd = -1;
229     status_t res = mBuffer->mGraphicBuffer->unlockAsync(&releaseFenceFd);
230     if (res != OK) {
231         ALOGE("%s unlock buffer failed on iamge %p.", __FUNCTION__, this);
232         *fenceFd = -1;
233         return AMEDIA_IMGREADER_CANNOT_UNLOCK_IMAGE;
234     }
235 
236     *fenceFd = releaseFenceFd;
237     return AMEDIA_OK;
238 }
239 
240 media_status_t
getPlanePixelStride(int planeIdx,int32_t * pixelStride) const241 AImage::getPlanePixelStride(int planeIdx, /*out*/int32_t* pixelStride) const {
242     if (mLockedBuffer == nullptr) {
243         ALOGE("%s: buffer not locked.", __FUNCTION__);
244         return AMEDIA_IMGREADER_IMAGE_NOT_LOCKED;
245     }
246 
247     if (planeIdx < 0 || planeIdx >= mNumPlanes) {
248         ALOGE("Error: planeIdx %d out of bound [0,%d]",
249                 planeIdx, mNumPlanes - 1);
250         return AMEDIA_ERROR_INVALID_PARAMETER;
251     }
252     if (pixelStride == nullptr) {
253         return AMEDIA_ERROR_INVALID_PARAMETER;
254     }
255     if (isClosed()) {
256         ALOGE("%s: image %p has been closed!", __FUNCTION__, this);
257         return AMEDIA_ERROR_INVALID_OBJECT;
258     }
259     int32_t fmt = mLockedBuffer->flexFormat;
260     switch (fmt) {
261         case HAL_PIXEL_FORMAT_YCbCr_420_888:
262             *pixelStride = (planeIdx == 0) ? 1 : mLockedBuffer->chromaStep;
263             return AMEDIA_OK;
264         case HAL_PIXEL_FORMAT_YCrCb_420_SP:
265             *pixelStride = (planeIdx == 0) ? 1 : 2;
266             return AMEDIA_OK;
267         case HAL_PIXEL_FORMAT_YCBCR_P010:
268             if (mLockedBuffer->dataCb && mLockedBuffer->dataCr) {
269                 *pixelStride = (planeIdx == 0) ? 2 : mLockedBuffer->chromaStep;
270             } else {
271                 *pixelStride = (planeIdx == 0) ? 2 : 4;
272             }
273             return AMEDIA_OK;
274         case HAL_PIXEL_FORMAT_Y8:
275             *pixelStride = 1;
276             return AMEDIA_OK;
277         case HAL_PIXEL_FORMAT_YV12:
278             *pixelStride = 1;
279             return AMEDIA_OK;
280         case HAL_PIXEL_FORMAT_Y16:
281         case HAL_PIXEL_FORMAT_RAW16:
282         case HAL_PIXEL_FORMAT_RGB_565:
283             // Single plane 16bpp data.
284             *pixelStride = 2;
285             return AMEDIA_OK;
286         case HAL_PIXEL_FORMAT_RGBA_8888:
287         case HAL_PIXEL_FORMAT_RGBX_8888:
288             *pixelStride = 4;
289             return AMEDIA_OK;
290         case HAL_PIXEL_FORMAT_RGB_888:
291             // Single plane, 24bpp.
292             *pixelStride = 3;
293             return AMEDIA_OK;
294         case HAL_PIXEL_FORMAT_BLOB:
295         case HAL_PIXEL_FORMAT_RAW10:
296         case HAL_PIXEL_FORMAT_RAW12:
297         case HAL_PIXEL_FORMAT_RAW_OPAQUE:
298             // Blob is used for JPEG data, RAW10 and RAW12 is used for 10-bit and 12-bit raw data,
299             // those are single plane data without pixel stride defined
300             return AMEDIA_ERROR_UNSUPPORTED;
301         default:
302             ALOGE("Pixel format: 0x%x is unsupported", fmt);
303             return AMEDIA_ERROR_UNSUPPORTED;
304     }
305 }
306 
307 media_status_t
getPlaneRowStride(int planeIdx,int32_t * rowStride) const308 AImage::getPlaneRowStride(int planeIdx, /*out*/int32_t* rowStride) const {
309     if (mLockedBuffer == nullptr) {
310         ALOGE("%s: buffer not locked.", __FUNCTION__);
311         return AMEDIA_IMGREADER_IMAGE_NOT_LOCKED;
312     }
313 
314     if (planeIdx < 0 || planeIdx >= mNumPlanes) {
315         ALOGE("Error: planeIdx %d out of bound [0,%d]",
316                 planeIdx, mNumPlanes - 1);
317         return AMEDIA_ERROR_INVALID_PARAMETER;
318     }
319     if (rowStride == nullptr) {
320         return AMEDIA_ERROR_INVALID_PARAMETER;
321     }
322     if (isClosed()) {
323         ALOGE("%s: image %p has been closed!", __FUNCTION__, this);
324         return AMEDIA_ERROR_INVALID_OBJECT;
325     }
326     int32_t fmt = mLockedBuffer->flexFormat;
327     switch (fmt) {
328         case HAL_PIXEL_FORMAT_YCbCr_420_888:
329             *rowStride = (planeIdx == 0) ? mLockedBuffer->stride
330                                          : mLockedBuffer->chromaStride;
331             return AMEDIA_OK;
332         case HAL_PIXEL_FORMAT_YCrCb_420_SP:
333             *rowStride = mLockedBuffer->width;
334             return AMEDIA_OK;
335         case HAL_PIXEL_FORMAT_YV12:
336             if (mLockedBuffer->stride % 16) {
337                 ALOGE("Stride %d is not 16 pixel aligned!", mLockedBuffer->stride);
338                 return AMEDIA_ERROR_UNKNOWN;
339             }
340             *rowStride = (planeIdx == 0) ? mLockedBuffer->stride
341                                          : ALIGN(mLockedBuffer->stride / 2, 16);
342             return AMEDIA_OK;
343         case HAL_PIXEL_FORMAT_YCBCR_P010:
344             if (mLockedBuffer->dataCb && mLockedBuffer->dataCr) {
345                 *rowStride = (planeIdx == 0) ?  mLockedBuffer->stride : mLockedBuffer->chromaStride;
346             } else {
347                 *rowStride = mLockedBuffer->stride * 2;
348             }
349             return AMEDIA_OK;
350         case HAL_PIXEL_FORMAT_RAW10:
351         case HAL_PIXEL_FORMAT_RAW12:
352             // RAW10 and RAW12 are used for 10-bit and 12-bit raw data, they are single plane
353             *rowStride = mLockedBuffer->stride;
354             return AMEDIA_OK;
355         case HAL_PIXEL_FORMAT_Y8:
356             if (mLockedBuffer->stride % 16) {
357                 ALOGE("Stride %d is not 16 pixel aligned!",
358                       mLockedBuffer->stride);
359                 return AMEDIA_ERROR_UNKNOWN;
360             }
361             *rowStride = mLockedBuffer->stride;
362             return AMEDIA_OK;
363         case HAL_PIXEL_FORMAT_Y16:
364         case HAL_PIXEL_FORMAT_RAW16:
365             // In native side, strides are specified in pixels, not in bytes.
366             // Single plane 16bpp bayer data. even width/height,
367             // row stride multiple of 16 pixels (32 bytes)
368             if (mLockedBuffer->stride % 16) {
369                 ALOGE("Stride %d is not 16 pixel aligned!",
370                       mLockedBuffer->stride);
371                 return AMEDIA_ERROR_UNKNOWN;
372             }
373             *rowStride = mLockedBuffer->stride * 2;
374             return AMEDIA_OK;
375         case HAL_PIXEL_FORMAT_RGB_565:
376             *rowStride = mLockedBuffer->stride * 2;
377             return AMEDIA_OK;
378         case HAL_PIXEL_FORMAT_RGBA_8888:
379         case HAL_PIXEL_FORMAT_RGBX_8888:
380             *rowStride = mLockedBuffer->stride * 4;
381             return AMEDIA_OK;
382         case HAL_PIXEL_FORMAT_RGB_888:
383             // Single plane, 24bpp.
384             *rowStride = mLockedBuffer->stride * 3;
385             return AMEDIA_OK;
386         case HAL_PIXEL_FORMAT_BLOB:
387         case HAL_PIXEL_FORMAT_RAW_OPAQUE:
388             // Blob is used for JPEG/Raw opaque data. It is single plane and has 0 row stride and
389             // no row stride defined
390             return AMEDIA_ERROR_UNSUPPORTED;
391         default:
392             ALOGE("%s Pixel format: 0x%x is unsupported", __FUNCTION__, fmt);
393           return AMEDIA_ERROR_UNSUPPORTED;
394     }
395 }
396 
397 uint32_t
getJpegSize() const398 AImage::getJpegSize() const {
399     if (mLockedBuffer == nullptr) {
400         LOG_ALWAYS_FATAL("Error: buffer is null");
401     }
402 
403     uint32_t size = 0;
404     uint32_t width = mLockedBuffer->width;
405     uint8_t* jpegBuffer = mLockedBuffer->data;
406 
407     // First check for JPEG transport header at the end of the buffer
408     uint8_t* header = jpegBuffer + (width - sizeof(struct camera3_jpeg_blob_v2));
409     struct camera3_jpeg_blob_v2* blob = (struct camera3_jpeg_blob_v2*)(header);
410     if (blob->jpeg_blob_id == CAMERA3_JPEG_BLOB_ID) {
411         size = blob->jpeg_size;
412         ALOGV("%s: Jpeg size = %d", __FUNCTION__, size);
413     }
414 
415     // failed to find size, default to whole buffer
416     if (size == 0) {
417         /*
418          * This is a problem because not including the JPEG header
419          * means that in certain rare situations a regular JPEG blob
420          * will be misidentified as having a header, in which case
421          * we will get a garbage size value.
422          */
423         ALOGW("%s: No JPEG header detected, defaulting to size=width=%d",
424                 __FUNCTION__, width);
425         size = width;
426     }
427 
428     return size;
429 }
430 
431 media_status_t
getPlaneData(int planeIdx,uint8_t ** data,int * dataLength) const432 AImage::getPlaneData(int planeIdx,/*out*/uint8_t** data, /*out*/int* dataLength) const {
433     if (mLockedBuffer == nullptr) {
434         ALOGE("%s: buffer not locked.", __FUNCTION__);
435         return AMEDIA_IMGREADER_IMAGE_NOT_LOCKED;
436     }
437 
438     if (planeIdx < 0 || planeIdx >= mNumPlanes) {
439         ALOGE("Error: planeIdx %d out of bound [0,%d]",
440                 planeIdx, mNumPlanes - 1);
441         return AMEDIA_ERROR_INVALID_PARAMETER;
442     }
443     if (data == nullptr || dataLength == nullptr) {
444         return AMEDIA_ERROR_INVALID_PARAMETER;
445     }
446     if (isClosed()) {
447         ALOGE("%s: image %p has been closed!", __FUNCTION__, this);
448         return AMEDIA_ERROR_INVALID_OBJECT;
449     }
450 
451     uint32_t dataSize, ySize, cSize, cStride;
452     uint8_t* cb = nullptr;
453     uint8_t* cr = nullptr;
454     uint8_t* pData = nullptr;
455     int bytesPerPixel = 0;
456     int32_t fmt = mLockedBuffer->flexFormat;
457 
458     switch (fmt) {
459         case HAL_PIXEL_FORMAT_YCbCr_420_888:
460             pData = (planeIdx == 0) ? mLockedBuffer->data
461                                     : (planeIdx == 1) ? mLockedBuffer->dataCb
462                                                       : mLockedBuffer->dataCr;
463             // only map until last pixel
464             if (planeIdx == 0) {
465                 dataSize = mLockedBuffer->stride * (mLockedBuffer->height - 1) +
466                            mLockedBuffer->width;
467             } else {
468                 dataSize =
469                     mLockedBuffer->chromaStride *
470                         (mLockedBuffer->height / 2 - 1) +
471                     mLockedBuffer->chromaStep * (mLockedBuffer->width / 2 - 1) +
472                     1;
473             }
474             break;
475         // NV21
476         case HAL_PIXEL_FORMAT_YCrCb_420_SP:
477             cr = mLockedBuffer->data +
478                  (mLockedBuffer->stride * mLockedBuffer->height);
479             cb = cr + 1;
480             // only map until last pixel
481             ySize = mLockedBuffer->width * (mLockedBuffer->height - 1) +
482                     mLockedBuffer->width;
483             cSize = mLockedBuffer->width * (mLockedBuffer->height / 2 - 1) +
484                     mLockedBuffer->width - 1;
485             pData = (planeIdx == 0) ? mLockedBuffer->data
486                                     : (planeIdx == 1) ? cb : cr;
487             dataSize = (planeIdx == 0) ? ySize : cSize;
488             break;
489         case HAL_PIXEL_FORMAT_YV12:
490             // Y and C stride need to be 16 pixel aligned.
491             if (mLockedBuffer->stride % 16) {
492                 ALOGE("Stride %d is not 16 pixel aligned!",
493                       mLockedBuffer->stride);
494                 return AMEDIA_ERROR_UNKNOWN;
495             }
496 
497             ySize = mLockedBuffer->stride * mLockedBuffer->height;
498             cStride = ALIGN(mLockedBuffer->stride / 2, 16);
499             cr = mLockedBuffer->data + ySize;
500             cSize = cStride * mLockedBuffer->height / 2;
501             cb = cr + cSize;
502 
503             pData = (planeIdx == 0) ? mLockedBuffer->data
504                                     : (planeIdx == 1) ? cb : cr;
505             dataSize = (planeIdx == 0) ? ySize : cSize;
506             break;
507         case HAL_PIXEL_FORMAT_YCBCR_P010:
508             if (mLockedBuffer->height % 2 != 0) {
509                 ALOGE("YCBCR_P010: height (%d) should be a multiple of 2", mLockedBuffer->height);
510                 return AMEDIA_ERROR_UNKNOWN;
511             }
512 
513             if (mLockedBuffer->width <= 0) {
514                 ALOGE("YCBCR_P010: width (%d) should be a > 0", mLockedBuffer->width);
515                 return AMEDIA_ERROR_UNKNOWN;
516             }
517 
518             if (mLockedBuffer->height <= 0) {
519                 ALOGE("YCBCR_P010: height (%d) should be a > 0", mLockedBuffer->height);
520                 return AMEDIA_ERROR_UNKNOWN;
521             }
522 
523             if (mLockedBuffer->dataCb && mLockedBuffer->dataCr) {
524                 pData = (planeIdx == 0) ?  mLockedBuffer->data :
525                         (planeIdx == 1) ?  mLockedBuffer->dataCb : mLockedBuffer->dataCr;
526                 // only map until last pixel
527                 if (planeIdx == 0) {
528                     cStride = mLockedBuffer->stride;
529                     dataSize = cStride * (mLockedBuffer->height - 1) + mLockedBuffer->width * 2;
530                 } else {
531                     bytesPerPixel = mLockedBuffer->chromaStep;
532                     cStride = mLockedBuffer->chromaStride;
533                     dataSize = cStride * (mLockedBuffer->height / 2 - 1) +
534                             bytesPerPixel * (mLockedBuffer->width / 2);
535                 }
536                 break;
537             }
538 
539             cStride = mLockedBuffer->stride * 2;
540             ySize = cStride * mLockedBuffer->height;
541             cSize = ySize / 2;
542             cb = mLockedBuffer->data + ySize;
543             cr = cb + 2;
544 
545             pData = (planeIdx == 0) ?  mLockedBuffer->data : (planeIdx == 1) ?  cb : cr;
546             dataSize = (planeIdx == 0) ? ySize : cSize;
547             break;
548         case HAL_PIXEL_FORMAT_Y8:
549             // Single plane, 8bpp.
550 
551             pData = mLockedBuffer->data;
552             dataSize = mLockedBuffer->stride * mLockedBuffer->height;
553             break;
554         case HAL_PIXEL_FORMAT_Y16:
555             bytesPerPixel = 2;
556 
557             pData = mLockedBuffer->data;
558             dataSize =
559                 mLockedBuffer->stride * mLockedBuffer->height * bytesPerPixel;
560             break;
561         case HAL_PIXEL_FORMAT_BLOB:
562             // Used for JPEG data, height must be 1, width == size, single plane.
563             if (mLockedBuffer->height != 1) {
564                 ALOGE("Jpeg should have height value one but got %d",
565                       mLockedBuffer->height);
566                 return AMEDIA_ERROR_UNKNOWN;
567             }
568 
569             pData = mLockedBuffer->data;
570             dataSize = getJpegSize();
571             break;
572         case HAL_PIXEL_FORMAT_RAW16:
573             // Single plane 16bpp bayer data.
574             bytesPerPixel = 2;
575             pData = mLockedBuffer->data;
576             dataSize =
577                 mLockedBuffer->stride * mLockedBuffer->height * bytesPerPixel;
578             break;
579         case HAL_PIXEL_FORMAT_RAW_OPAQUE:
580             // Used for RAW_OPAQUE data, height must be 1, width == size, single plane.
581             if (mLockedBuffer->height != 1) {
582                 ALOGE("RAW_OPAQUE should have height value one but got %d",
583                       mLockedBuffer->height);
584                 return AMEDIA_ERROR_UNKNOWN;
585             }
586             pData = mLockedBuffer->data;
587             dataSize = mLockedBuffer->width;
588             break;
589         case HAL_PIXEL_FORMAT_RAW10:
590             // Single plane 10bpp bayer data.
591             if (mLockedBuffer->width % 4) {
592                 ALOGE("Width is not multiple of 4 %d", mLockedBuffer->width);
593                 return AMEDIA_ERROR_UNKNOWN;
594             }
595             if (mLockedBuffer->height % 2) {
596                 ALOGE("Height is not multiple of 2 %d", mLockedBuffer->height);
597                 return AMEDIA_ERROR_UNKNOWN;
598             }
599             if (mLockedBuffer->stride < (mLockedBuffer->width * 10 / 8)) {
600                 ALOGE("stride (%d) should be at least %d",
601                         mLockedBuffer->stride, mLockedBuffer->width * 10 / 8);
602                 return AMEDIA_ERROR_UNKNOWN;
603             }
604             pData = mLockedBuffer->data;
605             dataSize = mLockedBuffer->stride * mLockedBuffer->height;
606             break;
607         case HAL_PIXEL_FORMAT_RAW12:
608             // Single plane 10bpp bayer data.
609             if (mLockedBuffer->width % 4) {
610                 ALOGE("Width is not multiple of 4 %d", mLockedBuffer->width);
611                 return AMEDIA_ERROR_UNKNOWN;
612             }
613             if (mLockedBuffer->height % 2) {
614                 ALOGE("Height is not multiple of 2 %d", mLockedBuffer->height);
615                 return AMEDIA_ERROR_UNKNOWN;
616             }
617             if (mLockedBuffer->stride < (mLockedBuffer->width * 12 / 8)) {
618                 ALOGE("stride (%d) should be at least %d",
619                         mLockedBuffer->stride, mLockedBuffer->width * 12 / 8);
620                 return AMEDIA_ERROR_UNKNOWN;
621             }
622             pData = mLockedBuffer->data;
623             dataSize = mLockedBuffer->stride * mLockedBuffer->height;
624             break;
625         case HAL_PIXEL_FORMAT_RGBA_8888:
626         case HAL_PIXEL_FORMAT_RGBX_8888:
627             // Single plane, 32bpp.
628             bytesPerPixel = 4;
629             pData = mLockedBuffer->data;
630             dataSize =
631                 mLockedBuffer->stride * mLockedBuffer->height * bytesPerPixel;
632             break;
633         case HAL_PIXEL_FORMAT_RGB_565:
634             // Single plane, 16bpp.
635             bytesPerPixel = 2;
636             pData = mLockedBuffer->data;
637             dataSize =
638                 mLockedBuffer->stride * mLockedBuffer->height * bytesPerPixel;
639             break;
640         case HAL_PIXEL_FORMAT_RGB_888:
641             // Single plane, 24bpp.
642             bytesPerPixel = 3;
643             pData = mLockedBuffer->data;
644             dataSize = mLockedBuffer->stride * mLockedBuffer->height * bytesPerPixel;
645             break;
646         default:
647             ALOGE("Pixel format: 0x%x is unsupported", fmt);
648             return AMEDIA_ERROR_UNSUPPORTED;
649     }
650 
651     *data = pData;
652     *dataLength = dataSize;
653     return AMEDIA_OK;
654 }
655 
656 media_status_t
getHardwareBuffer(AHardwareBuffer ** buffer) const657 AImage::getHardwareBuffer(/*out*/AHardwareBuffer** buffer) const {
658     if (mBuffer == nullptr || mBuffer->mGraphicBuffer == nullptr) {
659         ALOGE("%s: AImage %p has no buffer.", __FUNCTION__, this);
660         return AMEDIA_ERROR_INVALID_OBJECT;
661     }
662 
663     // TODO(jwcai) Someone from Android graphics team stating this should just be a static_cast.
664     *buffer = reinterpret_cast<AHardwareBuffer*>(mBuffer->mGraphicBuffer.get());
665     return AMEDIA_OK;
666 }
667 
668 EXPORT
AImage_delete(AImage * image)669 void AImage_delete(AImage* image) {
670     ALOGV("%s", __FUNCTION__);
671     AImage_deleteAsync(image, -1);
672     return;
673 }
674 
675 EXPORT
AImage_deleteAsync(AImage * image,int releaseFenceFd)676 void AImage_deleteAsync(AImage* image, int releaseFenceFd) {
677     ALOGV("%s", __FUNCTION__);
678     if (image != nullptr) {
679         image->lockReader();
680         image->close(releaseFenceFd);
681         image->unlockReader();
682         if (!image->isClosed()) {
683             LOG_ALWAYS_FATAL("Image close failed!");
684         }
685         image->free();
686     }
687     return;
688 }
689 
690 EXPORT
AImage_getWidth(const AImage * image,int32_t * width)691 media_status_t AImage_getWidth(const AImage* image, /*out*/int32_t* width) {
692     ALOGV("%s", __FUNCTION__);
693     if (image == nullptr || width == nullptr) {
694         ALOGE("%s: bad argument. image %p width %p",
695                 __FUNCTION__, image, width);
696         return AMEDIA_ERROR_INVALID_PARAMETER;
697     }
698     return image->getWidth(width);
699 }
700 
701 EXPORT
AImage_getHeight(const AImage * image,int32_t * height)702 media_status_t AImage_getHeight(const AImage* image, /*out*/int32_t* height) {
703     ALOGV("%s", __FUNCTION__);
704     if (image == nullptr || height == nullptr) {
705         ALOGE("%s: bad argument. image %p height %p",
706                 __FUNCTION__, image, height);
707         return AMEDIA_ERROR_INVALID_PARAMETER;
708     }
709     return image->getHeight(height);
710 }
711 
712 EXPORT
AImage_getFormat(const AImage * image,int32_t * format)713 media_status_t AImage_getFormat(const AImage* image, /*out*/int32_t* format) {
714     ALOGV("%s", __FUNCTION__);
715     if (image == nullptr || format == nullptr) {
716         ALOGE("%s: bad argument. image %p format %p",
717                 __FUNCTION__, image, format);
718         return AMEDIA_ERROR_INVALID_PARAMETER;
719     }
720     return image->getFormat(format);
721 }
722 
723 EXPORT
AImage_getCropRect(const AImage * image,AImageCropRect * rect)724 media_status_t AImage_getCropRect(const AImage* image, /*out*/AImageCropRect* rect) {
725     ALOGV("%s", __FUNCTION__);
726     if (image == nullptr || rect == nullptr) {
727         ALOGE("%s: bad argument. image %p rect %p",
728                 __FUNCTION__, image, rect);
729         return AMEDIA_ERROR_INVALID_PARAMETER;
730     }
731     // For now AImage only supports camera outputs where cropRect is always full window
732     int32_t width = -1;
733     media_status_t ret = image->getWidth(&width);
734     if (ret != AMEDIA_OK) {
735         return ret;
736     }
737     int32_t height = -1;
738     ret = image->getHeight(&height);
739     if (ret != AMEDIA_OK) {
740         return ret;
741     }
742     rect->left = 0;
743     rect->top = 0;
744     rect->right = width;
745     rect->bottom = height;
746     return AMEDIA_OK;
747 }
748 
749 EXPORT
AImage_getTimestamp(const AImage * image,int64_t * timestampNs)750 media_status_t AImage_getTimestamp(const AImage* image, /*out*/int64_t* timestampNs) {
751     ALOGV("%s", __FUNCTION__);
752     if (image == nullptr || timestampNs == nullptr) {
753         ALOGE("%s: bad argument. image %p timestampNs %p",
754                 __FUNCTION__, image, timestampNs);
755         return AMEDIA_ERROR_INVALID_PARAMETER;
756     }
757     return image->getTimestamp(timestampNs);
758 }
759 
760 EXPORT
AImage_getNumberOfPlanes(const AImage * image,int32_t * numPlanes)761 media_status_t AImage_getNumberOfPlanes(const AImage* image, /*out*/int32_t* numPlanes) {
762     ALOGV("%s", __FUNCTION__);
763     if (image == nullptr || numPlanes == nullptr) {
764         ALOGE("%s: bad argument. image %p numPlanes %p",
765                 __FUNCTION__, image, numPlanes);
766         return AMEDIA_ERROR_INVALID_PARAMETER;
767     }
768     return image->getNumPlanes(numPlanes);
769 }
770 
771 EXPORT
AImage_getPlanePixelStride(const AImage * image,int planeIdx,int32_t * pixelStride)772 media_status_t AImage_getPlanePixelStride(
773         const AImage* image, int planeIdx, /*out*/int32_t* pixelStride) {
774     ALOGV("%s", __FUNCTION__);
775     if (image == nullptr || pixelStride == nullptr) {
776         ALOGE("%s: bad argument. image %p pixelStride %p",
777                 __FUNCTION__, image, pixelStride);
778         return AMEDIA_ERROR_INVALID_PARAMETER;
779     }
780     media_status_t ret = const_cast<AImage*>(image)->lockImage();
781     if (ret != AMEDIA_OK) {
782         ALOGE("%s: failed to lock buffer for CPU access. image %p, error=%d.",
783               __FUNCTION__, image, ret);
784         return ret;
785     }
786     return image->getPlanePixelStride(planeIdx, pixelStride);
787 }
788 
789 EXPORT
AImage_getPlaneRowStride(const AImage * image,int planeIdx,int32_t * rowStride)790 media_status_t AImage_getPlaneRowStride(
791         const AImage* image, int planeIdx, /*out*/int32_t* rowStride) {
792     ALOGV("%s", __FUNCTION__);
793     if (image == nullptr || rowStride == nullptr) {
794         ALOGE("%s: bad argument. image %p rowStride %p",
795                 __FUNCTION__, image, rowStride);
796         return AMEDIA_ERROR_INVALID_PARAMETER;
797     }
798     media_status_t ret = const_cast<AImage*>(image)->lockImage();
799     if (ret != AMEDIA_OK) {
800         ALOGE("%s: failed to lock buffer for CPU access. image %p, error=%d.",
801               __FUNCTION__, image, ret);
802         return ret;
803     }
804     return image->getPlaneRowStride(planeIdx, rowStride);
805 }
806 
807 EXPORT
AImage_getPlaneData(const AImage * image,int planeIdx,uint8_t ** data,int * dataLength)808 media_status_t AImage_getPlaneData(
809         const AImage* image, int planeIdx,
810         /*out*/uint8_t** data, /*out*/int* dataLength) {
811     ALOGV("%s", __FUNCTION__);
812     if (image == nullptr || data == nullptr || dataLength == nullptr) {
813         ALOGE("%s: bad argument. image %p data %p dataLength %p",
814                 __FUNCTION__, image, data, dataLength);
815         return AMEDIA_ERROR_INVALID_PARAMETER;
816     }
817     media_status_t ret = const_cast<AImage*>(image)->lockImage();
818     if (ret != AMEDIA_OK) {
819         ALOGE("%s: failed to lock buffer for CPU access. image %p, error=%d.",
820               __FUNCTION__, image, ret);
821         return ret;
822     }
823     return image->getPlaneData(planeIdx, data, dataLength);
824 }
825 
826 EXPORT
AImage_getHardwareBuffer(const AImage * image,AHardwareBuffer ** buffer)827 media_status_t AImage_getHardwareBuffer(
828     const AImage* image, /*out*/AHardwareBuffer** buffer) {
829     ALOGV("%s", __FUNCTION__);
830 
831     if (image == nullptr || buffer == nullptr) {
832         ALOGE("%s: bad argument. image %p buffer %p", __FUNCTION__, image, buffer);
833         return AMEDIA_ERROR_INVALID_PARAMETER;
834     }
835     return image->getHardwareBuffer(buffer);
836 }
837 
838 EXPORT
AImage_getDataSpace(const AImage * image,int32_t * dataSpace)839 media_status_t AImage_getDataSpace(
840     const AImage* image, /*out*/int32_t* dataSpace) {
841     ALOGV("%s", __FUNCTION__);
842 
843     if (image == nullptr || dataSpace == nullptr) {
844         ALOGE("%s: bad argument. image %p dataSpace %p", __FUNCTION__, image, dataSpace);
845         return AMEDIA_ERROR_INVALID_PARAMETER;
846     }
847     return image->getDataSpace((android_dataspace*)(dataSpace));
848 }