blob: cb429820f898f365bbda6a7fa180fd6cc76fd964 [file] [log] [blame]
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef ANDROID_MEDIA_ECO_DATA_H_
#define ANDROID_MEDIA_ECO_DATA_H_
#include <binder/Parcel.h>
#include <binder/Parcelable.h>
#include <string>
#include <unordered_map>
#include <variant>
namespace android {
namespace media {
namespace eco {
enum class ECODataStatus {
OK,
FAIL_TO_INSERT,
INVALID_ECODATA_TYPE,
KEY_NOT_EXIST,
INVALID_VALUE_TYPE,
INVALID_ARGUMENT,
};
/**
* ECOData is the container for all messages passed between different components in ECOService.
* All messages in ECOServices are represented by a list of key-value pairs.
* For example:
* "bit-rate" -> 22000000
* "Provider-Name" -> "QCOM-Video-Encoder".
* "avg-frame-qp" -> 40
* ECOData follows the same design pattern of AMessage and Metadata in Media Framework. The key
* must be non-empty string. Below are the supported data types:
*
* // Item types set/find function suffixes
* // ==========================================
* // int32_t Int32
* // int64_t Int64
* // size_t Size
* // float Float
* // double Double
* // String String
*
* ECOData does not support duplicate keys with different values. When inserting a key-value pair,
* a new entry will be created if the key does not exist. Othewise, they key's value will be
* overwritten with the new value.
*
* Sample usage:
*
* // Create the ECOData
* std::unique_ptr<ECOData> data = std::make_unique<ECOData>(ECOData::DATA_TYPE_STATS, 1000);
*
* // Set the encoder name.
* data->setString("stats-encoder-type", "google-avc");
*
* // Set encoding bitrate.
* data->setInt32("stats-encoder-target-bitrate-bps", 22000000);
*/
class ECOData : public Parcelable {
public:
using ECODataValueType =
std::variant<int32_t, int64_t, size_t, float, double, std::string, int8_t>;
using ECODataKeyValuePair = std::pair<std::string, ECODataValueType>;
ECOData() : mDataType(0), mDataTimeUs(-1) {}
ECOData(int32_t type) : mDataType(type), mDataTimeUs(-1) {}
ECOData(int32_t type, int64_t timeUs) : mDataType(type), mDataTimeUs(timeUs) {}
// Constants for mDataType.
typedef enum {
DATA_TYPE_UNKNOWN = 0,
/* Data sent from the ECOServiceStatsProvider to ECOService. */
DATA_TYPE_STATS = 1,
/* Data sent from the ECOService to ECOServiceInfoListener. */
DATA_TYPE_INFO = 2,
/* Configuration data sent by ECOServiceStatsProvider when connects with ECOService. */
DATA_TYPE_STATS_PROVIDER_CONFIG = 3,
/* Configuration data sent by ECOServiceInfoListener when connects with ECOService. */
DATA_TYPE_INFO_LISTENER_CONFIG = 4,
} ECODatatype;
// set/find functions that could be used for all the value types.
ECODataStatus set(const std::string& key, const ECODataValueType& value);
ECODataStatus find(const std::string& key, ECODataValueType* out) const;
// Convenient set/find functions for string value type.
ECODataStatus setString(const std::string& key, const std::string& value);
ECODataStatus findString(const std::string& key, std::string* out) const;
// Convenient set/find functions for int32_t value type.
ECODataStatus setInt32(const std::string& key, int32_t value);
ECODataStatus findInt32(const std::string& key, int32_t* out) const;
// Convenient set/find functions for int64_t value type.
ECODataStatus setInt64(const std::string& key, int64_t value);
ECODataStatus findInt64(const std::string& key, int64_t* out) const;
// Convenient set/find functions for float value type.
ECODataStatus setFloat(const std::string& key, float value);
ECODataStatus findFloat(const std::string& key, float* out) const;
// Convenient set/find functions for double value type.
ECODataStatus setDouble(const std::string& key, double value);
ECODataStatus findDouble(const std::string& key, double* out) const;
// Convenient set/find functions for size_t value type.
ECODataStatus setSize(const std::string& key, size_t value);
ECODataStatus findSize(const std::string& key, size_t* out) const;
// Convenient set/find functions for int8_t value type.
// TODO(hkuang): Add unit test.
ECODataStatus setInt8(const std::string& key, int8_t value);
ECODataStatus findInt8(const std::string& key, int8_t* out) const;
/**
* Serialization over Binder
*/
status_t readFromParcel(const Parcel* parcel) override;
status_t writeToParcel(Parcel* parcel) const override;
/* Returns the type of the data. */
int32_t getDataType() const;
/* Returns the type of the data in string. */
std::string getDataTypeString() const;
/* Returns the timestamp associated with the data. */
int64_t getDataTimeUs() const;
/* Sets the type of the data. */
void setDataType(int32_t type);
/* Sets the timestamp associated with the data. */
void setDataTimeUs();
/* Gets the number of keys in the ECOData. */
size_t getNumOfEntries() const { return mKeyValueStore.size(); }
/* Whether the ECOData is empty. */
size_t isEmpty() const { return mKeyValueStore.size() == 0; }
friend class ECODataKeyValueIterator;
friend bool copyKeyValue(const ECOData& src, ECOData* dst);
// Dump the ECOData as a string.
std::string debugString() const;
protected:
// ValueType. This must match the index in ECODataValueType.
enum ValueType {
kTypeInt32 = 0,
kTypeInt64 = 1,
kTypeSize = 2,
kTypeFloat = 3,
kTypeDouble = 4,
kTypeString = 5,
kTypeInt8 = 6,
};
/* The type of the data */
int32_t mDataType;
// The timestamp time associated with the data in microseconds. The timestamp should be in
// boottime time base. This is only used when the data type is stats or info. -1 means
// unavailable.
int64_t mDataTimeUs;
// Internal store for the key value pairs.
std::unordered_map<std::string, ECODataValueType> mKeyValueStore;
template <typename T>
ECODataStatus setValue(const std::string& key, T value);
template <typename T>
ECODataStatus findValue(const std::string& key, T* out) const;
};
// A simple ECOData iterator that will iterate over all the key value paris in ECOData.
// To be used like:
// while (it.hasNext()) {
// entry = it.next();
// }
class ECODataKeyValueIterator {
public:
ECODataKeyValueIterator(const ECOData& data)
: mKeyValueStore(data.mKeyValueStore), mBeginReturned(false) {
mIterator = mKeyValueStore.begin();
}
~ECODataKeyValueIterator() = default;
bool hasNext();
ECOData::ECODataKeyValuePair next() const;
private:
const std::unordered_map<std::string, ECOData::ECODataValueType>& mKeyValueStore;
std::unordered_map<std::string, ECOData::ECODataValueType>::const_iterator mIterator;
bool mBeginReturned;
};
} // namespace eco
} // namespace media
} // namespace android
#endif // ANDROID_MEDIA_ECO_DATA_H_