1 /*
2 * Copyright 2019 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 #include "CCodecConfig.h"
18
19 #include <set>
20
21 #include <gtest/gtest.h>
22
23 #include <codec2/hidl/1.0/Configurable.h>
24 #include <codec2/hidl/client.h>
25 #include <util/C2InterfaceHelper.h>
26
27 #include <media/stagefright/MediaCodecConstants.h>
28
29 namespace {
30
31 enum ExtendedC2ParamIndexKind : C2Param::type_index_t {
32 kParamIndexVendorInt32 = C2Param::TYPE_INDEX_VENDOR_START,
33 kParamIndexVendorInt64,
34 kParamIndexVendorString,
35 };
36
37 typedef C2PortParam<C2Info, C2Int32Value, kParamIndexVendorInt32> C2PortVendorInt32Info;
38 constexpr char C2_PARAMKEY_VENDOR_INT32[] = "example.int32";
39 constexpr char KEY_VENDOR_INT32[] = "vendor.example.int32.value";
40
41 typedef C2StreamParam<C2Info, C2Int64Value, kParamIndexVendorInt64> C2StreamVendorInt64Info;
42 constexpr char C2_PARAMKEY_VENDOR_INT64[] = "example.int64";
43 constexpr char KEY_VENDOR_INT64[] = "vendor.example.int64.value";
44
45 typedef C2PortParam<C2Info, C2StringValue, kParamIndexVendorString> C2PortVendorStringInfo;
46 constexpr char C2_PARAMKEY_VENDOR_STRING[] = "example.string";
47 constexpr char KEY_VENDOR_STRING[] = "vendor.example.string.value";
48
49 } // namespace
50
51 namespace android {
52
53 class CCodecConfigTest : public ::testing::Test {
54 public:
55 constexpr static int32_t kCodec2Int32 = 0xC0DEC2;
56 constexpr static int64_t kCodec2Int64 = 0xC0DEC2C0DEC2ll;
57 constexpr static char kCodec2Str[] = "codec2";
58
CCodecConfigTest()59 CCodecConfigTest()
60 : mReflector{std::make_shared<C2ReflectorHelper>()} {
61 }
62
init(C2Component::domain_t domain,C2Component::kind_t kind,const char * mediaType)63 void init(
64 C2Component::domain_t domain,
65 C2Component::kind_t kind,
66 const char *mediaType) {
67 sp<hardware::media::c2::V1_0::utils::CachedConfigurable> cachedConfigurable =
68 new hardware::media::c2::V1_0::utils::CachedConfigurable(
69 std::make_unique<Configurable>(mReflector, domain, kind, mediaType));
70 cachedConfigurable->init(std::make_shared<Cache>());
71 mConfigurable = std::make_shared<Codec2Client::Configurable>(cachedConfigurable);
72 }
73
74 struct Cache : public hardware::media::c2::V1_0::utils::ParameterCache {
validateandroid::CCodecConfigTest::Cache75 c2_status_t validate(const std::vector<std::shared_ptr<C2ParamDescriptor>>&) override {
76 return C2_OK;
77 }
78 };
79
80 class Configurable : public hardware::media::c2::V1_0::utils::ConfigurableC2Intf {
81 public:
Configurable(const std::shared_ptr<C2ReflectorHelper> & reflector,C2Component::domain_t domain,C2Component::kind_t kind,const char * mediaType)82 Configurable(
83 const std::shared_ptr<C2ReflectorHelper> &reflector,
84 C2Component::domain_t domain,
85 C2Component::kind_t kind,
86 const char *mediaType)
87 : ConfigurableC2Intf("name", 0u),
88 mImpl(reflector, domain, kind, mediaType) {
89 }
90
query(const std::vector<C2Param::Index> & indices,c2_blocking_t mayBlock,std::vector<std::unique_ptr<C2Param>> * const params) const91 c2_status_t query(
92 const std::vector<C2Param::Index> &indices,
93 c2_blocking_t mayBlock,
94 std::vector<std::unique_ptr<C2Param>>* const params) const override {
95 return mImpl.query({}, indices, mayBlock, params);
96 }
97
config(const std::vector<C2Param * > & params,c2_blocking_t mayBlock,std::vector<std::unique_ptr<C2SettingResult>> * const failures)98 c2_status_t config(
99 const std::vector<C2Param*> ¶ms,
100 c2_blocking_t mayBlock,
101 std::vector<std::unique_ptr<C2SettingResult>>* const failures) override {
102 return mImpl.config(params, mayBlock, failures);
103 }
104
querySupportedParams(std::vector<std::shared_ptr<C2ParamDescriptor>> * const params) const105 c2_status_t querySupportedParams(
106 std::vector<std::shared_ptr<C2ParamDescriptor>>* const params) const override {
107 return mImpl.querySupportedParams(params);
108 }
109
querySupportedValues(std::vector<C2FieldSupportedValuesQuery> & fields,c2_blocking_t mayBlock) const110 c2_status_t querySupportedValues(
111 std::vector<C2FieldSupportedValuesQuery>& fields,
112 c2_blocking_t mayBlock) const override {
113 return mImpl.querySupportedValues(fields, mayBlock);
114 }
115
116 private:
117 class Impl : public C2InterfaceHelper {
118 public:
Impl(const std::shared_ptr<C2ReflectorHelper> & reflector,C2Component::domain_t domain,C2Component::kind_t kind,const char * mediaType)119 Impl(const std::shared_ptr<C2ReflectorHelper> &reflector,
120 C2Component::domain_t domain,
121 C2Component::kind_t kind,
122 const char *mediaType)
123 : C2InterfaceHelper{reflector} {
124
125 setDerivedInstance(this);
126
127 addParameter(
128 DefineParam(mDomain, C2_PARAMKEY_COMPONENT_DOMAIN)
129 .withConstValue(new C2ComponentDomainSetting(domain))
130 .build());
131
132 addParameter(
133 DefineParam(mKind, C2_PARAMKEY_COMPONENT_KIND)
134 .withConstValue(new C2ComponentKindSetting(kind))
135 .build());
136
137 addParameter(
138 DefineParam(mInputStreamCount, C2_PARAMKEY_INPUT_STREAM_COUNT)
139 .withConstValue(new C2PortStreamCountTuning::input(1))
140 .build());
141
142 addParameter(
143 DefineParam(mOutputStreamCount, C2_PARAMKEY_OUTPUT_STREAM_COUNT)
144 .withConstValue(new C2PortStreamCountTuning::output(1))
145 .build());
146
147 const char *rawMediaType = "";
148 switch (domain) {
149 case C2Component::DOMAIN_IMAGE: [[fallthrough]];
150 case C2Component::DOMAIN_VIDEO:
151 rawMediaType = MIMETYPE_VIDEO_RAW;
152 break;
153 case C2Component::DOMAIN_AUDIO:
154 rawMediaType = MIMETYPE_AUDIO_RAW;
155 break;
156 default:
157 break;
158 }
159 bool isEncoder = kind == C2Component::KIND_ENCODER;
160 std::string inputMediaType{isEncoder ? rawMediaType : mediaType};
161 std::string outputMediaType{isEncoder ? mediaType : rawMediaType};
162
__anon38026ec30202(const auto ¶m, const std::string &str) 163 auto allocSharedString = [](const auto ¶m, const std::string &str) {
164 typedef typename std::remove_reference<decltype(param)>::type::element_type T;
165 std::shared_ptr<T> ret = T::AllocShared(str.length() + 1);
166 strcpy(ret->m.value, str.c_str());
167 return ret;
168 };
169
170 addParameter(
171 DefineParam(mInputMediaType, C2_PARAMKEY_INPUT_MEDIA_TYPE)
172 .withConstValue(allocSharedString(mInputMediaType, inputMediaType))
173 .build());
174
175 addParameter(
176 DefineParam(mOutputMediaType, C2_PARAMKEY_OUTPUT_MEDIA_TYPE)
177 .withConstValue(allocSharedString(mOutputMediaType, outputMediaType))
178 .build());
179
180 addParameter(
181 DefineParam(mInt32Input, C2_PARAMKEY_VENDOR_INT32)
182 .withDefault(new C2PortVendorInt32Info::input(0))
183 .withFields({C2F(mInt32Input, value).any()})
184 .withSetter(Setter<decltype(mInt32Input)::element_type>)
185 .build());
186
187 addParameter(
188 DefineParam(mInt64Output, C2_PARAMKEY_VENDOR_INT64)
189 .withDefault(new C2StreamVendorInt64Info::output(0u, 0))
190 .withFields({C2F(mInt64Output, value).any()})
191 .withSetter(Setter<decltype(mInt64Output)::element_type>)
192 .build());
193
194 addParameter(
195 DefineParam(mStringInput, C2_PARAMKEY_VENDOR_STRING)
196 .withDefault(decltype(mStringInput)::element_type::AllocShared(1, ""))
197 .withFields({C2F(mStringInput, m.value).any()})
198 .withSetter(Setter<decltype(mStringInput)::element_type>)
199 .build());
200
201 addParameter(
202 DefineParam(mPixelAspectRatio, C2_PARAMKEY_PIXEL_ASPECT_RATIO)
203 .withDefault(new C2StreamPixelAspectRatioInfo::output(0u, 1, 1))
204 .withFields({
205 C2F(mPixelAspectRatio, width).any(),
206 C2F(mPixelAspectRatio, height).any(),
207 })
208 .withSetter(Setter<C2StreamPixelAspectRatioInfo::output>)
209 .build());
210
211 // TODO: more SDK params
212 }
213 private:
214 std::shared_ptr<C2ComponentDomainSetting> mDomain;
215 std::shared_ptr<C2ComponentKindSetting> mKind;
216 std::shared_ptr<C2PortStreamCountTuning::input> mInputStreamCount;
217 std::shared_ptr<C2PortStreamCountTuning::output> mOutputStreamCount;
218 std::shared_ptr<C2PortMediaTypeSetting::input> mInputMediaType;
219 std::shared_ptr<C2PortMediaTypeSetting::output> mOutputMediaType;
220 std::shared_ptr<C2PortVendorInt32Info::input> mInt32Input;
221 std::shared_ptr<C2StreamVendorInt64Info::output> mInt64Output;
222 std::shared_ptr<C2PortVendorStringInfo::input> mStringInput;
223 std::shared_ptr<C2StreamPixelAspectRatioInfo::output> mPixelAspectRatio;
224
225 template<typename T>
Setter(bool,C2P<T> &)226 static C2R Setter(bool, C2P<T> &) {
227 return C2R::Ok();
228 }
229 };
230
231 Impl mImpl;
232 };
233
234 std::shared_ptr<C2ReflectorHelper> mReflector;
235 std::shared_ptr<Codec2Client::Configurable> mConfigurable;
236 CCodecConfig mConfig;
237 };
238
239 using D = CCodecConfig::Domain;
240
241 template<typename T>
FindParam(const std::vector<std::unique_ptr<C2Param>> & vec)242 T *FindParam(const std::vector<std::unique_ptr<C2Param>> &vec) {
243 for (const std::unique_ptr<C2Param> ¶m : vec) {
244 if (param->coreIndex() == T::CORE_INDEX) {
245 return static_cast<T *>(param.get());
246 }
247 }
248 return nullptr;
249 }
250
TEST_F(CCodecConfigTest,SetVendorParam)251 TEST_F(CCodecConfigTest, SetVendorParam) {
252 // Test at audio domain, as video domain has a few local parameters that
253 // interfere with the testing.
254 init(C2Component::DOMAIN_AUDIO, C2Component::KIND_DECODER, MIMETYPE_AUDIO_AAC);
255
256 ASSERT_EQ(OK, mConfig.initialize(mReflector, mConfigurable));
257
258 sp<AMessage> format{new AMessage};
259 format->setInt32(KEY_VENDOR_INT32, kCodec2Int32);
260 format->setInt64(KEY_VENDOR_INT64, kCodec2Int64);
261 format->setString(KEY_VENDOR_STRING, kCodec2Str);
262
263 std::vector<std::unique_ptr<C2Param>> configUpdate;
264 ASSERT_EQ(OK, mConfig.getConfigUpdateFromSdkParams(
265 mConfigurable, format, D::ALL, C2_MAY_BLOCK, &configUpdate));
266
267 ASSERT_EQ(3u, configUpdate.size());
268 C2PortVendorInt32Info::input *i32 =
269 FindParam<std::remove_pointer<decltype(i32)>::type>(configUpdate);
270 ASSERT_NE(nullptr, i32);
271 ASSERT_EQ(kCodec2Int32, i32->value);
272
273 C2StreamVendorInt64Info::output *i64 =
274 FindParam<std::remove_pointer<decltype(i64)>::type>(configUpdate);
275 ASSERT_NE(nullptr, i64);
276 ASSERT_EQ(kCodec2Int64, i64->value);
277
278 C2PortVendorStringInfo::input *str =
279 FindParam<std::remove_pointer<decltype(str)>::type>(configUpdate);
280 ASSERT_NE(nullptr, str);
281 ASSERT_STREQ(kCodec2Str, str->m.value);
282 }
283
TEST_F(CCodecConfigTest,VendorParamUpdate_Unsubscribed)284 TEST_F(CCodecConfigTest, VendorParamUpdate_Unsubscribed) {
285 // Test at audio domain, as video domain has a few local parameters that
286 // interfere with the testing.
287 init(C2Component::DOMAIN_AUDIO, C2Component::KIND_DECODER, MIMETYPE_AUDIO_AAC);
288
289 ASSERT_EQ(OK, mConfig.initialize(mReflector, mConfigurable));
290
291 std::vector<std::unique_ptr<C2Param>> configUpdate;
292 C2PortVendorInt32Info::input i32(kCodec2Int32);
293 C2StreamVendorInt64Info::output i64(0u, kCodec2Int64);
294 std::unique_ptr<C2PortVendorStringInfo::input> str =
295 C2PortVendorStringInfo::input::AllocUnique(strlen(kCodec2Str) + 1, kCodec2Str);
296 configUpdate.push_back(C2Param::Copy(i32));
297 configUpdate.push_back(C2Param::Copy(i64));
298 configUpdate.push_back(std::move(str));
299
300 // The vendor parameters are not yet subscribed
301 ASSERT_FALSE(mConfig.updateConfiguration(configUpdate, D::ALL));
302
303 int32_t vendorInt32{0};
304 ASSERT_FALSE(mConfig.mInputFormat->findInt32(KEY_VENDOR_INT32, &vendorInt32))
305 << "mInputFormat = " << mConfig.mInputFormat->debugString().c_str();
306 ASSERT_FALSE(mConfig.mOutputFormat->findInt32(KEY_VENDOR_INT32, &vendorInt32))
307 << "mOutputFormat = " << mConfig.mOutputFormat->debugString().c_str();
308
309 int64_t vendorInt64{0};
310 ASSERT_FALSE(mConfig.mInputFormat->findInt64(KEY_VENDOR_INT64, &vendorInt64))
311 << "mInputFormat = " << mConfig.mInputFormat->debugString().c_str();
312 ASSERT_FALSE(mConfig.mOutputFormat->findInt64(KEY_VENDOR_INT64, &vendorInt64))
313 << "mOutputFormat = " << mConfig.mOutputFormat->debugString().c_str();
314
315 AString vendorString;
316 ASSERT_FALSE(mConfig.mInputFormat->findString(KEY_VENDOR_STRING, &vendorString))
317 << "mInputFormat = " << mConfig.mInputFormat->debugString().c_str();
318 ASSERT_FALSE(mConfig.mOutputFormat->findString(KEY_VENDOR_STRING, &vendorString))
319 << "mOutputFormat = " << mConfig.mOutputFormat->debugString().c_str();
320 }
321
TEST_F(CCodecConfigTest,VendorParamUpdate_AllSubscribed)322 TEST_F(CCodecConfigTest, VendorParamUpdate_AllSubscribed) {
323 // Test at audio domain, as video domain has a few local parameters that
324 // interfere with the testing.
325 init(C2Component::DOMAIN_AUDIO, C2Component::KIND_DECODER, MIMETYPE_AUDIO_AAC);
326
327 ASSERT_EQ(OK, mConfig.initialize(mReflector, mConfigurable));
328
329 // Force subscribe to all vendor params
330 ASSERT_EQ(OK, mConfig.subscribeToAllVendorParams(mConfigurable, C2_MAY_BLOCK));
331
332 std::vector<std::unique_ptr<C2Param>> configUpdate;
333 C2PortVendorInt32Info::input i32(kCodec2Int32);
334 C2StreamVendorInt64Info::output i64(0u, kCodec2Int64);
335 std::unique_ptr<C2PortVendorStringInfo::input> str =
336 C2PortVendorStringInfo::input::AllocUnique(strlen(kCodec2Str) + 1, kCodec2Str);
337 configUpdate.push_back(C2Param::Copy(i32));
338 configUpdate.push_back(C2Param::Copy(i64));
339 configUpdate.push_back(std::move(str));
340
341 ASSERT_TRUE(mConfig.updateConfiguration(configUpdate, D::ALL));
342
343 int32_t vendorInt32{0};
344 ASSERT_TRUE(mConfig.mInputFormat->findInt32(KEY_VENDOR_INT32, &vendorInt32))
345 << "mInputFormat = " << mConfig.mInputFormat->debugString().c_str();
346 ASSERT_EQ(kCodec2Int32, vendorInt32);
347 ASSERT_FALSE(mConfig.mOutputFormat->findInt32(KEY_VENDOR_INT32, &vendorInt32))
348 << "mOutputFormat = " << mConfig.mOutputFormat->debugString().c_str();
349
350 int64_t vendorInt64{0};
351 ASSERT_FALSE(mConfig.mInputFormat->findInt64(KEY_VENDOR_INT64, &vendorInt64))
352 << "mInputFormat = " << mConfig.mInputFormat->debugString().c_str();
353 ASSERT_TRUE(mConfig.mOutputFormat->findInt64(KEY_VENDOR_INT64, &vendorInt64))
354 << "mOutputFormat = " << mConfig.mOutputFormat->debugString().c_str();
355 ASSERT_EQ(kCodec2Int64, vendorInt64);
356
357 AString vendorString;
358 ASSERT_TRUE(mConfig.mInputFormat->findString(KEY_VENDOR_STRING, &vendorString))
359 << "mInputFormat = " << mConfig.mInputFormat->debugString().c_str();
360 ASSERT_STREQ(kCodec2Str, vendorString.c_str());
361 ASSERT_FALSE(mConfig.mOutputFormat->findString(KEY_VENDOR_STRING, &vendorString))
362 << "mOutputFormat = " << mConfig.mOutputFormat->debugString().c_str();
363 }
364
TEST_F(CCodecConfigTest,VendorParamUpdate_PartiallySubscribed)365 TEST_F(CCodecConfigTest, VendorParamUpdate_PartiallySubscribed) {
366 // Test at audio domain, as video domain has a few local parameters that
367 // interfere with the testing.
368 init(C2Component::DOMAIN_AUDIO, C2Component::KIND_DECODER, MIMETYPE_AUDIO_AAC);
369
370 ASSERT_EQ(OK, mConfig.initialize(mReflector, mConfigurable));
371
372 // Subscribe to example.int32 only
373 std::vector<std::unique_ptr<C2Param>> configUpdate;
374 sp<AMessage> format{new AMessage};
375 format->setInt32(KEY_VENDOR_INT32, 0);
376 configUpdate.clear();
377 ASSERT_EQ(OK, mConfig.getConfigUpdateFromSdkParams(
378 mConfigurable, format, D::ALL, C2_MAY_BLOCK, &configUpdate));
379 ASSERT_EQ(OK, mConfig.setParameters(mConfigurable, configUpdate, C2_MAY_BLOCK));
380
381 C2PortVendorInt32Info::input i32(kCodec2Int32);
382 C2StreamVendorInt64Info::output i64(0u, kCodec2Int64);
383 std::unique_ptr<C2PortVendorStringInfo::input> str =
384 C2PortVendorStringInfo::input::AllocUnique(strlen(kCodec2Str) + 1, kCodec2Str);
385 configUpdate.clear();
386 configUpdate.push_back(C2Param::Copy(i32));
387 configUpdate.push_back(C2Param::Copy(i64));
388 configUpdate.push_back(std::move(str));
389
390 // Only example.i32 should be updated
391 ASSERT_TRUE(mConfig.updateConfiguration(configUpdate, D::ALL));
392
393 int32_t vendorInt32{0};
394 ASSERT_TRUE(mConfig.mInputFormat->findInt32(KEY_VENDOR_INT32, &vendorInt32))
395 << "mInputFormat = " << mConfig.mInputFormat->debugString().c_str();
396 ASSERT_EQ(kCodec2Int32, vendorInt32);
397 ASSERT_FALSE(mConfig.mOutputFormat->findInt32(KEY_VENDOR_INT32, &vendorInt32))
398 << "mOutputFormat = " << mConfig.mOutputFormat->debugString().c_str();
399
400 int64_t vendorInt64{0};
401 ASSERT_FALSE(mConfig.mInputFormat->findInt64(KEY_VENDOR_INT64, &vendorInt64))
402 << "mInputFormat = " << mConfig.mInputFormat->debugString().c_str();
403 ASSERT_FALSE(mConfig.mOutputFormat->findInt64(KEY_VENDOR_INT64, &vendorInt64))
404 << "mOutputFormat = " << mConfig.mOutputFormat->debugString().c_str();
405
406 AString vendorString;
407 ASSERT_FALSE(mConfig.mInputFormat->findString(KEY_VENDOR_STRING, &vendorString))
408 << "mInputFormat = " << mConfig.mInputFormat->debugString().c_str();
409 ASSERT_FALSE(mConfig.mOutputFormat->findString(KEY_VENDOR_STRING, &vendorString))
410 << "mOutputFormat = " << mConfig.mOutputFormat->debugString().c_str();
411 }
412
TEST_F(CCodecConfigTest,SetPixelAspectRatio)413 TEST_F(CCodecConfigTest, SetPixelAspectRatio) {
414 init(C2Component::DOMAIN_VIDEO, C2Component::KIND_DECODER, MIMETYPE_VIDEO_AVC);
415
416 ASSERT_EQ(OK, mConfig.initialize(mReflector, mConfigurable));
417
418 sp<AMessage> format{new AMessage};
419 format->setInt32(KEY_PIXEL_ASPECT_RATIO_WIDTH, 12);
420 format->setInt32(KEY_PIXEL_ASPECT_RATIO_HEIGHT, 11);
421
422 std::vector<std::unique_ptr<C2Param>> configUpdate;
423 ASSERT_EQ(OK, mConfig.getConfigUpdateFromSdkParams(
424 mConfigurable, format, D::ALL, C2_MAY_BLOCK, &configUpdate));
425
426 ASSERT_EQ(1u, configUpdate.size());
427 C2StreamPixelAspectRatioInfo::output *par =
428 FindParam<std::remove_pointer<decltype(par)>::type>(configUpdate);
429 ASSERT_NE(nullptr, par);
430 ASSERT_EQ(12, par->width);
431 ASSERT_EQ(11, par->height);
432 }
433
TEST_F(CCodecConfigTest,PixelAspectRatioUpdate)434 TEST_F(CCodecConfigTest, PixelAspectRatioUpdate) {
435 init(C2Component::DOMAIN_VIDEO, C2Component::KIND_DECODER, MIMETYPE_VIDEO_AVC);
436
437 ASSERT_EQ(OK, mConfig.initialize(mReflector, mConfigurable));
438
439 std::vector<std::unique_ptr<C2Param>> configUpdate;
440 C2StreamPixelAspectRatioInfo::output par(0u, 12, 11);
441 configUpdate.push_back(C2Param::Copy(par));
442
443 ASSERT_TRUE(mConfig.updateConfiguration(configUpdate, D::ALL));
444
445 int32_t parWidth{0};
446 ASSERT_TRUE(mConfig.mOutputFormat->findInt32(KEY_PIXEL_ASPECT_RATIO_WIDTH, &parWidth))
447 << "mOutputFormat = " << mConfig.mOutputFormat->debugString().c_str();
448 ASSERT_EQ(12, parWidth);
449 ASSERT_FALSE(mConfig.mInputFormat->findInt32(KEY_PIXEL_ASPECT_RATIO_WIDTH, &parWidth))
450 << "mInputFormat = " << mConfig.mInputFormat->debugString().c_str();
451
452 int32_t parHeight{0};
453 ASSERT_TRUE(mConfig.mOutputFormat->findInt32(KEY_PIXEL_ASPECT_RATIO_HEIGHT, &parHeight))
454 << "mOutputFormat = " << mConfig.mOutputFormat->debugString().c_str();
455 ASSERT_EQ(11, parHeight);
456 ASSERT_FALSE(mConfig.mInputFormat->findInt32(KEY_PIXEL_ASPECT_RATIO_HEIGHT, &parHeight))
457 << "mInputFormat = " << mConfig.mInputFormat->debugString().c_str();
458 }
459
460 } // namespace android
461