1 /* 2 * Copyright (C) 2019 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 #ifndef ANDROID_MEDIA_ECO_DATA_H_ 18 #define ANDROID_MEDIA_ECO_DATA_H_ 19 20 #include <binder/Parcel.h> 21 #include <binder/Parcelable.h> 22 23 #include <string> 24 #include <unordered_map> 25 #include <variant> 26 27 namespace android { 28 namespace media { 29 namespace eco { 30 31 enum class ECODataStatus { 32 OK, 33 FAIL_TO_INSERT, 34 INVALID_ECODATA_TYPE, 35 KEY_NOT_EXIST, 36 INVALID_VALUE_TYPE, 37 INVALID_ARGUMENT, 38 }; 39 40 /** 41 * ECOData is the container for all messages passed between different components in ECOService. 42 * All messages in ECOServices are represented by a list of key-value pairs. 43 * For example: 44 * "bit-rate" -> 22000000 45 * "Provider-Name" -> "QCOM-Video-Encoder". 46 * "avg-frame-qp" -> 40 47 * ECOData follows the same design pattern of AMessage and Metadata in Media Framework. The key 48 * must be non-empty string. Below are the supported data types: 49 * 50 * // Item types set/find function suffixes 51 * // ========================================== 52 * // int32_t Int32 53 * // int64_t Int64 54 * // size_t Size 55 * // float Float 56 * // double Double 57 * // String String 58 * 59 * ECOData does not support duplicate keys with different values. When inserting a key-value pair, 60 * a new entry will be created if the key does not exist. Othewise, they key's value will be 61 * overwritten with the new value. 62 * 63 * Sample usage: 64 * 65 * // Create the ECOData 66 * std::unique_ptr<ECOData> data = std::make_unique<ECOData>(ECOData::DATA_TYPE_STATS, 1000); 67 * 68 * // Set the encoder name. 69 * data->setString("stats-encoder-type", "google-avc"); 70 * 71 * // Set encoding bitrate. 72 * data->setInt32("stats-encoder-target-bitrate-bps", 22000000); 73 */ 74 class ECOData : public Parcelable { 75 public: 76 using ECODataValueType = 77 std::variant<int32_t, int64_t, size_t, float, double, std::string, int8_t>; 78 using ECODataKeyValuePair = std::pair<std::string, ECODataValueType>; 79 ECOData()80 ECOData() : mDataType(0), mDataTimeUs(-1) {} ECOData(int32_t type)81 ECOData(int32_t type) : mDataType(type), mDataTimeUs(-1) {} ECOData(int32_t type,int64_t timeUs)82 ECOData(int32_t type, int64_t timeUs) : mDataType(type), mDataTimeUs(timeUs) {} 83 84 // Constants for mDataType. 85 typedef enum { 86 DATA_TYPE_UNKNOWN = 0, 87 /* Data sent from the ECOServiceStatsProvider to ECOService. */ 88 DATA_TYPE_STATS = 1, 89 /* Data sent from the ECOService to ECOServiceInfoListener. */ 90 DATA_TYPE_INFO = 2, 91 /* Configuration data sent by ECOServiceStatsProvider when connects with ECOService. */ 92 DATA_TYPE_STATS_PROVIDER_CONFIG = 3, 93 /* Configuration data sent by ECOServiceInfoListener when connects with ECOService. */ 94 DATA_TYPE_INFO_LISTENER_CONFIG = 4, 95 } ECODatatype; 96 97 // set/find functions that could be used for all the value types. 98 ECODataStatus set(const std::string& key, const ECODataValueType& value); 99 ECODataStatus find(const std::string& key, ECODataValueType* out) const; 100 101 // Convenient set/find functions for string value type. 102 ECODataStatus setString(const std::string& key, const std::string& value); 103 ECODataStatus findString(const std::string& key, std::string* out) const; 104 105 // Convenient set/find functions for int32_t value type. 106 ECODataStatus setInt32(const std::string& key, int32_t value); 107 ECODataStatus findInt32(const std::string& key, int32_t* out) const; 108 109 // Convenient set/find functions for int64_t value type. 110 ECODataStatus setInt64(const std::string& key, int64_t value); 111 ECODataStatus findInt64(const std::string& key, int64_t* out) const; 112 113 // Convenient set/find functions for float value type. 114 ECODataStatus setFloat(const std::string& key, float value); 115 ECODataStatus findFloat(const std::string& key, float* out) const; 116 117 // Convenient set/find functions for double value type. 118 ECODataStatus setDouble(const std::string& key, double value); 119 ECODataStatus findDouble(const std::string& key, double* out) const; 120 121 // Convenient set/find functions for size_t value type. 122 ECODataStatus setSize(const std::string& key, size_t value); 123 ECODataStatus findSize(const std::string& key, size_t* out) const; 124 125 // Convenient set/find functions for int8_t value type. 126 // TODO(hkuang): Add unit test. 127 ECODataStatus setInt8(const std::string& key, int8_t value); 128 ECODataStatus findInt8(const std::string& key, int8_t* out) const; 129 130 /** 131 * Serialization over Binder 132 */ 133 status_t readFromParcel(const Parcel* parcel) override; 134 status_t writeToParcel(Parcel* parcel) const override; 135 136 /* Returns the type of the data. */ 137 int32_t getDataType() const; 138 139 /* Returns the type of the data in string. */ 140 std::string getDataTypeString() const; 141 142 /* Returns the timestamp associated with the data. */ 143 int64_t getDataTimeUs() const; 144 145 /* Sets the type of the data. */ 146 void setDataType(int32_t type); 147 148 /* Sets the timestamp associated with the data. */ 149 void setDataTimeUs(); 150 151 /* Gets the number of keys in the ECOData. */ getNumOfEntries()152 size_t getNumOfEntries() const { return mKeyValueStore.size(); } 153 154 /* Whether the ECOData is empty. */ isEmpty()155 size_t isEmpty() const { return mKeyValueStore.size() == 0; } 156 157 friend class ECODataKeyValueIterator; 158 159 friend bool copyKeyValue(const ECOData& src, ECOData* dst); 160 161 // Dump the ECOData as a string. 162 std::string debugString() const; 163 164 protected: 165 // ValueType. This must match the index in ECODataValueType. 166 enum ValueType { 167 kTypeInt32 = 0, 168 kTypeInt64 = 1, 169 kTypeSize = 2, 170 kTypeFloat = 3, 171 kTypeDouble = 4, 172 kTypeString = 5, 173 kTypeInt8 = 6, 174 }; 175 176 /* The type of the data */ 177 int32_t mDataType; 178 179 // The timestamp time associated with the data in microseconds. The timestamp should be in 180 // boottime time base. This is only used when the data type is stats or info. -1 means 181 // unavailable. 182 int64_t mDataTimeUs; 183 184 // Internal store for the key value pairs. 185 std::unordered_map<std::string, ECODataValueType> mKeyValueStore; 186 187 template <typename T> 188 ECODataStatus setValue(const std::string& key, T value); 189 190 template <typename T> 191 ECODataStatus findValue(const std::string& key, T* out) const; 192 }; 193 194 // A simple ECOData iterator that will iterate over all the key value paris in ECOData. 195 // To be used like: 196 // while (it.hasNext()) { 197 // entry = it.next(); 198 // } 199 class ECODataKeyValueIterator { 200 public: ECODataKeyValueIterator(const ECOData & data)201 ECODataKeyValueIterator(const ECOData& data) 202 : mKeyValueStore(data.mKeyValueStore), mBeginReturned(false) { 203 mIterator = mKeyValueStore.begin(); 204 } 205 ~ECODataKeyValueIterator() = default; 206 bool hasNext(); 207 ECOData::ECODataKeyValuePair next() const; 208 209 private: 210 const std::unordered_map<std::string, ECOData::ECODataValueType>& mKeyValueStore; 211 std::unordered_map<std::string, ECOData::ECODataValueType>::const_iterator mIterator; 212 bool mBeginReturned; 213 }; 214 215 } // namespace eco 216 } // namespace media 217 } // namespace android 218 219 #endif // ANDROID_MEDIA_ECO_DATA_H_ 220