OutputConfiguration.cpp revision addae1cfa92c3bae2b59917160da5520d2a25865
1/*
2**
3** Copyright 2015, The Android Open Source Project
4**
5** Licensed under the Apache License, Version 2.0 (the "License");
6** you may not use this file except in compliance with the License.
7** You may obtain a copy of the License at
8**
9**     http://www.apache.org/licenses/LICENSE-2.0
10**
11** Unless required by applicable law or agreed to in writing, software
12** distributed under the License is distributed on an "AS IS" BASIS,
13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14** See the License for the specific language governing permissions and
15** limitations under the License.
16*/
17
18#define LOG_TAG "OutputConfiguration"
19//#define LOG_NDEBUG 0
20
21#include <utils/Log.h>
22
23#include <camera/camera2/OutputConfiguration.h>
24#include <binder/Parcel.h>
25#include <gui/Surface.h>
26#include <utils/String8.h>
27
28namespace android {
29
30
31const int OutputConfiguration::INVALID_ROTATION = -1;
32const int OutputConfiguration::INVALID_SET_ID = -1;
33
34const std::vector<sp<IGraphicBufferProducer>>&
35        OutputConfiguration::getGraphicBufferProducers() const {
36    return mGbps;
37}
38
39int OutputConfiguration::getRotation() const {
40    return mRotation;
41}
42
43int OutputConfiguration::getSurfaceSetID() const {
44    return mSurfaceSetID;
45}
46
47int OutputConfiguration::getSurfaceType() const {
48    return mSurfaceType;
49}
50
51int OutputConfiguration::getWidth() const {
52    return mWidth;
53}
54
55int OutputConfiguration::getHeight() const {
56    return mHeight;
57}
58
59OutputConfiguration::OutputConfiguration() :
60        mRotation(INVALID_ROTATION),
61        mSurfaceSetID(INVALID_SET_ID),
62        mSurfaceType(SURFACE_TYPE_UNKNOWN),
63        mWidth(0),
64        mHeight(0) {
65}
66
67OutputConfiguration::OutputConfiguration(const android::Parcel& parcel) :
68        mRotation(INVALID_ROTATION),
69        mSurfaceSetID(INVALID_SET_ID) {
70    readFromParcel(&parcel);
71}
72
73status_t OutputConfiguration::readFromParcel(const android::Parcel* parcel) {
74    status_t err = OK;
75    int rotation = 0;
76
77    if (parcel == nullptr) return BAD_VALUE;
78
79    if ((err = parcel->readInt32(&rotation)) != OK) {
80        ALOGE("%s: Failed to read rotation from parcel", __FUNCTION__);
81        return err;
82    }
83
84    int setID = INVALID_SET_ID;
85    if ((err = parcel->readInt32(&setID)) != OK) {
86        ALOGE("%s: Failed to read surface set ID from parcel", __FUNCTION__);
87        return err;
88    }
89
90    int surfaceType = SURFACE_TYPE_UNKNOWN;
91    if ((err = parcel->readInt32(&surfaceType)) != OK) {
92        ALOGE("%s: Failed to read surface type from parcel", __FUNCTION__);
93        return err;
94    }
95
96    int width = 0;
97    if ((err = parcel->readInt32(&width)) != OK) {
98        ALOGE("%s: Failed to read surface width from parcel", __FUNCTION__);
99        return err;
100    }
101
102    int height = 0;
103    if ((err = parcel->readInt32(&height)) != OK) {
104        ALOGE("%s: Failed to read surface height from parcel", __FUNCTION__);
105        return err;
106    }
107
108    // numSurfaces is the total number of surfaces for this OutputConfiguration,
109    // regardless the surface is deferred or not.
110    int numSurfaces = 0;
111    if ((err = parcel->readInt32(&numSurfaces)) != OK) {
112        ALOGE("%s: Failed to read maxSurfaces from parcel", __FUNCTION__);
113        return err;
114    }
115    if (numSurfaces < 1) {
116        ALOGE("%s: there has to be at least 1 surface per"
117              " outputConfiguration", __FUNCTION__);
118        return BAD_VALUE;
119    }
120
121    // Read all surfaces from parcel. If a surface is deferred, readFromPacel
122    // returns error, and a null surface is put into the mGbps. We assume all
123    // deferred surfaces are after non-deferred surfaces in the parcel.
124    // TODO: Need better way to detect deferred surface than using error
125    // return from readFromParcel.
126    std::vector<sp<IGraphicBufferProducer>> gbps;
127    for (int i = 0; i < numSurfaces; i++) {
128        view::Surface surfaceShim;
129        if ((err = surfaceShim.readFromParcel(parcel)) != OK) {
130            // Read surface failure for deferred surface configuration is expected.
131            if ((surfaceType == SURFACE_TYPE_SURFACE_VIEW ||
132                    surfaceType == SURFACE_TYPE_SURFACE_TEXTURE)) {
133                ALOGV("%s: Get null surface from a deferred surface configuration (%dx%d)",
134                        __FUNCTION__, width, height);
135                err = OK;
136            } else {
137                ALOGE("%s: Failed to read surface from parcel", __FUNCTION__);
138                return err;
139            }
140        }
141        gbps.push_back(surfaceShim.graphicBufferProducer);
142        ALOGV("%s: OutputConfiguration: gbps[%d] : %p, name %s", __FUNCTION__,
143                i, gbps[i].get(), String8(surfaceShim.name).string());
144    }
145
146    mRotation = rotation;
147    mSurfaceSetID = setID;
148    mSurfaceType = surfaceType;
149    mWidth = width;
150    mHeight = height;
151    mGbps = std::move(gbps);
152
153    ALOGV("%s: OutputConfiguration: rotation = %d, setId = %d, surfaceType = %d",
154            __FUNCTION__, mRotation, mSurfaceSetID, mSurfaceType);
155
156    return err;
157}
158
159OutputConfiguration::OutputConfiguration(sp<IGraphicBufferProducer>& gbp, int rotation,
160        int surfaceSetID) {
161    mGbps.push_back(gbp);
162    mRotation = rotation;
163    mSurfaceSetID = surfaceSetID;
164}
165
166status_t OutputConfiguration::writeToParcel(android::Parcel* parcel) const {
167
168    if (parcel == nullptr) return BAD_VALUE;
169    status_t err = OK;
170
171    err = parcel->writeInt32(mRotation);
172    if (err != OK) return err;
173
174    err = parcel->writeInt32(mSurfaceSetID);
175    if (err != OK) return err;
176
177    err = parcel->writeInt32(mSurfaceType);
178    if (err != OK) return err;
179
180    err = parcel->writeInt32(mWidth);
181    if (err != OK) return err;
182
183    err = parcel->writeInt32(mHeight);
184    if (err != OK) return err;
185
186    int numSurfaces = mGbps.size();
187    err = parcel->writeInt32(numSurfaces);
188    if (err != OK) return err;
189
190    for (int i = 0; i < numSurfaces; i++) {
191        view::Surface surfaceShim;
192        surfaceShim.name = String16("unknown_name"); // name of surface
193        surfaceShim.graphicBufferProducer = mGbps[i];
194
195        err = surfaceShim.writeToParcel(parcel);
196        if (err != OK) return err;
197    }
198
199    return OK;
200}
201
202bool OutputConfiguration::gbpsEqual(const OutputConfiguration& other) const {
203    const std::vector<sp<IGraphicBufferProducer> >& otherGbps =
204            other.getGraphicBufferProducers();
205
206    if (mGbps.size() != otherGbps.size()) {
207        return false;
208    }
209
210    for (size_t i = 0; i < mGbps.size(); i++) {
211        if (mGbps[i] != otherGbps[i]) {
212            return false;
213        }
214    }
215
216    return true;
217}
218
219bool OutputConfiguration::gbpsLessThan(const OutputConfiguration& other) const {
220    const std::vector<sp<IGraphicBufferProducer> >& otherGbps =
221            other.getGraphicBufferProducers();
222
223    if (mGbps.size() !=  otherGbps.size()) {
224        return mGbps.size() < otherGbps.size();
225    }
226
227    for (size_t i = 0; i < mGbps.size(); i++) {
228        if (mGbps[i] != otherGbps[i]) {
229            return mGbps[i] < otherGbps[i];
230        }
231    }
232
233    return false;
234}
235}; // namespace android
236