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