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 "NativeMediaFormatUnitTest"
19 #include <log/log.h>
20
21 #include <jni.h>
22 #include <media/NdkMediaFormat.h>
23
24 #include <cinttypes>
25 #include <map>
26 #include <string>
27
28 static const char story[] = {"What if after you die, God asks you: 'so how was heaven'"};
29 static const char dragon[] = {"e4 c5 Nf3 d6 d4 cxd4 Nxd4 Nf6 Nc3 g6"};
30
31 class Rect {
32 public:
33 int left;
34 int top;
35 int right;
36 int bottom;
37
Rect(int a,int b,int c,int d)38 Rect(int a, int b, int c, int d) : left{a}, top{b}, right{c}, bottom{d} {};
39 };
40
41 class Buffer {
42 public:
43 char* buffer;
44 size_t size;
45
Buffer(char * buffer=nullptr,size_t size=0)46 explicit Buffer(char* buffer = nullptr, size_t size = 0) : buffer{buffer}, size{size} {};
47 };
48
49 class NativeMediaFormatUnitTest {
50 private:
51 std::map<int32_t, const char*> mInt32KeyValuePairs;
52 std::map<int64_t, const char*> mInt64KeyValuePairs;
53 std::map<float, const char*> mFloatKeyValuePairs;
54 std::map<double, const char*> mDoubleKeyValuePairs;
55 std::map<size_t, const char*> mSizeKeyValuePairs;
56 std::map<const char*, const char*> mStringKeyValuePairs;
57 std::map<Rect*, const char*> mWindowKeyValuePairs;
58 std::map<Buffer*, const char*> mBufferKeyValuePairs;
59
60 public:
61 NativeMediaFormatUnitTest();
62 ~NativeMediaFormatUnitTest();
63
64 bool validateFormatInt32(AMediaFormat* fmt, int offset = 0, bool isClear = false);
65 bool validateFormatInt64(AMediaFormat* fmt, int offset = 0, bool isClear = false);
66 bool validateFormatFloat(AMediaFormat* fmt, float offset = 0.0f, bool isClear = false);
67 bool validateFormatDouble(AMediaFormat* fmt, double offset = 0.0, bool isClear = false);
68 bool validateFormatSize(AMediaFormat* fmt, size_t offset = 0, bool isClear = false);
69 bool validateFormatString(AMediaFormat* fmt, int offset = 0, bool isClear = false);
70 bool validateFormatRect(AMediaFormat* fmt, int offset = 0, bool isClear = false);
71 bool validateFormatBuffer(AMediaFormat* fmt, int offset = 0, bool isClear = false);
72 bool validateFormat(AMediaFormat* fmt, int offset = 0, bool isClear = false);
73
74 void configureFormatInt32(AMediaFormat* fmt, int offset = 0);
75 void configureFormatInt64(AMediaFormat* fmt, int offset = 0);
76 void configureFormatFloat(AMediaFormat* fmt, float offset = 0.0f);
77 void configureFormatDouble(AMediaFormat* fmt, double offset = 0.0);
78 void configureFormatSize(AMediaFormat* fmt, size_t offset = 0);
79 void configureFormatString(AMediaFormat* fmt, int offset = 0);
80 void configureFormatRect(AMediaFormat* fmt, int offset = 0);
81 void configureFormatBuffer(AMediaFormat* fmt, int offset = 0);
82 void configureFormat(AMediaFormat* fmt, int offset = 0);
83 };
84
NativeMediaFormatUnitTest()85 NativeMediaFormatUnitTest::NativeMediaFormatUnitTest() {
86 mInt32KeyValuePairs.insert({118, "elements in periodic table"});
87 mInt32KeyValuePairs.insert({5778, "surface temp. of sun in kelvin"});
88 mInt32KeyValuePairs.insert({8611, "k2 peak in mts"});
89 mInt32KeyValuePairs.insert({72, "heart rate in bpm"});
90 mInt64KeyValuePairs.insert({299792458L, "vel. of em wave in free space m/s"});
91 mInt64KeyValuePairs.insert({86400L, "number of seconds in a day"});
92 mInt64KeyValuePairs.insert({1520200000L, "distance of earth from the sun in km"});
93 mInt64KeyValuePairs.insert({39000000L, "forest area of the world km^2"});
94 mFloatKeyValuePairs.insert({22.0f / 7.0f, "pi"});
95 mFloatKeyValuePairs.insert({3.6f, "not great, not terrible"});
96 mFloatKeyValuePairs.insert({15.999f, "atomic weight of oxygen 8"});
97 mFloatKeyValuePairs.insert({2.7182f, "Euler's number"});
98 mDoubleKeyValuePairs.insert({44.0 / 7, "tau"});
99 mDoubleKeyValuePairs.insert({9.80665, "g on earth m/sec^2"});
100 mSizeKeyValuePairs.insert({sizeof(int64_t), "size of int64_t"});
101 mSizeKeyValuePairs.insert({sizeof(wchar_t), "size of wide char"});
102 mSizeKeyValuePairs.insert({sizeof(intptr_t), "size of pointer variable"});
103 mSizeKeyValuePairs.insert({sizeof *this, "size of class NativeMediaFormatUnitTest"});
104 mStringKeyValuePairs.insert(
105 {"Discovered radium and polonium, and made huge contribution to finding treatments "
106 "for cancer", "Marie Curie"});
107 mStringKeyValuePairs.insert({"Sun rises in the east has zero entropy", "Shannon"});
108 mWindowKeyValuePairs.insert({new Rect{12, 15, 12, 21}, "trapezoid"});
109 mWindowKeyValuePairs.insert({new Rect{12, 12, 12, 12}, "rhombus"});
110 mWindowKeyValuePairs.insert({new Rect{12, 15, 12, 15}, "rectangle"});
111 mWindowKeyValuePairs.insert({new Rect{12, 15, 18, 21}, "quadrilateral"});
112 mBufferKeyValuePairs.insert({new Buffer(), "empty buffer"});
113 size_t sz = strlen(story) + 1;
114 auto* quote = new Buffer{new char[sz], sz};
115 memcpy(quote->buffer, story, sz);
116 mBufferKeyValuePairs.insert({quote, "one line story"});
117 sz = strlen(dragon) + 1;
118 auto* chess = new Buffer(new char[sz], sz);
119 memcpy(chess->buffer, dragon, sz);
120 mBufferKeyValuePairs.insert({chess, "sicilian dragon"});
121 }
122
~NativeMediaFormatUnitTest()123 NativeMediaFormatUnitTest::~NativeMediaFormatUnitTest() {
124 for (auto it : mWindowKeyValuePairs) {
125 delete it.first;
126 }
127 for (auto it : mBufferKeyValuePairs) {
128 delete[] it.first->buffer;
129 delete it.first;
130 }
131 }
132
validateFormatInt32(AMediaFormat * fmt,int offset,bool isClear)133 bool NativeMediaFormatUnitTest::validateFormatInt32(AMediaFormat* fmt, int offset, bool isClear) {
134 bool status = true;
135 int32_t val;
136 const char* toString = AMediaFormat_toString(fmt);
137 for (auto it : mInt32KeyValuePairs) {
138 bool result = AMediaFormat_getInt32(fmt, it.second, &val);
139 if (isClear) {
140 if (result) {
141 ALOGE("MediaFormat is not expected to contain Key %s", it.second);
142 status &= false;
143 }
144 } else {
145 if (!result) {
146 ALOGE("MediaFormat doesn't contain key %s", it.second);
147 status &= false;
148 } else if (val != it.first + offset) {
149 ALOGE("MediaFormat Value for Key %s is not %d but %d", it.second, it.first + offset,
150 val);
151 status &= false;
152 }
153 if (strstr(toString, it.second) == nullptr) {
154 ALOGE("AMediaFormat_toString() of fmt %s doesn't contains %s", toString, it.second);
155 status &= false;
156 }
157 if (strstr(toString, std::to_string(it.first + offset).c_str()) == nullptr) {
158 ALOGE("AMediaFormat_toString() of fmt %s doesn't contains %s", toString,
159 std::to_string(it.first + offset).c_str());
160 status &= false;
161 }
162 }
163 }
164 if (AMediaFormat_getInt32(fmt, "hello world", &val)) {
165 ALOGE("MediaFormat has value for key 'hello world' ");
166 status &= false;
167 }
168 return status;
169 }
170
validateFormatInt64(AMediaFormat * fmt,int offset,bool isClear)171 bool NativeMediaFormatUnitTest::validateFormatInt64(AMediaFormat* fmt, int offset, bool isClear) {
172 bool status = true;
173 int64_t val;
174 const char* toString = AMediaFormat_toString(fmt);
175 for (auto it : mInt64KeyValuePairs) {
176 bool result = AMediaFormat_getInt64(fmt, it.second, &val);
177 if (isClear) {
178 if (result) {
179 ALOGE("MediaFormat is not expected to contain Key %s", it.second);
180 status &= false;
181 }
182 } else {
183 if (!result) {
184 ALOGE("MediaFormat doesn't contain key %s", it.second);
185 status &= false;
186 } else if (val != it.first + offset) {
187 ALOGE("MediaFormat Value for Key %s is not %" PRId64 "but %" PRId64, it.second,
188 it.first + offset, val);
189 status &= false;
190 }
191 if (strstr(toString, it.second) == nullptr) {
192 ALOGE("AMediaFormat_toString() of fmt %s doesn't contains %s", toString, it.second);
193 status &= false;
194 }
195 if (strstr(toString, std::to_string(it.first + offset).c_str()) == nullptr) {
196 ALOGE("AMediaFormat_toString() of fmt %s doesn't contains %s", toString,
197 std::to_string(it.first + offset).c_str());
198 status &= false;
199 }
200 }
201 }
202 if (AMediaFormat_getInt64(fmt, "hello world", &val)) {
203 ALOGE("MediaFormat has value for key 'hello world' ");
204 status &= false;
205 }
206 return status;
207 }
208
validateFormatFloat(AMediaFormat * fmt,float offset,bool isClear)209 bool NativeMediaFormatUnitTest::validateFormatFloat(AMediaFormat* fmt, float offset, bool isClear) {
210 bool status = true;
211 float val;
212 const char* toString = AMediaFormat_toString(fmt);
213 for (auto it : mFloatKeyValuePairs) {
214 bool result = AMediaFormat_getFloat(fmt, it.second, &val);
215 if (isClear) {
216 if (result) {
217 ALOGE("MediaFormat is not expected to contain Key %s", it.second);
218 status &= false;
219 }
220 } else {
221 if (!result) {
222 ALOGE("MediaFormat doesn't contain key %s", it.second);
223 status &= false;
224 } else if (val != it.first + offset) {
225 ALOGE("MediaFormat Value for Key %s is not %f but %f", it.second, it.first + offset,
226 val);
227 status &= false;
228 }
229 if (strstr(toString, it.second) == nullptr) {
230 ALOGE("AMediaFormat_toString() of fmt %s doesn't contains %s", toString, it.second);
231 status &= false;
232 }
233 if (strstr(toString, std::to_string(it.first + offset).c_str()) == nullptr) {
234 ALOGE("AMediaFormat_toString() of fmt %s doesn't contains %s", toString,
235 std::to_string(it.first + offset).c_str());
236 status &= false;
237 }
238 }
239 }
240 if (AMediaFormat_getFloat(fmt, "hello world", &val)) {
241 ALOGE("MediaFormat has value for key 'hello world' ");
242 status &= false;
243 }
244 return status;
245 }
246
validateFormatDouble(AMediaFormat * fmt,double offset,bool isClear)247 bool NativeMediaFormatUnitTest::validateFormatDouble(AMediaFormat* fmt, double offset,
248 bool isClear) {
249 bool status = true;
250 double val;
251 const char* toString = AMediaFormat_toString(fmt);
252 for (auto it : mDoubleKeyValuePairs) {
253 bool result = AMediaFormat_getDouble(fmt, it.second, &val);
254 if (isClear) {
255 if (result) {
256 ALOGE("MediaFormat is not expected to contain Key %s", it.second);
257 status &= false;
258 }
259 } else {
260 if (!result) {
261 ALOGE("MediaFormat doesn't contain key %s", it.second);
262 status &= false;
263 } else if (val != it.first + offset) {
264 ALOGE("MediaFormat Value for Key %s is not %f but %f", it.second, it.first + offset,
265 val);
266 status &= false;
267 }
268 if (strstr(toString, it.second) == nullptr) {
269 ALOGE("AMediaFormat_toString() of fmt %s doesn't contains %s", toString, it.second);
270 status &= false;
271 }
272 if (strstr(toString, std::to_string(it.first + offset).c_str()) == nullptr) {
273 ALOGE("AMediaFormat_toString() of fmt %s doesn't contains %s", toString,
274 std::to_string(it.first + offset).c_str());
275 status &= false;
276 }
277 }
278 }
279 if (AMediaFormat_getDouble(fmt, "hello world", &val)) {
280 ALOGE("MediaFormat has value for key 'hello world' ");
281 status &= false;
282 }
283 return status;
284 }
285
validateFormatSize(AMediaFormat * fmt,size_t offset,bool isClear)286 bool NativeMediaFormatUnitTest::validateFormatSize(AMediaFormat* fmt, size_t offset, bool isClear) {
287 bool status = true;
288 size_t val;
289 const char* toString = AMediaFormat_toString(fmt);
290 for (auto it : mSizeKeyValuePairs) {
291 bool result = AMediaFormat_getSize(fmt, it.second, &val);
292 if (isClear) {
293 if (result) {
294 ALOGE("MediaFormat is not expected to contain Key %s", it.second);
295 status &= false;
296 }
297 } else {
298 if (!result) {
299 ALOGE("MediaFormat doesn't contain key %s", it.second);
300 status &= false;
301 } else if (val != it.first + offset) {
302 ALOGE("MediaFormat Value for Key %s is not %zu but %zu", it.second,
303 it.first + offset, val);
304 status &= false;
305 }
306 if (strstr(toString, it.second) == nullptr) {
307 ALOGE("AMediaFormat_toString() of fmt %s doesn't contains %s", toString, it.second);
308 status &= false;
309 }
310 if (strstr(toString, std::to_string(it.first + offset).c_str()) == nullptr) {
311 ALOGE("AMediaFormat_toString() of fmt %s doesn't contains %s", toString,
312 std::to_string(it.first + offset).c_str());
313 status &= false;
314 }
315 }
316 }
317 if (AMediaFormat_getSize(fmt, "hello world", &val)) {
318 ALOGE("MediaFormat has value for key 'hello world' ");
319 status &= false;
320 }
321 return status;
322 }
323
validateFormatString(AMediaFormat * fmt,int offset,bool isClear)324 bool NativeMediaFormatUnitTest::validateFormatString(AMediaFormat* fmt, int offset, bool isClear) {
325 bool status = true;
326 const char* val;
327 const char* toString = AMediaFormat_toString(fmt);
328 for (auto it : mStringKeyValuePairs) {
329 bool result = AMediaFormat_getString(fmt, it.second, &val);
330 if (isClear) {
331 if (result) {
332 ALOGE("MediaFormat is not expected to contain Key %s", it.second);
333 status &= false;
334 }
335 } else {
336 std::string s = it.first + std::to_string(offset);
337 if (!result) {
338 ALOGE("MediaFormat doesn't contain key %s", it.second);
339 status &= false;
340 } else if (s != val) {
341 ALOGE("MediaFormat Value for Key %s is not %s but %s", it.second, s.c_str(), val);
342 status &= false;
343 }
344 if (strstr(toString, it.second) == nullptr) {
345 ALOGE("AMediaFormat_toString() of fmt %s doesn't contains %s", toString, it.second);
346 status &= false;
347 }
348 if (strstr(toString, s.c_str()) == nullptr) {
349 ALOGE("AMediaFormat_toString() of fmt %s doesn't contains %s", toString, s.c_str());
350 status &= false;
351 }
352 }
353 }
354 if (AMediaFormat_getString(fmt, "hello world", &val)) {
355 ALOGE("MediaFormat has value for key 'hello world' ");
356 status &= false;
357 }
358 return status;
359 }
360
validateFormatRect(AMediaFormat * fmt,int offset,bool isClear)361 bool NativeMediaFormatUnitTest::validateFormatRect(AMediaFormat* fmt, int offset, bool isClear) {
362 bool status = true;
363 int left, top, right, bottom;
364 const char* toString = AMediaFormat_toString(fmt);
365 for (auto it : mWindowKeyValuePairs) {
366 bool result = AMediaFormat_getRect(fmt, it.second, &left, &top, &right, &bottom);
367 if (isClear) {
368 if (result) {
369 ALOGE("MediaFormat is not expected to contain Key %s", it.second);
370 status &= false;
371 }
372 } else {
373 if (!result) {
374 ALOGE("MediaFormat doesn't contain key %s", it.second);
375 status &= false;
376 } else if (left != it.first->left + offset || top != it.first->top + offset ||
377 right != it.first->right + offset || bottom != it.first->bottom + offset) {
378 ALOGE("MediaFormat Value for Key %s is not (%d, %d, %d, %d)) but (%d, %d, %d, %d)",
379 it.second, it.first->left, it.first->top, it.first->right, it.first->bottom,
380 left, top, right, bottom);
381 status &= false;
382 }
383 if (strstr(toString, it.second) == nullptr) {
384 ALOGE("AMediaFormat_toString() of fmt %s doesn't contains %s", toString, it.second);
385 status &= false;
386 }
387 if (strstr(toString, std::to_string(it.first->left + offset).c_str()) == nullptr) {
388 ALOGE("AMediaFormat_toString() of fmt %s doesn't contains %s", toString,
389 std::to_string(it.first->left + offset).c_str());
390 status &= false;
391 }
392 if (strstr(toString, std::to_string(it.first->top + offset).c_str()) == nullptr) {
393 ALOGE("AMediaFormat_toString() of fmt %s doesn't contains %s", toString,
394 std::to_string(it.first->top + offset).c_str());
395 status &= false;
396 }
397 if (strstr(toString, std::to_string(it.first->right + offset).c_str()) == nullptr) {
398 ALOGE("AMediaFormat_toString() of fmt %s doesn't contains %s", toString,
399 std::to_string(it.first->right + offset).c_str());
400 status &= false;
401 }
402 if (strstr(toString, std::to_string(it.first->bottom + offset).c_str()) == nullptr) {
403 ALOGE("AMediaFormat_toString() of fmt %s doesn't contains %s", toString,
404 std::to_string(it.first->bottom + offset).c_str());
405 status &= false;
406 }
407 }
408 }
409 if (AMediaFormat_getRect(fmt, "hello world", &left, &top, &right, &bottom)) {
410 ALOGE("MediaFormat has value for key 'hello world' ");
411 status &= false;
412 }
413 return status;
414 }
415
validateFormatBuffer(AMediaFormat * fmt,int offset,bool isClear)416 bool NativeMediaFormatUnitTest::validateFormatBuffer(AMediaFormat* fmt, int offset, bool isClear) {
417 bool status = true;
418 void* data;
419 size_t size;
420 const char* toString = AMediaFormat_toString(fmt);
421 for (auto it : mBufferKeyValuePairs) {
422 bool result = AMediaFormat_getBuffer(fmt, it.second, &data, &size);
423 if (isClear) {
424 if (result) {
425 ALOGE("MediaFormat is not expected to contain Key %s", it.second);
426 status &= false;
427 }
428 } else {
429 if (!result) {
430 ALOGE("MediaFormat doesn't contain key %s", it.second);
431 status &= false;
432 } else if (size != (offset == 0 ? it.first->size : it.first->size / 2)) {
433 ALOGE("MediaFormat Value for Key %s is not %zu but %zu", it.second,
434 (offset == 0 ? it.first->size : it.first->size / 2), size);
435 status &= false;
436 } else {
437 if (it.first->buffer != nullptr &&
438 memcmp(data, it.first->buffer + it.first->size - size, size) != 0) {
439 ALOGE("MediaFormat Value for Key %s is not %s but %s {%zu}", it.second,
440 it.first->buffer + it.first->size - size, (char*)data, size);
441 status &= false;
442 }
443 }
444 if (strstr(toString, it.second) == nullptr) {
445 ALOGE("AMediaFormat_toString() of fmt %s doesn't contains %s", toString, it.second);
446 status &= false;
447 }
448 }
449 }
450 if (AMediaFormat_getBuffer(fmt, "hello world", &data, &size)) {
451 ALOGE("MediaFormat has value for key 'hello world' ");
452 status &= false;
453 }
454 return status;
455 }
456
validateFormat(AMediaFormat * fmt,int offset,bool isClear)457 bool NativeMediaFormatUnitTest::validateFormat(AMediaFormat* fmt, int offset, bool isClear) {
458 bool status = validateFormatInt32(fmt, offset, isClear);
459 status &= validateFormatInt64(fmt, offset, isClear);
460 status &= validateFormatFloat(fmt, offset, isClear);
461 status &= validateFormatDouble(fmt, offset, isClear);
462 status &= validateFormatSize(fmt, offset, isClear);
463 status &= validateFormatString(fmt, offset, isClear);
464 status &= validateFormatRect(fmt, offset, isClear);
465 status &= validateFormatBuffer(fmt, offset, isClear);
466 return status;
467 }
468
configureFormatInt32(AMediaFormat * fmt,int offset)469 void NativeMediaFormatUnitTest::configureFormatInt32(AMediaFormat* fmt, int offset) {
470 for (auto it : mInt32KeyValuePairs) {
471 AMediaFormat_setInt32(fmt, it.second, it.first + offset);
472 }
473 }
474
configureFormatInt64(AMediaFormat * fmt,int offset)475 void NativeMediaFormatUnitTest::configureFormatInt64(AMediaFormat* fmt, int offset) {
476 for (auto it : mInt64KeyValuePairs) {
477 AMediaFormat_setInt64(fmt, it.second, it.first + offset);
478 }
479 }
480
configureFormatFloat(AMediaFormat * fmt,float offset)481 void NativeMediaFormatUnitTest::configureFormatFloat(AMediaFormat* fmt, float offset) {
482 for (auto it : mFloatKeyValuePairs) {
483 AMediaFormat_setFloat(fmt, it.second, it.first + offset);
484 }
485 }
486
configureFormatDouble(AMediaFormat * fmt,double offset)487 void NativeMediaFormatUnitTest::configureFormatDouble(AMediaFormat* fmt, double offset) {
488 for (auto it : mDoubleKeyValuePairs) {
489 AMediaFormat_setDouble(fmt, it.second, it.first + offset);
490 }
491 }
492
configureFormatSize(AMediaFormat * fmt,size_t offset)493 void NativeMediaFormatUnitTest::configureFormatSize(AMediaFormat* fmt, size_t offset) {
494 for (auto it : mSizeKeyValuePairs) {
495 AMediaFormat_setSize(fmt, it.second, it.first + offset);
496 }
497 }
498
configureFormatString(AMediaFormat * fmt,int offset)499 void NativeMediaFormatUnitTest::configureFormatString(AMediaFormat* fmt, int offset) {
500 for (auto it : mStringKeyValuePairs) {
501 std::string s1 = it.first + std::to_string(offset);
502 AMediaFormat_setString(fmt, it.second, s1.c_str());
503 }
504 }
505
configureFormatRect(AMediaFormat * fmt,int offset)506 void NativeMediaFormatUnitTest::configureFormatRect(AMediaFormat* fmt, int offset) {
507 for (auto it : mWindowKeyValuePairs) {
508 AMediaFormat_setRect(fmt, it.second, it.first->left + offset, it.first->top + offset,
509 it.first->right + offset, it.first->bottom + offset);
510 }
511 }
512
configureFormatBuffer(AMediaFormat * fmt,int offset)513 void NativeMediaFormatUnitTest::configureFormatBuffer(AMediaFormat* fmt, int offset) {
514 for (auto it : mBufferKeyValuePairs) {
515 int sz = offset == 0 ? it.first->size : it.first->size / 2;
516 AMediaFormat_setBuffer(fmt, it.second, it.first->buffer + it.first->size - sz, sz);
517 }
518 }
519
configureFormat(AMediaFormat * fmt,int offset)520 void NativeMediaFormatUnitTest::configureFormat(AMediaFormat* fmt, int offset) {
521 configureFormatInt32(fmt, offset);
522 configureFormatInt64(fmt, offset);
523 configureFormatFloat(fmt, offset);
524 configureFormatDouble(fmt, offset);
525 configureFormatSize(fmt, offset);
526 configureFormatString(fmt, offset);
527 configureFormatRect(fmt, offset);
528 configureFormatBuffer(fmt, offset);
529 }
530
531 // 1. configure format with default values and validate the same
532 // 2. copy configured format to an empty format and validate the copied format
533 // 3. overwrite copied format with default + offset values and validate the updated format
534 // 4. overwrite updated format with default values using AMediaFormat_copy API and validate the same
535 // 5. clear mediaformat and validate if keys are not present
testMediaFormatAllNative()536 static bool testMediaFormatAllNative() {
537 auto* nmf = new NativeMediaFormatUnitTest();
538 AMediaFormat* fmtOrig = AMediaFormat_new();
539 AMediaFormat* fmtDup = AMediaFormat_new();
540 const int offset = 123;
541
542 nmf->configureFormat(fmtOrig);
543 bool status = nmf->validateFormat(fmtOrig);
544
545 AMediaFormat_copy(fmtDup, fmtOrig);
546 status &= nmf->validateFormat(fmtDup);
547
548 nmf->configureFormat(fmtDup, offset);
549 status &= nmf->validateFormat(fmtDup, offset);
550
551 AMediaFormat_copy(fmtDup, fmtOrig);
552 status &= nmf->validateFormat(fmtDup);
553
554 AMediaFormat_clear(fmtDup);
555 status &= nmf->validateFormat(fmtDup, offset, true);
556
557 AMediaFormat_delete(fmtOrig);
558 AMediaFormat_delete(fmtDup);
559 delete nmf;
560
561 return status;
562 }
563
564 // 1. configure format with default values and validate the same
565 // 2. copy configured format to an empty format and validate the copied format
566 // 3. overwrite copied format with default + offset values and validate the updated format
567 // 4. overwrite updated format with default values using AMediaFormat_copy API and validate the same
568 #define testMediaFormatfuncNative(func) \
569 static bool testMediaFormat##func##Native() { \
570 auto* nmf = new NativeMediaFormatUnitTest(); \
571 AMediaFormat* fmtOrig = AMediaFormat_new(); \
572 AMediaFormat* fmtDup = AMediaFormat_new(); \
573 const int offset = 12345; \
574 \
575 nmf->configureFormat##func(fmtOrig); \
576 bool status = nmf->validateFormat##func(fmtOrig); \
577 \
578 AMediaFormat_copy(fmtDup, fmtOrig); \
579 status &= nmf->validateFormat##func(fmtDup); \
580 \
581 nmf->configureFormat##func(fmtDup, offset); \
582 status &= nmf->validateFormat##func(fmtDup, offset); \
583 \
584 AMediaFormat_copy(fmtDup, fmtOrig); \
585 status &= nmf->validateFormat##func(fmtDup); \
586 \
587 AMediaFormat_clear(fmtDup); \
588 status &= nmf->validateFormat##func(fmtDup, offset, true); \
589 AMediaFormat_delete(fmtOrig); \
590 AMediaFormat_delete(fmtDup); \
591 delete nmf; \
592 return status; \
593 }
594
595 testMediaFormatfuncNative(Int32)
596
testMediaFormatfuncNative(Int64)597 testMediaFormatfuncNative(Int64)
598
599 testMediaFormatfuncNative(Float)
600
601 testMediaFormatfuncNative(Double)
602
603 testMediaFormatfuncNative(Size)
604
605 testMediaFormatfuncNative(String)
606
607 testMediaFormatfuncNative(Rect)
608
609 testMediaFormatfuncNative(Buffer)
610
611 #define nativeTestMediaFormatfunc(func) \
612 static jboolean nativeTestMediaFormat##func(JNIEnv*, jobject) { \
613 return static_cast<jboolean>(testMediaFormat##func##Native()); \
614 }
615
616 nativeTestMediaFormatfunc(Int32)
617
618 nativeTestMediaFormatfunc(Int64)
619
620 nativeTestMediaFormatfunc(Float)
621
622 nativeTestMediaFormatfunc(Double)
623
624 nativeTestMediaFormatfunc(Size)
625
626 nativeTestMediaFormatfunc(String)
627
628 nativeTestMediaFormatfunc(Rect)
629
630 nativeTestMediaFormatfunc(Buffer)
631
632 nativeTestMediaFormatfunc(All)
633
634 int registerAndroidMediaV2CtsMediaFormatUnitTest(JNIEnv* env) {
635 const JNINativeMethod methodTable[] = {
636 {"nativeTestMediaFormatInt32", "()Z", (void*)nativeTestMediaFormatInt32},
637 {"nativeTestMediaFormatInt64", "()Z", (void*)nativeTestMediaFormatInt64},
638 {"nativeTestMediaFormatFloat", "()Z", (void*)nativeTestMediaFormatFloat},
639 {"nativeTestMediaFormatDouble", "()Z", (void*)nativeTestMediaFormatDouble},
640 {"nativeTestMediaFormatSize", "()Z", (void*)nativeTestMediaFormatSize},
641 {"nativeTestMediaFormatString", "()Z", (void*)nativeTestMediaFormatString},
642 {"nativeTestMediaFormatRect", "()Z", (void*)nativeTestMediaFormatRect},
643 {"nativeTestMediaFormatBuffer", "()Z", (void*)nativeTestMediaFormatBuffer},
644 {"nativeTestMediaFormatAll", "()Z", (void*)nativeTestMediaFormatAll},
645 };
646 jclass c = env->FindClass("android/mediav2/cts/MediaFormatUnitTest");
647 return env->RegisterNatives(c, methodTable, sizeof(methodTable) / sizeof(JNINativeMethod));
648 }
649
JNI_OnLoad(JavaVM * vm,void *)650 extern "C" JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void*) {
651 JNIEnv* env;
652 if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) return JNI_ERR;
653 if (registerAndroidMediaV2CtsMediaFormatUnitTest(env) != JNI_OK) return JNI_ERR;
654 return JNI_VERSION_1_6;
655 }
656