1 /*
2 * Copyright (C) 2017 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 "SimpleC2Interface"
19 #include <utils/Log.h>
20
21 // use MediaDefs here vs. MediaCodecConstants as this is not MediaCodec specific/dependent
22 #include <media/stagefright/foundation/MediaDefs.h>
23
24 #include <C2PlatformSupport.h>
25 #include <SimpleC2Interface.h>
26
27 namespace android {
28
29 /* SimpleInterface */
30
BaseParams(const std::shared_ptr<C2ReflectorHelper> & reflector,C2String name,C2Component::kind_t kind,C2Component::domain_t domain,C2String mediaType,std::vector<C2String> aliases)31 SimpleInterface<void>::BaseParams::BaseParams(
32 const std::shared_ptr<C2ReflectorHelper> &reflector,
33 C2String name,
34 C2Component::kind_t kind,
35 C2Component::domain_t domain,
36 C2String mediaType,
37 std::vector<C2String> aliases)
38 : C2InterfaceHelper(reflector) {
39 setDerivedInstance(this);
40
41 addParameter(
42 DefineParam(mApiFeatures, C2_PARAMKEY_API_FEATURES)
43 .withConstValue(new C2ApiFeaturesSetting(C2Config::api_feature_t(
44 API_REFLECTION |
45 API_VALUES |
46 API_CURRENT_VALUES |
47 API_DEPENDENCY |
48 API_SAME_INPUT_BUFFER)))
49 .build());
50
51 addParameter(
52 DefineParam(mName, C2_PARAMKEY_COMPONENT_NAME)
53 .withConstValue(AllocSharedString<C2ComponentNameSetting>(name.c_str()))
54 .build());
55
56 if (aliases.size()) {
57 C2String joined;
58 for (const C2String &alias : aliases) {
59 if (joined.length()) {
60 joined += ",";
61 }
62 joined += alias;
63 }
64 addParameter(
65 DefineParam(mAliases, C2_PARAMKEY_COMPONENT_ALIASES)
66 .withConstValue(AllocSharedString<C2ComponentAliasesSetting>(joined.c_str()))
67 .build());
68 }
69
70 addParameter(
71 DefineParam(mKind, C2_PARAMKEY_COMPONENT_KIND)
72 .withConstValue(new C2ComponentKindSetting(kind))
73 .build());
74
75 addParameter(
76 DefineParam(mDomain, C2_PARAMKEY_COMPONENT_DOMAIN)
77 .withConstValue(new C2ComponentDomainSetting(domain))
78 .build());
79
80 // simple interfaces have single streams
81 addParameter(
82 DefineParam(mInputStreamCount, C2_PARAMKEY_INPUT_STREAM_COUNT)
83 .withConstValue(new C2PortStreamCountTuning::input(1))
84 .build());
85
86 addParameter(
87 DefineParam(mOutputStreamCount, C2_PARAMKEY_OUTPUT_STREAM_COUNT)
88 .withConstValue(new C2PortStreamCountTuning::output(1))
89 .build());
90
91 // set up buffer formats and allocators
92
93 // default to linear buffers and no media type
94 C2BufferData::type_t rawBufferType = C2BufferData::LINEAR;
95 C2String rawMediaType;
96 C2Allocator::id_t rawAllocator = C2AllocatorStore::DEFAULT_LINEAR;
97 C2BlockPool::local_id_t rawPoolId = C2BlockPool::BASIC_LINEAR;
98 C2BufferData::type_t codedBufferType = C2BufferData::LINEAR;
99 int poolMask = GetCodec2PoolMask();
100 C2Allocator::id_t preferredLinearId = GetPreferredLinearAllocatorId(poolMask);
101 C2Allocator::id_t codedAllocator = preferredLinearId;
102 C2BlockPool::local_id_t codedPoolId = C2BlockPool::BASIC_LINEAR;
103
104 switch (domain) {
105 case C2Component::DOMAIN_IMAGE: [[fallthrough]];
106 case C2Component::DOMAIN_VIDEO:
107 // TODO: should we define raw image? The only difference is timestamp handling
108 rawBufferType = C2BufferData::GRAPHIC;
109 rawMediaType = MEDIA_MIMETYPE_VIDEO_RAW;
110 rawAllocator = C2PlatformAllocatorStore::GRALLOC;
111 rawPoolId = C2BlockPool::BASIC_GRAPHIC;
112 break;
113 case C2Component::DOMAIN_AUDIO:
114 rawBufferType = C2BufferData::LINEAR;
115 rawMediaType = MEDIA_MIMETYPE_AUDIO_RAW;
116 rawAllocator = preferredLinearId;
117 rawPoolId = C2BlockPool::BASIC_LINEAR;
118 break;
119 default:
120 break;
121 }
122 bool isEncoder = kind == C2Component::KIND_ENCODER;
123
124 // handle raw decoders
125 if (mediaType == rawMediaType) {
126 codedBufferType = rawBufferType;
127 codedAllocator = rawAllocator;
128 codedPoolId = rawPoolId;
129 }
130
131 addParameter(
132 DefineParam(mInputFormat, C2_PARAMKEY_INPUT_STREAM_BUFFER_TYPE)
133 .withConstValue(new C2StreamBufferTypeSetting::input(
134 0u, isEncoder ? rawBufferType : codedBufferType))
135 .build());
136
137 addParameter(
138 DefineParam(mInputMediaType, C2_PARAMKEY_INPUT_MEDIA_TYPE)
139 .withConstValue(AllocSharedString<C2PortMediaTypeSetting::input>(
140 isEncoder ? rawMediaType : mediaType))
141 .build());
142
143 addParameter(
144 DefineParam(mOutputFormat, C2_PARAMKEY_OUTPUT_STREAM_BUFFER_TYPE)
145 .withConstValue(new C2StreamBufferTypeSetting::output(
146 0u, isEncoder ? codedBufferType : rawBufferType))
147 .build());
148
149 addParameter(
150 DefineParam(mOutputMediaType, C2_PARAMKEY_OUTPUT_MEDIA_TYPE)
151 .withConstValue(AllocSharedString<C2PortMediaTypeSetting::output>(
152 isEncoder ? mediaType : rawMediaType))
153 .build());
154
155 C2Allocator::id_t inputAllocators[1] = { isEncoder ? rawAllocator : codedAllocator };
156 C2Allocator::id_t outputAllocators[1] = { isEncoder ? codedAllocator : rawAllocator };
157 C2BlockPool::local_id_t outputPoolIds[1] = { isEncoder ? codedPoolId : rawPoolId };
158
159 addParameter(
160 DefineParam(mInputAllocators, C2_PARAMKEY_INPUT_ALLOCATORS)
161 .withDefault(C2PortAllocatorsTuning::input::AllocShared(inputAllocators))
162 .withFields({ C2F(mInputAllocators, m.values[0]).any(),
163 C2F(mInputAllocators, m.values).inRange(0, 1) })
164 .withSetter(Setter<C2PortAllocatorsTuning::input>::NonStrictValuesWithNoDeps)
165 .build());
166
167 addParameter(
168 DefineParam(mOutputAllocators, C2_PARAMKEY_OUTPUT_ALLOCATORS)
169 .withDefault(C2PortAllocatorsTuning::output::AllocShared(outputAllocators))
170 .withFields({ C2F(mOutputAllocators, m.values[0]).any(),
171 C2F(mOutputAllocators, m.values).inRange(0, 1) })
172 .withSetter(Setter<C2PortAllocatorsTuning::output>::NonStrictValuesWithNoDeps)
173 .build());
174
175 addParameter(
176 DefineParam(mOutputPoolIds, C2_PARAMKEY_OUTPUT_BLOCK_POOLS)
177 .withDefault(C2PortBlockPoolsTuning::output::AllocShared(outputPoolIds))
178 .withFields({ C2F(mOutputPoolIds, m.values[0]).any(),
179 C2F(mOutputPoolIds, m.values).inRange(0, 1) })
180 .withSetter(Setter<C2PortBlockPoolsTuning::output>::NonStrictValuesWithNoDeps)
181 .build());
182
183 // add stateless params
184 addParameter(
185 DefineParam(mSubscribedParamIndices, C2_PARAMKEY_SUBSCRIBED_PARAM_INDICES)
186 .withDefault(C2SubscribedParamIndicesTuning::AllocShared(0u))
187 .withFields({ C2F(mSubscribedParamIndices, m.values[0]).any(),
188 C2F(mSubscribedParamIndices, m.values).any() })
189 .withSetter(Setter<C2SubscribedParamIndicesTuning>::NonStrictValuesWithNoDeps)
190 .build());
191
192 /* TODO
193
194 addParameter(
195 DefineParam(mCurrentWorkOrdinal, C2_PARAMKEY_CURRENT_WORK)
196 .withDefault(new C2CurrentWorkTuning())
197 .withFields({ C2F(mCurrentWorkOrdinal, m.timeStamp).any(),
198 C2F(mCurrentWorkOrdinal, m.frameIndex).any(),
199 C2F(mCurrentWorkOrdinal, m.customOrdinal).any() })
200 .withSetter(Setter<C2CurrentWorkTuning>::NonStrictValuesWithNoDeps)
201 .build());
202
203 addParameter(
204 DefineParam(mLastInputQueuedWorkOrdinal, C2_PARAMKEY_LAST_INPUT_QUEUED)
205 .withDefault(new C2LastWorkQueuedTuning::input())
206 .withFields({ C2F(mLastInputQueuedWorkOrdinal, m.timeStamp).any(),
207 C2F(mLastInputQueuedWorkOrdinal, m.frameIndex).any(),
208 C2F(mLastInputQueuedWorkOrdinal, m.customOrdinal).any() })
209 .withSetter(Setter<C2LastWorkQueuedTuning::input>::NonStrictValuesWithNoDeps)
210 .build());
211
212 addParameter(
213 DefineParam(mLastOutputQueuedWorkOrdinal, C2_PARAMKEY_LAST_OUTPUT_QUEUED)
214 .withDefault(new C2LastWorkQueuedTuning::output())
215 .withFields({ C2F(mLastOutputQueuedWorkOrdinal, m.timeStamp).any(),
216 C2F(mLastOutputQueuedWorkOrdinal, m.frameIndex).any(),
217 C2F(mLastOutputQueuedWorkOrdinal, m.customOrdinal).any() })
218 .withSetter(Setter<C2LastWorkQueuedTuning::output>::NonStrictValuesWithNoDeps)
219 .build());
220
221 std::shared_ptr<C2OutOfMemoryTuning> mOutOfMemory;
222
223 std::shared_ptr<C2PortConfigCounterTuning::input> mInputConfigCounter;
224 std::shared_ptr<C2PortConfigCounterTuning::output> mOutputConfigCounter;
225 std::shared_ptr<C2ConfigCounterTuning> mDirectConfigCounter;
226
227 */
228 }
229
noInputLatency()230 void SimpleInterface<void>::BaseParams::noInputLatency() {
231 addParameter(
232 DefineParam(mRequestedInputDelay, C2_PARAMKEY_INPUT_DELAY_REQUEST)
233 .withConstValue(new C2PortRequestedDelayTuning::input(0u))
234 .build());
235
236 addParameter(
237 DefineParam(mActualInputDelay, C2_PARAMKEY_INPUT_DELAY)
238 .withConstValue(new C2PortActualDelayTuning::input(0u))
239 .build());
240 }
241
noOutputLatency()242 void SimpleInterface<void>::BaseParams::noOutputLatency() {
243 addParameter(
244 DefineParam(mRequestedOutputDelay, C2_PARAMKEY_OUTPUT_DELAY_REQUEST)
245 .withConstValue(new C2PortRequestedDelayTuning::output(0u))
246 .build());
247
248 addParameter(
249 DefineParam(mActualOutputDelay, C2_PARAMKEY_OUTPUT_DELAY)
250 .withConstValue(new C2PortActualDelayTuning::output(0u))
251 .build());
252 }
253
noPipelineLatency()254 void SimpleInterface<void>::BaseParams::noPipelineLatency() {
255 addParameter(
256 DefineParam(mRequestedPipelineDelay, C2_PARAMKEY_PIPELINE_DELAY_REQUEST)
257 .withConstValue(new C2RequestedPipelineDelayTuning(0u))
258 .build());
259
260 addParameter(
261 DefineParam(mActualPipelineDelay, C2_PARAMKEY_PIPELINE_DELAY)
262 .withConstValue(new C2ActualPipelineDelayTuning(0u))
263 .build());
264 }
265
noPrivateBuffers()266 void SimpleInterface<void>::BaseParams::noPrivateBuffers() {
267 addParameter(
268 DefineParam(mPrivateAllocators, C2_PARAMKEY_PRIVATE_ALLOCATORS)
269 .withConstValue(C2PrivateAllocatorsTuning::AllocShared(0u))
270 .build());
271
272 addParameter(
273 DefineParam(mMaxPrivateBufferCount, C2_PARAMKEY_MAX_PRIVATE_BUFFER_COUNT)
274 .withConstValue(C2MaxPrivateBufferCountTuning::AllocShared(0u))
275 .build());
276
277 addParameter(
278 DefineParam(mPrivatePoolIds, C2_PARAMKEY_PRIVATE_BLOCK_POOLS)
279 .withConstValue(C2PrivateBlockPoolsTuning::AllocShared(0u))
280 .build());
281 }
282
noInputReferences()283 void SimpleInterface<void>::BaseParams::noInputReferences() {
284 addParameter(
285 DefineParam(mMaxInputReferenceAge, C2_PARAMKEY_INPUT_MAX_REFERENCE_AGE)
286 .withConstValue(new C2StreamMaxReferenceAgeTuning::input(0u))
287 .build());
288
289 addParameter(
290 DefineParam(mMaxInputReferenceCount, C2_PARAMKEY_INPUT_MAX_REFERENCE_COUNT)
291 .withConstValue(new C2StreamMaxReferenceCountTuning::input(0u))
292 .build());
293 }
294
noOutputReferences()295 void SimpleInterface<void>::BaseParams::noOutputReferences() {
296 addParameter(
297 DefineParam(mMaxOutputReferenceAge, C2_PARAMKEY_OUTPUT_MAX_REFERENCE_AGE)
298 .withConstValue(new C2StreamMaxReferenceAgeTuning::output(0u))
299 .build());
300
301 addParameter(
302 DefineParam(mMaxOutputReferenceCount, C2_PARAMKEY_OUTPUT_MAX_REFERENCE_COUNT)
303 .withConstValue(new C2StreamMaxReferenceCountTuning::output(0u))
304 .build());
305 }
306
noTimeStretch()307 void SimpleInterface<void>::BaseParams::noTimeStretch() {
308 addParameter(
309 DefineParam(mTimeStretch, C2_PARAMKEY_TIME_STRETCH)
310 .withConstValue(new C2ComponentTimeStretchTuning(1.f))
311 .build());
312 }
313
314 /*
315 Clients need to handle the following base params due to custom dependency.
316
317 std::shared_ptr<C2ApiLevelSetting> mApiLevel;
318 std::shared_ptr<C2ComponentAttributesSetting> mAttrib;
319
320 std::shared_ptr<C2PortSuggestedBufferCountTuning::input> mSuggestedInputBufferCount;
321 std::shared_ptr<C2PortSuggestedBufferCountTuning::output> mSuggestedOutputBufferCount;
322
323 std::shared_ptr<C2TrippedTuning> mTripped;
324
325 */
326
327 } // namespace android
328