1 /*
2 * Copyright (C) 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 "FormatShaper"
19 #include <utils/Log.h>
20
21 #include <string>
22 #include <inttypes.h>
23
24 #include <media/NdkMediaFormat.h>
25
26 #include "CodecProperties.h"
27 #include "VideoShaper.h"
28 #include "VQops.h"
29
30 #include <media/formatshaper/FormatShaper.h>
31
32 namespace android {
33 namespace mediaformatshaper {
34
35 //
36 // Caller retains ownership of and responsibility for inFormat
37 //
38
39 //
40 // the interface to the outside
41 //
42
shapeFormat(shaperHandle_t shaper,AMediaFormat * inFormat,int flags)43 int shapeFormat(shaperHandle_t shaper, AMediaFormat* inFormat, int flags) {
44 CodecProperties *codec = (CodecProperties*) shaper;
45 if (codec == nullptr) {
46 return -1;
47 }
48 if (!codec->isRegistered()) {
49 return -1;
50 }
51
52 // run through the list of possible transformations
53 //
54
55 std::string mediaType = codec->getMediaType();
56 if (strncmp(mediaType.c_str(), "video/", 6) == 0) {
57 // video specific shaping
58 (void) videoShaper(codec, inFormat, flags);
59
60 } else if (strncmp(mediaType.c_str(), "audio/", 6) == 0) {
61 // audio specific shaping
62
63 } else {
64 ALOGV("unknown mediatype '%s', left untouched", mediaType.c_str());
65
66 }
67
68 return 0;
69 }
70
setMap(shaperHandle_t shaper,const char * kind,const char * key,const char * value)71 int setMap(shaperHandle_t shaper, const char *kind, const char *key, const char *value) {
72 ALOGV("setMap: kind %s key %s -> value %s", kind, key, value);
73 CodecProperties *codec = (CodecProperties*) shaper;
74 if (codec == nullptr) {
75 return -1;
76 }
77 // must not yet be registered
78 if (codec->isRegistered()) {
79 return -1;
80 }
81
82 codec->setMapping(kind, key, value);
83 return 0;
84 }
85
setFeature(shaperHandle_t shaper,const char * feature,int value)86 int setFeature(shaperHandle_t shaper, const char *feature, int value) {
87 ALOGV("set_feature: feature %s value %d", feature, value);
88 CodecProperties *codec = (CodecProperties*) shaper;
89 if (codec == nullptr) {
90 return -1;
91 }
92 // must not yet be registered
93 if (codec->isRegistered()) {
94 return -1;
95 }
96
97 // save a map of all features
98 codec->setFeatureValue(feature, value);
99
100 return 0;
101 }
102
setTuning(shaperHandle_t shaper,const char * tuning,const char * value)103 int setTuning(shaperHandle_t shaper, const char *tuning, const char *value) {
104 ALOGV("setTuning: tuning %s value %s", tuning, value);
105 CodecProperties *codec = (CodecProperties*) shaper;
106 if (codec == nullptr) {
107 return -1;
108 }
109 // must not yet be registered
110 if (codec->isRegistered()) {
111 return -1;
112 }
113
114 // save a map of all features
115 codec->setTuningValue(tuning, value);
116
117 return 0;
118 }
119
120 /*
121 * The routines that manage finding, creating, and registering the shapers.
122 */
123
findShaper(const char * codecName,const char * mediaType)124 shaperHandle_t findShaper(const char *codecName, const char *mediaType) {
125 CodecProperties *codec = findCodec(codecName, mediaType);
126 return (shaperHandle_t) codec;
127 }
128
createShaper(const char * codecName,const char * mediaType)129 shaperHandle_t createShaper(const char *codecName, const char *mediaType) {
130 CodecProperties *codec = new CodecProperties(codecName, mediaType);
131 if (codec != nullptr) {
132 codec->Seed();
133 }
134 return (shaperHandle_t) codec;
135 }
136
registerShaper(shaperHandle_t shaper,const char * codecName,const char * mediaType)137 shaperHandle_t registerShaper(shaperHandle_t shaper, const char *codecName, const char *mediaType) {
138 ALOGV("registerShaper(handle, codecName %s, mediaType %s", codecName, mediaType);
139 CodecProperties *codec = (CodecProperties*) shaper;
140 if (codec == nullptr) {
141 return nullptr;
142 }
143 // must not yet be registered
144 if (codec->isRegistered()) {
145 return nullptr;
146 }
147
148 // any final cleanup for the parameters. This allows us to override
149 // bad parameters from a devices XML file.
150 codec->Finish();
151
152 // may return a different codec, if we lost a race.
153 // if so, registerCodec() reclaims the one we tried to register for us.
154 codec = registerCodec(codec, codecName, mediaType);
155 return (shaperHandle_t) codec;
156 }
157
158 // mapping & unmapping
159 // give me the mappings for 'kind'.
160 // kind==null (or empty string), means *all* mappings
161
getMappings(shaperHandle_t shaper,const char * kind)162 const char **getMappings(shaperHandle_t shaper, const char *kind) {
163 CodecProperties *codec = (CodecProperties*) shaper;
164 if (codec == nullptr)
165 return nullptr;
166 if (kind == nullptr)
167 kind = "";
168
169 return codec->getMappings(kind, /* reverse */ false);
170 }
171
getReverseMappings(shaperHandle_t shaper,const char * kind)172 const char **getReverseMappings(shaperHandle_t shaper, const char *kind) {
173 CodecProperties *codec = (CodecProperties*) shaper;
174 if (codec == nullptr)
175 return nullptr;
176 if (kind == nullptr)
177 kind = "";
178
179 return codec->getMappings(kind, /* reverse */ true);
180 }
181
182
183 // the system grabs this structure
184 __attribute__ ((visibility ("default")))
185 extern "C" FormatShaperOps_t shaper_ops = {
186 .version = SHAPER_VERSION_V1,
187
188 .findShaper = findShaper,
189 .createShaper = createShaper,
190 .setMap = setMap,
191 .setFeature = setFeature,
192 .registerShaper = registerShaper,
193
194 .shapeFormat = shapeFormat,
195 .getMappings = getMappings,
196 .getReverseMappings = getReverseMappings,
197
198 .setTuning = setTuning,
199 };
200
201 } // namespace mediaformatshaper
202 } // namespace android
203
204