1c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh/*
2c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh * Copyright (C) 2016 The Android Open Source Project
3c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh *
4c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh * Licensed under the Apache License, Version 2.0 (the "License");
5c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh * you may not use this file except in compliance with the License.
6c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh * You may obtain a copy of the License at
7c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh *
8c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh *      http://www.apache.org/licenses/LICENSE-2.0
9c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh *
10c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh * Unless required by applicable law or agreed to in writing, software
11c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh * distributed under the License is distributed on an "AS IS" BASIS,
12c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh * See the License for the specific language governing permissions and
14c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh * limitations under the License.
15c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh */
16c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh
17c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh#include <inttypes.h>
18c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh
19c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh//#define LOG_NDEBUG 0
20c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh#define LOG_TAG "NdkImage"
21c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh
22c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh#include "NdkImagePriv.h"
23c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh#include "NdkImageReaderPriv.h"
24c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh
25c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh#include <utils/Log.h>
26c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh#include "hardware/camera3.h"
27c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh
28c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yehusing namespace android;
29c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh
30c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh#define ALIGN(x, mask) ( ((x) + (mask) - 1) & ~((mask) - 1) )
31c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh
32c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia YehAImage::AImage(AImageReader* reader, int32_t format,
33c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        CpuConsumer::LockedBuffer* buffer, int64_t timestamp,
34c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        int32_t width, int32_t height, int32_t numPlanes) :
35c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        mReader(reader), mFormat(format),
36c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        mBuffer(buffer), mTimestamp(timestamp),
37c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        mWidth(width), mHeight(height), mNumPlanes(numPlanes) {
38c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh}
39c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh
40c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh// Can only be called by free() with mLock hold
41c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia YehAImage::~AImage() {
42c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    if (!mIsClosed) {
43c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        LOG_ALWAYS_FATAL(
44c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh                "Error: AImage %p is deleted before returning buffer to AImageReader!", this);
45c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    }
46c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh}
47c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh
48c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yehbool
49c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia YehAImage::isClosed() const {
50c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    Mutex::Autolock _l(mLock);
51c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    return mIsClosed;
52c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh}
53c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh
54c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yehvoid
55c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia YehAImage::close() {
56c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    Mutex::Autolock _l(mLock);
57c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    if (mIsClosed) {
58c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        return;
59c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    }
60c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    sp<AImageReader> reader = mReader.promote();
61c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    if (reader == nullptr) {
62c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        LOG_ALWAYS_FATAL("Error: AImage not closed before AImageReader close!");
63c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        return;
64c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    }
65c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    reader->releaseImageLocked(this);
66c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    // Should have been set to nullptr in releaseImageLocked
67c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    // Set to nullptr here for extra safety only
68c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    mBuffer = nullptr;
69c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    mIsClosed = true;
70c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh}
71c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh
72c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yehvoid
73c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia YehAImage::free() {
74c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    if (!isClosed()) {
75c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        ALOGE("Cannot free AImage before close!");
76c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        return;
77c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    }
78c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    Mutex::Autolock _l(mLock);
79c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    delete this;
80c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh}
81c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh
82c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yehvoid
83c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia YehAImage::lockReader() const {
84c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    sp<AImageReader> reader = mReader.promote();
85c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    if (reader == nullptr) {
86c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        // Reader has been closed
87c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        return;
88c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    }
89c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    reader->mLock.lock();
90c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh}
91c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh
92c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yehvoid
93c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia YehAImage::unlockReader() const {
94c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    sp<AImageReader> reader = mReader.promote();
95c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    if (reader == nullptr) {
96c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        // Reader has been closed
97c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        return;
98c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    }
99c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    reader->mLock.unlock();
100c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh}
101c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh
102c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yehmedia_status_t
103c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia YehAImage::getWidth(int32_t* width) const {
104c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    if (width == nullptr) {
105c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        return AMEDIA_ERROR_INVALID_PARAMETER;
106c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    }
107c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    *width = -1;
108c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    if (isClosed()) {
109c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        ALOGE("%s: image %p has been closed!", __FUNCTION__, this);
110c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        return AMEDIA_ERROR_INVALID_OBJECT;
111c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    }
112c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    *width = mWidth;
113c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    return AMEDIA_OK;
114c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh}
115c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh
116c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yehmedia_status_t
117c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia YehAImage::getHeight(int32_t* height) const {
118c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    if (height == nullptr) {
119c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        return AMEDIA_ERROR_INVALID_PARAMETER;
120c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    }
121c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    *height = -1;
122c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    if (isClosed()) {
123c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        ALOGE("%s: image %p has been closed!", __FUNCTION__, this);
124c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        return AMEDIA_ERROR_INVALID_OBJECT;
125c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    }
126c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    *height = mHeight;
127c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    return AMEDIA_OK;
128c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh}
129c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh
130c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yehmedia_status_t
131c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia YehAImage::getFormat(int32_t* format) const {
132c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    if (format == nullptr) {
133c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        return AMEDIA_ERROR_INVALID_PARAMETER;
134c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    }
135c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    *format = -1;
136c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    if (isClosed()) {
137c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        ALOGE("%s: image %p has been closed!", __FUNCTION__, this);
138c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        return AMEDIA_ERROR_INVALID_OBJECT;
139c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    }
140c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    *format = mFormat;
141c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    return AMEDIA_OK;
142c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh}
143c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh
144c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yehmedia_status_t
145c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia YehAImage::getNumPlanes(int32_t* numPlanes) const {
146c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    if (numPlanes == nullptr) {
147c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        return AMEDIA_ERROR_INVALID_PARAMETER;
148c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    }
149c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    *numPlanes = -1;
150c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    if (isClosed()) {
151c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        ALOGE("%s: image %p has been closed!", __FUNCTION__, this);
152c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        return AMEDIA_ERROR_INVALID_OBJECT;
153c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    }
154c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    *numPlanes = mNumPlanes;
155c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    return AMEDIA_OK;
156c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh}
157c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh
158c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yehmedia_status_t
159c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia YehAImage::getTimestamp(int64_t* timestamp) const {
160c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    if (timestamp == nullptr) {
161c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        return AMEDIA_ERROR_INVALID_PARAMETER;
162c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    }
163c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    *timestamp = -1;
164c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    if (isClosed()) {
165c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        ALOGE("%s: image %p has been closed!", __FUNCTION__, this);
166c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        return AMEDIA_ERROR_INVALID_OBJECT;
167c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    }
168c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    *timestamp = mTimestamp;
169c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    return AMEDIA_OK;
170c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh}
171c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh
172c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yehmedia_status_t
173c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia YehAImage::getPlanePixelStride(int planeIdx, /*out*/int32_t* pixelStride) const {
174c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    if (planeIdx < 0 || planeIdx >= mNumPlanes) {
175c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        ALOGE("Error: planeIdx %d out of bound [0,%d]",
176c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh                planeIdx, mNumPlanes - 1);
177c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        return AMEDIA_ERROR_INVALID_PARAMETER;
178c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    }
179c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    if (pixelStride == nullptr) {
180c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        return AMEDIA_ERROR_INVALID_PARAMETER;
181c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    }
182c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    if (isClosed()) {
183c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        ALOGE("%s: image %p has been closed!", __FUNCTION__, this);
184c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        return AMEDIA_ERROR_INVALID_OBJECT;
185c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    }
186c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    int32_t fmt = mBuffer->flexFormat;
187c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    switch (fmt) {
188c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        case HAL_PIXEL_FORMAT_YCbCr_420_888:
189c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            *pixelStride = (planeIdx == 0) ? 1 : mBuffer->chromaStep;
190c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            return AMEDIA_OK;
191c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
192c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            *pixelStride = (planeIdx == 0) ? 1 : 2;
193c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            return AMEDIA_OK;
194c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        case HAL_PIXEL_FORMAT_Y8:
195c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            *pixelStride = 1;
196c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            return AMEDIA_OK;
197c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        case HAL_PIXEL_FORMAT_YV12:
198c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            *pixelStride = 1;
199c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            return AMEDIA_OK;
200c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        case HAL_PIXEL_FORMAT_Y16:
201c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        case HAL_PIXEL_FORMAT_RAW16:
202c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        case HAL_PIXEL_FORMAT_RGB_565:
203c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            // Single plane 16bpp data.
204c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            *pixelStride = 2;
205c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            return AMEDIA_OK;
206c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        case HAL_PIXEL_FORMAT_RGBA_8888:
207c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        case HAL_PIXEL_FORMAT_RGBX_8888:
208c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            *pixelStride = 4;
209c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            return AMEDIA_OK;
210c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        case HAL_PIXEL_FORMAT_RGB_888:
211c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            // Single plane, 24bpp.
212c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            *pixelStride = 3;
213c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            return AMEDIA_OK;
214c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        case HAL_PIXEL_FORMAT_BLOB:
215c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        case HAL_PIXEL_FORMAT_RAW10:
216c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        case HAL_PIXEL_FORMAT_RAW12:
217c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        case HAL_PIXEL_FORMAT_RAW_OPAQUE:
218c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            // Blob is used for JPEG data, RAW10 and RAW12 is used for 10-bit and 12-bit raw data,
219c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            // those are single plane data without pixel stride defined
220c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            return AMEDIA_ERROR_UNSUPPORTED;
221c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        default:
222c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            ALOGE("Pixel format: 0x%x is unsupported", fmt);
223c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            return AMEDIA_ERROR_UNSUPPORTED;
224c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    }
225c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh}
226c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh
227c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yehmedia_status_t
228c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia YehAImage::getPlaneRowStride(int planeIdx, /*out*/int32_t* rowStride) const {
229c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    if (planeIdx < 0 || planeIdx >= mNumPlanes) {
230c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        ALOGE("Error: planeIdx %d out of bound [0,%d]",
231c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh                planeIdx, mNumPlanes - 1);
232c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        return AMEDIA_ERROR_INVALID_PARAMETER;
233c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    }
234c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    if (rowStride == nullptr) {
235c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        return AMEDIA_ERROR_INVALID_PARAMETER;
236c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    }
237c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    if (isClosed()) {
238c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        ALOGE("%s: image %p has been closed!", __FUNCTION__, this);
239c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        return AMEDIA_ERROR_INVALID_OBJECT;
240c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    }
241c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    int32_t fmt = mBuffer->flexFormat;
242c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    switch (fmt) {
243c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        case HAL_PIXEL_FORMAT_YCbCr_420_888:
244c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            *rowStride = (planeIdx == 0) ? mBuffer->stride : mBuffer->chromaStride;
245c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            return AMEDIA_OK;
246c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
247c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            *rowStride = mBuffer->width;
248c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            return AMEDIA_OK;
249c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        case HAL_PIXEL_FORMAT_YV12:
250c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            if (mBuffer->stride % 16) {
251c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh                ALOGE("Stride %d is not 16 pixel aligned!", mBuffer->stride);
252c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh                return AMEDIA_ERROR_UNKNOWN;
253c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            }
254c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            *rowStride = (planeIdx == 0) ? mBuffer->stride : ALIGN(mBuffer->stride / 2, 16);
255c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            return AMEDIA_OK;
256c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        case HAL_PIXEL_FORMAT_RAW10:
257c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        case HAL_PIXEL_FORMAT_RAW12:
258c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            // RAW10 and RAW12 are used for 10-bit and 12-bit raw data, they are single plane
259c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            *rowStride = mBuffer->stride;
260c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            return AMEDIA_OK;
261c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        case HAL_PIXEL_FORMAT_Y8:
262c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            if (mBuffer->stride % 16) {
263c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh                ALOGE("Stride %d is not 16 pixel aligned!", mBuffer->stride);
264c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh                return AMEDIA_ERROR_UNKNOWN;
265c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            }
266c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            *rowStride = mBuffer->stride;
267c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            return AMEDIA_OK;
268c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        case HAL_PIXEL_FORMAT_Y16:
269c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        case HAL_PIXEL_FORMAT_RAW16:
270c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            // In native side, strides are specified in pixels, not in bytes.
271c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            // Single plane 16bpp bayer data. even width/height,
272c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            // row stride multiple of 16 pixels (32 bytes)
273c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            if (mBuffer->stride % 16) {
274c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh                ALOGE("Stride %d is not 16 pixel aligned!", mBuffer->stride);
275c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh                return AMEDIA_ERROR_UNKNOWN;
276c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            }
277c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            *rowStride = mBuffer->stride * 2;
278c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            return AMEDIA_OK;
279c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        case HAL_PIXEL_FORMAT_RGB_565:
280c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            *rowStride = mBuffer->stride * 2;
281c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            return AMEDIA_OK;
282c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        case HAL_PIXEL_FORMAT_RGBA_8888:
283c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        case HAL_PIXEL_FORMAT_RGBX_8888:
284c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            *rowStride = mBuffer->stride * 4;
285c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            return AMEDIA_OK;
286c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        case HAL_PIXEL_FORMAT_RGB_888:
287c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            // Single plane, 24bpp.
288c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            *rowStride = mBuffer->stride * 3;
289c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            return AMEDIA_OK;
290c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        case HAL_PIXEL_FORMAT_BLOB:
291c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        case HAL_PIXEL_FORMAT_RAW_OPAQUE:
292c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            // Blob is used for JPEG/Raw opaque data. It is single plane and has 0 row stride and
293c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            // no row stride defined
294c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            return AMEDIA_ERROR_UNSUPPORTED;
295c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        default:
296c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            ALOGE("%s Pixel format: 0x%x is unsupported", __FUNCTION__, fmt);
297c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh          return AMEDIA_ERROR_UNSUPPORTED;
298c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    }
299c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh}
300c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh
301c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yehuint32_t
302c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia YehAImage::getJpegSize() const {
303c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    if (mBuffer == nullptr) {
304c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        LOG_ALWAYS_FATAL("Error: buffer is null");
305c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    }
306c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh
307c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    uint32_t size = 0;
308c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    uint32_t width = mBuffer->width;
309c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    uint8_t* jpegBuffer = mBuffer->data;
310c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh
311c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    // First check for JPEG transport header at the end of the buffer
312c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    uint8_t* header = jpegBuffer + (width - sizeof(struct camera3_jpeg_blob));
313c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    struct camera3_jpeg_blob* blob = (struct camera3_jpeg_blob*)(header);
314c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    if (blob->jpeg_blob_id == CAMERA3_JPEG_BLOB_ID) {
315c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        size = blob->jpeg_size;
316c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        ALOGV("%s: Jpeg size = %d", __FUNCTION__, size);
317c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    }
318c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh
319c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    // failed to find size, default to whole buffer
320c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    if (size == 0) {
321c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        /*
322c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh         * This is a problem because not including the JPEG header
323c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh         * means that in certain rare situations a regular JPEG blob
324c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh         * will be misidentified as having a header, in which case
325c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh         * we will get a garbage size value.
326c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh         */
327c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        ALOGW("%s: No JPEG header detected, defaulting to size=width=%d",
328c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh                __FUNCTION__, width);
329c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        size = width;
330c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    }
331c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh
332c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    return size;
333c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh}
334c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh
335c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yehmedia_status_t
336c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia YehAImage::getPlaneData(int planeIdx,/*out*/uint8_t** data, /*out*/int* dataLength) const {
337c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    if (planeIdx < 0 || planeIdx >= mNumPlanes) {
338c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        ALOGE("Error: planeIdx %d out of bound [0,%d]",
339c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh                planeIdx, mNumPlanes - 1);
340c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        return AMEDIA_ERROR_INVALID_PARAMETER;
341c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    }
342c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    if (data == nullptr || dataLength == nullptr) {
343c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        return AMEDIA_ERROR_INVALID_PARAMETER;
344c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    }
345c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    if (isClosed()) {
346c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        ALOGE("%s: image %p has been closed!", __FUNCTION__, this);
347c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        return AMEDIA_ERROR_INVALID_OBJECT;
348c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    }
349c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh
350c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    uint32_t dataSize, ySize, cSize, cStride;
351c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    uint8_t* cb = nullptr;
352c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    uint8_t* cr = nullptr;
353c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    uint8_t* pData = nullptr;
354c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    int bytesPerPixel = 0;
355c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    int32_t fmt = mBuffer->flexFormat;
356c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh
357c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    switch (fmt) {
358c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        case HAL_PIXEL_FORMAT_YCbCr_420_888:
359c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            pData = (planeIdx == 0) ? mBuffer->data :
360c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh                    (planeIdx == 1) ? mBuffer->dataCb : mBuffer->dataCr;
361c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            // only map until last pixel
362c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            if (planeIdx == 0) {
363c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh                dataSize = mBuffer->stride * (mBuffer->height - 1) + mBuffer->width;
364c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            } else {
365c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh                dataSize = mBuffer->chromaStride * (mBuffer->height / 2 - 1) +
366c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh                        mBuffer->chromaStep * (mBuffer->width / 2 - 1) + 1;
367c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            }
368c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            break;
369c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        // NV21
370c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
371c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            cr = mBuffer->data + (mBuffer->stride * mBuffer->height);
372c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            cb = cr + 1;
373c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            // only map until last pixel
374c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            ySize = mBuffer->width * (mBuffer->height - 1) + mBuffer->width;
375c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            cSize = mBuffer->width * (mBuffer->height / 2 - 1) + mBuffer->width - 1;
376c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh
377c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            pData = (planeIdx == 0) ? mBuffer->data :
378c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh                    (planeIdx == 1) ? cb : cr;
379c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            dataSize = (planeIdx == 0) ? ySize : cSize;
380c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            break;
381c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        case HAL_PIXEL_FORMAT_YV12:
382c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            // Y and C stride need to be 16 pixel aligned.
383c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            if (mBuffer->stride % 16) {
384c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh                ALOGE("Stride %d is not 16 pixel aligned!", mBuffer->stride);
385c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh                return AMEDIA_ERROR_UNKNOWN;
386c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            }
387c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh
388c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            ySize = mBuffer->stride * mBuffer->height;
389c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            cStride = ALIGN(mBuffer->stride / 2, 16);
390c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            cr = mBuffer->data + ySize;
391c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            cSize = cStride * mBuffer->height / 2;
392c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            cb = cr + cSize;
393c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh
394c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            pData = (planeIdx == 0) ? mBuffer->data :
395c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh                    (planeIdx == 1) ? cb : cr;
396c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            dataSize = (planeIdx == 0) ? ySize : cSize;
397c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            break;
398c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        case HAL_PIXEL_FORMAT_Y8:
399c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            // Single plane, 8bpp.
400c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh
401c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            pData = mBuffer->data;
402c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            dataSize = mBuffer->stride * mBuffer->height;
403c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            break;
404c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        case HAL_PIXEL_FORMAT_Y16:
405c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            bytesPerPixel = 2;
406c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh
407c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            pData = mBuffer->data;
408c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            dataSize = mBuffer->stride * mBuffer->height * bytesPerPixel;
409c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            break;
410c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        case HAL_PIXEL_FORMAT_BLOB:
411c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            // Used for JPEG data, height must be 1, width == size, single plane.
412c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            if (mBuffer->height != 1) {
413c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh                ALOGE("Jpeg should have height value one but got %d", mBuffer->height);
414c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh                return AMEDIA_ERROR_UNKNOWN;
415c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            }
416c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh
417c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            pData = mBuffer->data;
418c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            dataSize = getJpegSize();
419c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            break;
420c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        case HAL_PIXEL_FORMAT_RAW16:
421c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            // Single plane 16bpp bayer data.
422c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            bytesPerPixel = 2;
423c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            pData = mBuffer->data;
424c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            dataSize = mBuffer->stride * mBuffer->height * bytesPerPixel;
425c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            break;
426c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        case HAL_PIXEL_FORMAT_RAW_OPAQUE:
427c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            // Used for RAW_OPAQUE data, height must be 1, width == size, single plane.
428c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            if (mBuffer->height != 1) {
429c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh                ALOGE("RAW_OPAQUE should have height value one but got %d", mBuffer->height);
430c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh                return AMEDIA_ERROR_UNKNOWN;
431c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            }
432c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            pData = mBuffer->data;
433c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            dataSize = mBuffer->width;
434c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            break;
435c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        case HAL_PIXEL_FORMAT_RAW10:
436c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            // Single plane 10bpp bayer data.
437c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            if (mBuffer->width % 4) {
438c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh                ALOGE("Width is not multiple of 4 %d", mBuffer->width);
439c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh                return AMEDIA_ERROR_UNKNOWN;
440c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            }
441c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            if (mBuffer->height % 2) {
442c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh                ALOGE("Height is not multiple of 2 %d", mBuffer->height);
443c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh                return AMEDIA_ERROR_UNKNOWN;
444c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            }
445c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            if (mBuffer->stride < (mBuffer->width * 10 / 8)) {
446c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh                ALOGE("stride (%d) should be at least %d",
447c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh                        mBuffer->stride, mBuffer->width * 10 / 8);
448c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh                return AMEDIA_ERROR_UNKNOWN;
449c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            }
450c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            pData = mBuffer->data;
451c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            dataSize = mBuffer->stride * mBuffer->height;
452c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            break;
453c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        case HAL_PIXEL_FORMAT_RAW12:
454c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            // Single plane 10bpp bayer data.
455c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            if (mBuffer->width % 4) {
456c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh                ALOGE("Width is not multiple of 4 %d", mBuffer->width);
457c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh                return AMEDIA_ERROR_UNKNOWN;
458c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            }
459c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            if (mBuffer->height % 2) {
460c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh                ALOGE("Height is not multiple of 2 %d", mBuffer->height);
461c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh                return AMEDIA_ERROR_UNKNOWN;
462c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            }
463c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            if (mBuffer->stride < (mBuffer->width * 12 / 8)) {
464c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh                ALOGE("stride (%d) should be at least %d",
465c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh                        mBuffer->stride, mBuffer->width * 12 / 8);
466c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh                return AMEDIA_ERROR_UNKNOWN;
467c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            }
468c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            pData = mBuffer->data;
469c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            dataSize = mBuffer->stride * mBuffer->height;
470c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            break;
471c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        case HAL_PIXEL_FORMAT_RGBA_8888:
472c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        case HAL_PIXEL_FORMAT_RGBX_8888:
473c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            // Single plane, 32bpp.
474c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            bytesPerPixel = 4;
475c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            pData = mBuffer->data;
476c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            dataSize = mBuffer->stride * mBuffer->height * bytesPerPixel;
477c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            break;
478c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        case HAL_PIXEL_FORMAT_RGB_565:
479c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            // Single plane, 16bpp.
480c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            bytesPerPixel = 2;
481c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            pData = mBuffer->data;
482c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            dataSize = mBuffer->stride * mBuffer->height * bytesPerPixel;
483c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            break;
484c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        case HAL_PIXEL_FORMAT_RGB_888:
485c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            // Single plane, 24bpp.
486c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            bytesPerPixel = 3;
487c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            pData = mBuffer->data;
488c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            dataSize = mBuffer->stride * mBuffer->height * bytesPerPixel;
489c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            break;
490c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        default:
491c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            ALOGE("Pixel format: 0x%x is unsupported", fmt);
492c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            return AMEDIA_ERROR_UNSUPPORTED;
493c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    }
494c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh
495c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    *data = pData;
496c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    *dataLength = dataSize;
497c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    return AMEDIA_OK;
498c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh}
499c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh
500c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia YehEXPORT
501c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yehvoid AImage_delete(AImage* image) {
502c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    ALOGV("%s", __FUNCTION__);
503c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    if (image != nullptr) {
504c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        image->lockReader();
505c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        image->close();
506c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        image->unlockReader();
507c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        if (!image->isClosed()) {
508c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh            LOG_ALWAYS_FATAL("Image close failed!");
509c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        }
510c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        image->free();
511c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    }
512c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    return;
513c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh}
514c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh
515c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia YehEXPORT
516c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yehmedia_status_t AImage_getWidth(const AImage* image, /*out*/int32_t* width) {
517c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    ALOGV("%s", __FUNCTION__);
518c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    if (image == nullptr || width == nullptr) {
519c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        ALOGE("%s: bad argument. image %p width %p",
520c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh                __FUNCTION__, image, width);
521c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        return AMEDIA_ERROR_INVALID_PARAMETER;
522c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    }
523c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    return image->getWidth(width);
524c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh}
525c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh
526c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia YehEXPORT
527c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yehmedia_status_t AImage_getHeight(const AImage* image, /*out*/int32_t* height) {
528c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    ALOGV("%s", __FUNCTION__);
529c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    if (image == nullptr || height == nullptr) {
530c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        ALOGE("%s: bad argument. image %p height %p",
531c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh                __FUNCTION__, image, height);
532c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        return AMEDIA_ERROR_INVALID_PARAMETER;
533c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    }
534c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    return image->getHeight(height);
535c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh}
536c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh
537c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia YehEXPORT
538c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yehmedia_status_t AImage_getFormat(const AImage* image, /*out*/int32_t* format) {
539c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    ALOGV("%s", __FUNCTION__);
540c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    if (image == nullptr || format == nullptr) {
541c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        ALOGE("%s: bad argument. image %p format %p",
542c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh                __FUNCTION__, image, format);
543c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        return AMEDIA_ERROR_INVALID_PARAMETER;
544c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    }
545c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    return image->getFormat(format);
546c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh}
547c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh
548c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia YehEXPORT
549c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yehmedia_status_t AImage_getCropRect(const AImage* image, /*out*/AImageCropRect* rect) {
550c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    ALOGV("%s", __FUNCTION__);
551c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    if (image == nullptr || rect == nullptr) {
552c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        ALOGE("%s: bad argument. image %p rect %p",
553c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh                __FUNCTION__, image, rect);
554c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        return AMEDIA_ERROR_INVALID_PARAMETER;
555c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    }
556c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    // For now AImage only supports camera outputs where cropRect is always full window
557c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    int32_t width = -1;
558c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    media_status_t ret = image->getWidth(&width);
559c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    if (ret != AMEDIA_OK) {
560c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        return ret;
561c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    }
562c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    int32_t height = -1;
563c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    ret = image->getHeight(&height);
564c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    if (ret != AMEDIA_OK) {
565c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        return ret;
566c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    }
567c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    rect->left = 0;
568c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    rect->top = 0;
569c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    rect->right = width;
570c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    rect->bottom = height;
571c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    return AMEDIA_OK;
572c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh}
573c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh
574c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia YehEXPORT
575c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yehmedia_status_t AImage_getTimestamp(const AImage* image, /*out*/int64_t* timestampNs) {
576c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    ALOGV("%s", __FUNCTION__);
577c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    if (image == nullptr || timestampNs == nullptr) {
578c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        ALOGE("%s: bad argument. image %p timestampNs %p",
579c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh                __FUNCTION__, image, timestampNs);
580c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        return AMEDIA_ERROR_INVALID_PARAMETER;
581c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    }
582c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    return image->getTimestamp(timestampNs);
583c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh}
584c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh
585c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia YehEXPORT
586c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yehmedia_status_t AImage_getNumberOfPlanes(const AImage* image, /*out*/int32_t* numPlanes) {
587c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    ALOGV("%s", __FUNCTION__);
588c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    if (image == nullptr || numPlanes == nullptr) {
589c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        ALOGE("%s: bad argument. image %p numPlanes %p",
590c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh                __FUNCTION__, image, numPlanes);
591c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        return AMEDIA_ERROR_INVALID_PARAMETER;
592c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    }
593c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    return image->getNumPlanes(numPlanes);
594c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh}
595c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh
596c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia YehEXPORT
597c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yehmedia_status_t AImage_getPlanePixelStride(
598c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        const AImage* image, int planeIdx, /*out*/int32_t* pixelStride) {
599c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    ALOGV("%s", __FUNCTION__);
600c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    if (image == nullptr || pixelStride == nullptr) {
601c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        ALOGE("%s: bad argument. image %p pixelStride %p",
602c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh                __FUNCTION__, image, pixelStride);
603c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        return AMEDIA_ERROR_INVALID_PARAMETER;
604c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    }
605c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    return image->getPlanePixelStride(planeIdx, pixelStride);
606c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh}
607c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh
608c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia YehEXPORT
609c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yehmedia_status_t AImage_getPlaneRowStride(
610c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        const AImage* image, int planeIdx, /*out*/int32_t* rowStride) {
611c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    ALOGV("%s", __FUNCTION__);
612c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    if (image == nullptr || rowStride == nullptr) {
613c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        ALOGE("%s: bad argument. image %p rowStride %p",
614c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh                __FUNCTION__, image, rowStride);
615c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        return AMEDIA_ERROR_INVALID_PARAMETER;
616c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    }
617c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    return image->getPlaneRowStride(planeIdx, rowStride);
618c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh}
619c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh
620c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia YehEXPORT
621c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yehmedia_status_t AImage_getPlaneData(
622c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        const AImage* image, int planeIdx,
623c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        /*out*/uint8_t** data, /*out*/int* dataLength) {
624c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    ALOGV("%s", __FUNCTION__);
625c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    if (image == nullptr || data == nullptr || dataLength == nullptr) {
626c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        ALOGE("%s: bad argument. image %p data %p dataLength %p",
627c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh                __FUNCTION__, image, data, dataLength);
628c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh        return AMEDIA_ERROR_INVALID_PARAMETER;
629c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    }
630c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh    return image->getPlaneData(planeIdx, data, dataLength);
631c360382bf257d815b2a411152485d3c3b37a9f46Yin-Chia Yeh}
632