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