OutputConfiguration.cpp revision 0129d52df9794d6fdf06be304722b5cb51a2eab5
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 <gui/Surface.h> 25#include <binder/Parcel.h> 26 27namespace android { 28 29 30const int OutputConfiguration::INVALID_ROTATION = -1; 31const int OutputConfiguration::INVALID_SET_ID = -1; 32 33const std::vector<sp<IGraphicBufferProducer>>& 34 OutputConfiguration::getGraphicBufferProducers() const { 35 return mGbps; 36} 37 38int OutputConfiguration::getRotation() const { 39 return mRotation; 40} 41 42int OutputConfiguration::getSurfaceSetID() const { 43 return mSurfaceSetID; 44} 45 46int OutputConfiguration::getSurfaceType() const { 47 return mSurfaceType; 48} 49 50int OutputConfiguration::getWidth() const { 51 return mWidth; 52} 53 54int OutputConfiguration::getHeight() const { 55 return mHeight; 56} 57 58OutputConfiguration::OutputConfiguration() : 59 mRotation(INVALID_ROTATION), 60 mSurfaceSetID(INVALID_SET_ID), 61 mSurfaceType(SURFACE_TYPE_UNKNOWN), 62 mWidth(0), 63 mHeight(0) { 64} 65 66OutputConfiguration::OutputConfiguration(const android::Parcel& parcel) : 67 mRotation(INVALID_ROTATION), 68 mSurfaceSetID(INVALID_SET_ID) { 69 readFromParcel(&parcel); 70} 71 72status_t OutputConfiguration::readFromParcel(const android::Parcel* parcel) { 73 status_t err = OK; 74 int rotation = 0; 75 76 if (parcel == nullptr) return BAD_VALUE; 77 78 if ((err = parcel->readInt32(&rotation)) != OK) { 79 ALOGE("%s: Failed to read rotation from parcel", __FUNCTION__); 80 return err; 81 } 82 83 int setID = INVALID_SET_ID; 84 if ((err = parcel->readInt32(&setID)) != OK) { 85 ALOGE("%s: Failed to read surface set ID from parcel", __FUNCTION__); 86 return err; 87 } 88 89 int surfaceType = SURFACE_TYPE_UNKNOWN; 90 if ((err = parcel->readInt32(&surfaceType)) != OK) { 91 ALOGE("%s: Failed to read surface type from parcel", __FUNCTION__); 92 return err; 93 } 94 95 int width = 0; 96 if ((err = parcel->readInt32(&width)) != OK) { 97 ALOGE("%s: Failed to read surface width from parcel", __FUNCTION__); 98 return err; 99 } 100 101 int height = 0; 102 if ((err = parcel->readInt32(&height)) != OK) { 103 ALOGE("%s: Failed to read surface height from parcel", __FUNCTION__); 104 return err; 105 } 106 107 // numSurfaces is the total number of surfaces for this OutputConfiguration, 108 // regardless the surface is deferred or not. 109 int numSurfaces = 0; 110 if ((err = parcel->readInt32(&numSurfaces)) != OK) { 111 ALOGE("%s: Failed to read maxSurfaces from parcel", __FUNCTION__); 112 return err; 113 } 114 if (numSurfaces < 1) { 115 ALOGE("%s: there has to be at least 1 surface per" 116 " outputConfiguration", __FUNCTION__); 117 return BAD_VALUE; 118 } 119 120 // Read all surfaces from parcel. If a surface is deferred, readFromPacel 121 // returns error, and a null surface is put into the mGbps. We assume all 122 // deferred surfaces are after non-deferred surfaces in the parcel. 123 // TODO: Need better way to detect deferred surface than using error 124 // return from readFromParcel. 125 std::vector<sp<IGraphicBufferProducer>> gbps; 126 for (int i = 0; i < numSurfaces; i++) { 127 view::Surface surfaceShim; 128 if ((err = surfaceShim.readFromParcel(parcel)) != OK) { 129 // Read surface failure for deferred surface configuration is expected. 130 if ((surfaceType == SURFACE_TYPE_SURFACE_VIEW || 131 surfaceType == SURFACE_TYPE_SURFACE_TEXTURE)) { 132 ALOGV("%s: Get null surface from a deferred surface configuration (%dx%d)", 133 __FUNCTION__, width, height); 134 err = OK; 135 } else { 136 ALOGE("%s: Failed to read surface from parcel", __FUNCTION__); 137 return err; 138 } 139 } 140 gbps.push_back(surfaceShim.graphicBufferProducer); 141 ALOGV("%s: OutputConfiguration: gbps[%d] : %p, name %s", __FUNCTION__, 142 i, gbps[i].get(), String8(surfaceShim.name).string()); 143 } 144 145 mRotation = rotation; 146 mSurfaceSetID = setID; 147 mSurfaceType = surfaceType; 148 mWidth = width; 149 mHeight = height; 150 mGbps = std::move(gbps); 151 152 ALOGV("%s: OutputConfiguration: rotation = %d, setId = %d, surfaceType = %d", 153 __FUNCTION__, mRotation, mSurfaceSetID, mSurfaceType); 154 155 return err; 156} 157 158OutputConfiguration::OutputConfiguration(sp<IGraphicBufferProducer>& gbp, int rotation, 159 int surfaceSetID) { 160 mGbps.push_back(gbp); 161 mRotation = rotation; 162 mSurfaceSetID = surfaceSetID; 163} 164 165status_t OutputConfiguration::writeToParcel(android::Parcel* parcel) const { 166 167 if (parcel == nullptr) return BAD_VALUE; 168 status_t err = OK; 169 170 err = parcel->writeInt32(mRotation); 171 if (err != OK) return err; 172 173 err = parcel->writeInt32(mSurfaceSetID); 174 if (err != OK) return err; 175 176 err = parcel->writeInt32(mSurfaceType); 177 if (err != OK) return err; 178 179 err = parcel->writeInt32(mWidth); 180 if (err != OK) return err; 181 182 err = parcel->writeInt32(mHeight); 183 if (err != OK) return err; 184 185 int numSurfaces = mGbps.size(); 186 err = parcel->writeInt32(numSurfaces); 187 if (err != OK) return err; 188 189 for (int i = 0; i < numSurfaces; i++) { 190 view::Surface surfaceShim; 191 surfaceShim.name = String16("unknown_name"); // name of surface 192 surfaceShim.graphicBufferProducer = mGbps[i]; 193 194 err = surfaceShim.writeToParcel(parcel); 195 if (err != OK) return err; 196 } 197 198 return OK; 199} 200 201bool OutputConfiguration::gbpsEqual(const OutputConfiguration& other) const { 202 const std::vector<sp<IGraphicBufferProducer> >& otherGbps = 203 other.getGraphicBufferProducers(); 204 205 if (mGbps.size() != otherGbps.size()) { 206 return false; 207 } 208 209 for (size_t i = 0; i < mGbps.size(); i++) { 210 if (mGbps[i] != otherGbps[i]) { 211 return false; 212 } 213 } 214 215 return true; 216} 217 218bool OutputConfiguration::gbpsLessThan(const OutputConfiguration& other) const { 219 const std::vector<sp<IGraphicBufferProducer> >& otherGbps = 220 other.getGraphicBufferProducers(); 221 222 if (mGbps.size() != otherGbps.size()) { 223 return mGbps.size() < otherGbps.size(); 224 } 225 226 for (size_t i = 0; i < mGbps.size(); i++) { 227 if (mGbps[i] != otherGbps[i]) { 228 return mGbps[i] < otherGbps[i]; 229 } 230 } 231 232 return false; 233} 234}; // namespace android 235