• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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