| Ray Essick | 1831f7b | 2021-03-15 16:10:51 -0700 | [diff] [blame] | 1 | /* | 
|  | 2 | * Copyright 2021, 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 | //#define LOG_NDEBUG 0 | 
|  | 18 | #define LOG_TAG "CodecProperties" | 
|  | 19 | #include <utils/Log.h> | 
|  | 20 |  | 
|  | 21 | #include <string> | 
|  | 22 |  | 
|  | 23 | #include <media/formatshaper/CodecProperties.h> | 
|  | 24 |  | 
|  | 25 | namespace android { | 
|  | 26 | namespace mediaformatshaper { | 
|  | 27 |  | 
|  | 28 | CodecProperties::CodecProperties(std::string name, std::string mediaType) { | 
|  | 29 | mName = name; | 
|  | 30 | mMediaType = mediaType; | 
|  | 31 | } | 
|  | 32 |  | 
|  | 33 | std::string CodecProperties::getName(){ | 
|  | 34 | return mName; | 
|  | 35 | } | 
|  | 36 |  | 
|  | 37 | std::string CodecProperties::getMediaType(){ | 
|  | 38 | return mMediaType; | 
|  | 39 | } | 
|  | 40 |  | 
|  | 41 | int CodecProperties::supportedMinimumQuality() { | 
|  | 42 | return mMinimumQuality; | 
|  | 43 | } | 
|  | 44 | void CodecProperties::setSupportedMinimumQuality(int vmaf) { | 
|  | 45 | mMinimumQuality = vmaf; | 
|  | 46 | } | 
|  | 47 |  | 
|  | 48 | int CodecProperties::targetQpMax() { | 
|  | 49 | return mTargetQpMax; | 
|  | 50 | } | 
|  | 51 | void CodecProperties::setTargetQpMax(int qpMax) { | 
|  | 52 | mTargetQpMax = qpMax; | 
|  | 53 | } | 
|  | 54 |  | 
|  | 55 | // what API is this codec set up for (e.g. API of the associated partition) | 
|  | 56 | // vendor-side (OEM) codecs may be older, due to 'vendor freeze' and treble | 
|  | 57 | int CodecProperties::supportedApi() { | 
|  | 58 | return mApi; | 
|  | 59 | } | 
|  | 60 |  | 
|  | 61 | std::string CodecProperties::getMapping(std::string key, std::string kind) { | 
|  | 62 | ALOGV("getMapping(key %s, kind %s )", key.c_str(), kind.c_str()); | 
|  | 63 | //play with mMappings | 
|  | 64 | auto mapped = mMappings.find(kind + "-" + key); | 
|  | 65 | if (mapped != mMappings.end()) { | 
|  | 66 | std::string result = mapped->second; | 
|  | 67 | ALOGV("getMapping(%s, %s) -> %s", key.c_str(), kind.c_str(), result.c_str()); | 
|  | 68 | return result; | 
|  | 69 | } | 
|  | 70 | ALOGV("nope, return unchanged key"); | 
|  | 71 | return key; | 
|  | 72 | } | 
|  | 73 |  | 
|  | 74 |  | 
|  | 75 | // really a bit of debugging code here. | 
|  | 76 | void CodecProperties::showMappings() { | 
|  | 77 | ALOGD("Mappings:"); | 
|  | 78 | int count = 0; | 
|  | 79 | for (const auto& [key, value] : mMappings) { | 
|  | 80 | count++; | 
|  | 81 | ALOGD("'%s' -> '%s'", key.c_str(), value.c_str()); | 
|  | 82 | } | 
|  | 83 | ALOGD("total %d mappings", count); | 
|  | 84 | } | 
|  | 85 |  | 
|  | 86 | void CodecProperties::setMapping(std::string kind, std::string key, std::string value) { | 
|  | 87 | ALOGV("setMapping(%s,%s,%s)", kind.c_str(), key.c_str(), value.c_str()); | 
|  | 88 | std::string metaKey = kind + "-" + key; | 
|  | 89 | mMappings.insert({metaKey, value}); | 
|  | 90 | } | 
|  | 91 |  | 
|  | 92 | const char **CodecProperties::getMappings(std::string kind, bool reverse) { | 
|  | 93 | ALOGV("getMappings(kind %s, reverse %d", kind.c_str(), reverse); | 
|  | 94 | // how many do we need? | 
|  | 95 | int count = mMappings.size(); | 
|  | 96 | if (count == 0) { | 
|  | 97 | ALOGV("empty mappings"); | 
|  | 98 | return nullptr; | 
|  | 99 | } | 
|  | 100 | size_t size = sizeof(char *) * (2 * count + 2); | 
|  | 101 | const char **result = (const char **)malloc(size); | 
|  | 102 | if (result == nullptr) { | 
|  | 103 | ALOGW("no memory to return mappings"); | 
|  | 104 | return nullptr; | 
|  | 105 | } | 
|  | 106 | memset(result, '\0', size); | 
|  | 107 |  | 
|  | 108 | const char **pp = result; | 
|  | 109 | for (const auto& [key, value] : mMappings) { | 
|  | 110 | // split out the kind/key | 
|  | 111 | size_t pos = key.find('-'); | 
|  | 112 | if (pos == std::string::npos) { | 
|  | 113 | ALOGD("ignoring malformed key: %s", key.c_str()); | 
|  | 114 | continue; | 
|  | 115 | } | 
|  | 116 | std::string actualKind = key.substr(0,pos); | 
|  | 117 | if (kind.length() != 0 && kind != actualKind) { | 
|  | 118 | ALOGD("kinds don't match: want '%s' got '%s'", kind.c_str(), actualKind.c_str()); | 
|  | 119 | continue; | 
|  | 120 | } | 
|  | 121 | if (reverse) { | 
|  | 122 | // codec specific -> std aka 'unmapping' | 
|  | 123 | pp[0] = strdup( value.c_str()); | 
|  | 124 | pp[1] = strdup( key.substr(pos+1).c_str()); | 
|  | 125 | } else { | 
|  | 126 | // std -> codec specific | 
|  | 127 | pp[0] = strdup( key.substr(pos+1).c_str()); | 
|  | 128 | pp[1] = strdup( value.c_str()); | 
|  | 129 | } | 
|  | 130 | ALOGV(" %s -> %s", pp[0], pp[1]); | 
|  | 131 | pp += 2; | 
|  | 132 | } | 
|  | 133 |  | 
|  | 134 | pp[0] = nullptr; | 
|  | 135 | pp[1] = nullptr; | 
|  | 136 |  | 
|  | 137 | return result; | 
|  | 138 | } | 
|  | 139 |  | 
|  | 140 |  | 
|  | 141 | } // namespace mediaformatshaper | 
|  | 142 | } // namespace android | 
|  | 143 |  |