xref: /rockchip-linux_mpp/utils/osd3_test.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
1 /* SPDX-License-Identifier: Apache-2.0 */
2 /*
3  * Copyright (c) 2025 Rockchip Electronics Co., Ltd.
4  */
5 
6 #define MODULE_TAG "OSD3_TEST"
7 
8 #include "osd3_test.h"
9 #include "mpp_common.h"
10 #include "kmpp_buffer.h"
11 
12 /**
13  * @brief Generate horizontal SMPTE test pattern in ARGB inteleaved format.
14  * Test pattern bar color:
15  *  {255, 255, 255},    // White
16  *  {254, 255, 0},      // Yelow
17  *  {0, 254, 255},      // Cyan
18  *  {255, 0, 0},        // Red
19  *  {0, 255, 0},        // Green
20  *  {0, 0, 255},        // Blue
21  *  {191, 191, 191},    // 75% White
22  *  {0, 0, 0,}          // Black
23  *  TODO Add RGB to YUV translation
24  *
25  * @param dst buffer should be at the size of (bar_width * bar_height * 8 * 4)
26  * @param bar_width each bar width
27  * @param bar_heigt each bar height
28  */
osd3_gen_smpte_bar_argb(RK_U8 ** dst)29 MPP_RET osd3_gen_smpte_bar_argb(RK_U8 **dst)
30 {
31     MPP_RET ret = MPP_OK;
32     RK_U32 i, j, k = 0;
33     FILE *fp = NULL;
34     RK_U32 bar_width = OSD_PATTERN_WIDTH;
35     RK_U32 bar_height = OSD_PATTERN_HEIGHT / SMPTE_BAR_CNT;
36     RK_U8 smpte_bar[8][3] = {
37         {255, 255, 255},    // White
38         {254, 255, 0},      // Yelow
39         {0, 254, 255},      // Cyan
40         {255, 0, 0},        // Red
41         {0, 255, 0},        // Green
42         {0, 0, 255},        // Blue
43         {191, 191, 191},    // 75% White
44         {0, 0, 0,}          // Black
45     };
46     RK_U8 *base = malloc(bar_width * bar_height * SMPTE_BAR_CNT * 4);
47 
48     *dst = base;
49     fp = fopen("/userdata/wind_ABGR8888.ABGR8888", "rb");
50     if (!fp) {
51         for (k = 0; k < SMPTE_BAR_CNT; k++) {
52             for (j = 0; j < bar_height; j++) {
53                 for (i = 0; i < bar_width; i++) {
54                     base[i * 4] = 0xff;
55                     base[i * 4 + 1] = smpte_bar[k][0];
56                     base[i * 4 + 2] = smpte_bar[k][1];
57                     base[i * 4 + 3] = smpte_bar[k][2];
58                 }
59                 base += bar_width * 4;
60             }
61         }
62     } else {
63         size_t read_size = OSD_PATTERN_WIDTH * OSD_PATTERN_HEIGHT * 4;
64         size_t fp_size;
65 
66         fp_size = fread(base, 1, read_size, fp);
67         if (fp_size != read_size) {
68             mpp_err("fread failed, read_size: %zu, fp_size: %zu", read_size, fp_size);
69             free(base);
70             *dst = NULL;
71             ret = MPP_NOK;
72         }
73         fclose(fp);
74     }
75 
76     return ret;
77 }
78 
translate_argb(RK_U8 * src,RK_U8 * dst,RK_U32 width,RK_U32 height,RK_U32 fmt_idx,MppEncOSDRegion3 * cfg)79 static MPP_RET translate_argb(RK_U8 *src, RK_U8 *dst, RK_U32 width, RK_U32 height,
80                               RK_U32 fmt_idx, MppEncOSDRegion3 *cfg)
81 {
82     MPP_RET ret = MPP_OK;
83     RK_U32 i = 0;
84     RK_U32 j = 0;
85     RK_U16 *tmp_u16 = NULL;
86 
87     RK_U8 tmp_r = 0;
88     RK_U8 tmp_g = 0;
89     RK_U8 tmp_b = 0;
90 
91     if (fmt_idx == OSD_FMT_ARGB8888) {
92         cfg->fmt = MPP_FMT_ARGB8888;
93         cfg->alpha_cfg.alpha_swap = 1;
94         cfg->rbuv_swap = 1;
95         cfg->stride = width * 4;
96         memcpy(dst, src, width * height * 4);
97     } else if (fmt_idx == OSD_FMT_RGBA8888) {
98         cfg->fmt = MPP_FMT_RGBA8888;
99         cfg->alpha_cfg.alpha_swap = 1;
100         cfg->rbuv_swap = 0;
101         cfg->stride = width * 4;
102         for (j = 0; j < height; j++) {
103             for (i = 0; i < width; i++) {
104                 dst[j * width * 4 + i * 4 + 0] = src[j * width * 4 + i * 4 + 0];
105                 dst[j * width * 4 + i * 4 + 1] = src[j * width * 4 + i * 4 + 3];
106                 dst[j * width * 4 + i * 4 + 2] = src[j * width * 4 + i * 4 + 2];
107                 dst[j * width * 4 + i * 4 + 3] = src[j * width * 4 + i * 4 + 1];
108             }
109         }
110     } else if (fmt_idx == OSD_FMT_BGRA8888) {
111         cfg->fmt = MPP_FMT_ARGB8888;
112         cfg->alpha_cfg.alpha_swap = 1;
113         cfg->alpha_cfg.alpha_swap = 0;
114         cfg->rbuv_swap = 0;
115         cfg->stride = width * 4;
116         for (j = 0; j < height; j++) {
117             for (i = 0; i < width; i++) {
118                 dst[j * width * 4 + i * 4 + 0] = src[j * width * 4 + i * 4 + 3];
119                 dst[j * width * 4 + i * 4 + 1] = src[j * width * 4 + i * 4 + 2];
120                 dst[j * width * 4 + i * 4 + 2] = src[j * width * 4 + i * 4 + 1];
121                 dst[j * width * 4 + i * 4 + 3] = src[j * width * 4 + i * 4 + 0];
122             }
123         }
124     } else if (fmt_idx == OSD_FMT_ABGR8888) {
125         cfg->fmt = MPP_FMT_ABGR8888;
126         cfg->alpha_cfg.alpha_swap = 0;
127         cfg->rbuv_swap = 1;
128         cfg->stride = width * 4;
129         for (j = 0; j < height; j++) {
130             for (i = 0; i < width; i++) {
131                 dst[j * width * 4 + i * 4 + 0] = src[j * width * 4 + i * 4 + 1];
132                 dst[j * width * 4 + i * 4 + 1] = src[j * width * 4 + i * 4 + 2];
133                 dst[j * width * 4 + i * 4 + 2] = src[j * width * 4 + i * 4 + 3];
134                 dst[j * width * 4 + i * 4 + 3] = src[j * width * 4 + i * 4 + 0];
135             }
136         }
137     } else if (fmt_idx == OSD_FMT_BGRA5551) {
138         cfg->fmt = MPP_FMT_ARGB1555;
139         cfg->alpha_cfg.alpha_swap = 0;
140         cfg->rbuv_swap = 0;
141         cfg->stride = width * 2;
142         tmp_u16 = (RK_U16 *)dst;
143         for (j = 0; j < height; j++) {
144             for (i = 0; i < width; i++) {
145                 tmp_r = src[j * width * 4 + i * 4 + 1];
146                 tmp_g = src[j * width * 4 + i * 4 + 2];
147                 tmp_b = src[j * width * 4 + i * 4 + 3];
148                 tmp_u16[j * width + i] = ((tmp_r >> 3) << 10) +
149                                          ((tmp_g >> 3) << 5) +
150                                          ((tmp_b >> 3) | 0x8000);
151             }
152         }
153     } else if (fmt_idx == OSD_FMT_RGBA5551) {
154         cfg->fmt = MPP_FMT_ARGB1555;
155         cfg->alpha_cfg.alpha_swap = 0;
156         cfg->rbuv_swap = 1;
157         cfg->stride = width * 2;
158         tmp_u16 = (RK_U16 *)dst;
159         for (j = 0; j < height; j++) {
160             for (i = 0; i < width; i++) {
161                 tmp_r = src[j * width * 4 + i * 4 + 1];
162                 tmp_g = src[j * width * 4 + i * 4 + 2];
163                 tmp_b = src[j * width * 4 + i * 4 + 3];
164                 tmp_u16[j * width + i] = ((tmp_b >> 3) << 10) +
165                                          ((tmp_g >> 3) << 5) +
166                                          ((tmp_r >> 3) | 0x8000);
167             }
168         }
169     } else if (fmt_idx == OSD_FMT_ABGR1555) {
170         cfg->fmt = MPP_FMT_ARGB1555;
171         cfg->alpha_cfg.alpha_swap = 1;
172         cfg->rbuv_swap = 0;
173         cfg->stride = width * 2;
174         tmp_u16 = (RK_U16 *)dst;
175         for (j = 0; j < height; j++) {
176             for (i = 0; i < width; i++) {
177                 tmp_r = src[j * width * 4 + i * 4 + 1];
178                 tmp_g = src[j * width * 4 + i * 4 + 2];
179                 tmp_b = src[j * width * 4 + i * 4 + 3];
180                 tmp_u16[j * width + i] = ((tmp_r >> 3) << 11) +
181                                          ((tmp_g >> 3) << 6) +
182                                          ((tmp_b >> 3) << 1) + 1;
183             }
184         }
185     } else if (fmt_idx == OSD_FMT_ARGB1555) {
186         cfg->fmt = MPP_FMT_ARGB1555;
187         cfg->alpha_cfg.alpha_swap = 1;
188         cfg->rbuv_swap = 1;
189         cfg->stride = width * 2;
190         tmp_u16 = (RK_U16 *)dst;
191         for (j = 0; j < height; j++) {
192             for (i = 0; i < width; i++) {
193                 tmp_r = src[j * width * 4 + i * 4 + 1];
194                 tmp_g = src[j * width * 4 + i * 4 + 2];
195                 tmp_b = src[j * width * 4 + i * 4 + 3];
196                 tmp_u16[j * width + i] = ((tmp_b >> 3) << 11) +
197                                          ((tmp_g >> 3) << 6) +
198                                          ((tmp_r >> 3) << 1) + 1;
199             }
200         }
201     } else if (fmt_idx == OSD_FMT_BGRA4444) {
202         cfg->fmt = MPP_FMT_ARGB4444;
203         cfg->alpha_cfg.alpha_swap = 0;
204         cfg->rbuv_swap = 0;
205         cfg->stride = width * 2;
206         tmp_u16 = (RK_U16 *)dst;
207         for (j = 0; j < height; j++) {
208             for (i = 0; i < width; i++) {
209                 tmp_r = src[j * width * 4 + i * 4 + 1];
210                 tmp_g = src[j * width * 4 + i * 4 + 2];
211                 tmp_b = src[j * width * 4 + i * 4 + 3];
212                 tmp_u16[j * width + i] = ((tmp_r >> 4) << 8) +
213                                          ((tmp_g >> 4) << 4) +
214                                          ((tmp_b >> 4) | 0xf000);
215             }
216         }
217     } else if (fmt_idx == OSD_FMT_RGBA4444) {
218         cfg->fmt = MPP_FMT_ARGB4444;
219         cfg->alpha_cfg.alpha_swap = 0;
220         cfg->rbuv_swap = 1;
221         cfg->stride = width * 2;
222         tmp_u16 = (RK_U16 *)dst;
223         for (j = 0; j < height; j++) {
224             for (i = 0; i < width; i++) {
225                 tmp_r = src[j * width * 4 + i * 4 + 1];
226                 tmp_g = src[j * width * 4 + i * 4 + 2];
227                 tmp_b = src[j * width * 4 + i * 4 + 3];
228                 tmp_u16[j * width + i] = ((tmp_b >> 4) << 8) +
229                                          ((tmp_g >> 4) << 4) +
230                                          ((tmp_r >> 4) | 0xf000);
231             }
232         }
233     } else if (fmt_idx == OSD_FMT_ABGR4444) {
234         cfg->fmt = MPP_FMT_ARGB4444;
235         cfg->alpha_cfg.alpha_swap = 1;
236         cfg->rbuv_swap = 0;
237         cfg->stride = width * 2;
238         tmp_u16 = (RK_U16 *)dst;
239         for (j = 0; j < height; j++) {
240             for (i = 0; i < width; i++) {
241                 tmp_r = src[j * width * 4 + i * 4 + 1];
242                 tmp_g = src[j * width * 4 + i * 4 + 2];
243                 tmp_b = src[j * width * 4 + i * 4 + 3];
244                 tmp_u16[j * width + i] = ((tmp_r >> 4) << 12) +
245                                          ((tmp_g >> 4) << 8) +
246                                          ((tmp_b >> 4) << 4) + 0x0f;
247             }
248         }
249     } else if (fmt_idx == OSD_FMT_ARGB4444) {
250         cfg->fmt = MPP_FMT_ARGB4444;
251         cfg->alpha_cfg.alpha_swap = 1;
252         cfg->rbuv_swap = 1;
253         cfg->stride = width * 2;
254         tmp_u16 = (RK_U16 *)dst;
255         for (j = 0; j < height; j++) {
256             for (i = 0; i < width; i++) {
257                 tmp_r = src[j * width * 4 + i * 4 + 1];
258                 tmp_g = src[j * width * 4 + i * 4 + 2];
259                 tmp_b = src[j * width * 4 + i * 4 + 3];
260                 tmp_u16[j * width + i] = ((tmp_b >> 4) << 12) +
261                                          ((tmp_g >> 4) << 8) +
262                                          ((tmp_r >> 4) << 4) + 0x0f;
263             }
264         }
265     } else if (fmt_idx == OSD_FMT_AYUV2BPP) {
266         cfg->fmt = MPP_FMT_AYUV2BPP;
267         cfg->rbuv_swap = 0;
268         cfg->alpha_cfg.alpha_swap = 0;
269         cfg->stride = width / 4;
270         for (j = 0; j < height; j++) {
271             RK_U32 is_black;
272 
273             is_black = (j / SMPTE_BAR_CNT) % 2 ? 1 : 0;
274             for (i = 0; i < width; i++) {
275                 if (is_black)
276                     dst[j * width / 4 + i / 4] = (dst[j * width / 4 + i / 4] << 2) | 0;
277                 else
278                     dst[j * width / 4 + i / 4] = (dst[j * width / 4 + i / 4] << 2) | (1 << 1 | 1);
279             }
280         }
281     } else if (fmt_idx == OSD_FMT_AYUV1BPP) {
282         cfg->fmt = MPP_FMT_AYUV1BPP;
283         cfg->rbuv_swap = 0;
284         cfg->alpha_cfg.alpha_swap = 0;
285         cfg->stride = width / 8;
286         for (j = 0; j < height; j++) {
287             RK_U32 is_black;
288 
289             is_black = (j / SMPTE_BAR_CNT) % 2 ? 1 : 0;
290             for (i = 0; i < width; i++) {
291                 if (is_black)
292                     dst[j * width / 8 + i / 8] = (dst[j * width / 8 + i / 8] << 1) | 0;
293                 else
294                     dst[j * width / 8 + i / 8] = (dst[j * width / 8 + i / 8] << 1) | 1;
295             }
296         }
297     }
298 
299     return ret;
300 }
301 
get_frame_size_by_format(OsdFmt fmt,RK_U32 width,RK_U32 height)302 static RK_U32 get_frame_size_by_format(OsdFmt fmt, RK_U32 width, RK_U32 height)
303 {
304     switch (fmt) {
305     case OSD_FMT_ARGB8888:
306     case OSD_FMT_RGBA8888:
307     case OSD_FMT_BGRA8888:
308     case OSD_FMT_ABGR8888:
309         return width * height * 4;
310     case OSD_FMT_ARGB1555:
311     case OSD_FMT_ABGR1555:
312     case OSD_FMT_RGBA5551:
313     case OSD_FMT_BGRA5551:
314     case OSD_FMT_ARGB4444:
315     case OSD_FMT_ABGR4444:
316     case OSD_FMT_RGBA4444:
317     case OSD_FMT_BGRA4444:
318         return width * height * 2;
319     case OSD_FMT_AYUV2BPP:
320         return width * height / 4;
321     case OSD_FMT_AYUV1BPP:
322         return width * height / 8;
323     default:
324         return 0;
325     }
326 }
327 
osd3_test_case_fmt(MppEncOSDData3 * osd_data)328 static MPP_RET osd3_test_case_fmt(MppEncOSDData3 *osd_data)
329 {
330     MppEncOSDRegion3 *region = &osd_data->region[0];
331 
332     if (region->fmt == MPP_FMT_AYUV2BPP || region->fmt == MPP_FMT_AYUV1BPP)
333         region->alpha_cfg.fg_alpha_sel = FROM_LUT;
334     else
335         region->alpha_cfg.fg_alpha_sel = FROM_DDR;
336 
337     return MPP_OK;
338 }
339 
osd3_test_case_fg_alpha_sel(MppEncOSDData3 * osd_data)340 static MPP_RET osd3_test_case_fg_alpha_sel(MppEncOSDData3 *osd_data)
341 {
342     MppEncOSDRegion3 *region = &osd_data->region[0];
343     RK_U32 region_width = OSD_PATTERN_WIDTH;
344 
345     region->alpha_cfg.fg_alpha_sel = FROM_DDR;
346 
347     region = &osd_data->region[1];
348     memcpy(region, &osd_data->region[0], sizeof(MppEncOSDRegion3));
349     region->lt_x = (region_width + 16);
350     region->rb_x = region->lt_x + region_width - 1;
351     region->alpha_cfg.fg_alpha_sel = FROM_LUT;
352 
353 
354     region = &osd_data->region[2];
355     memcpy(region, &osd_data->region[0], sizeof(MppEncOSDRegion3));
356     region->lt_x = (region_width + 16) * 2;
357     region->rb_x = region->lt_x + region_width - 1;
358     region->alpha_cfg.fg_alpha_sel = FROM_REG;
359     region->alpha_cfg.fg_alpha = 0x80;
360 
361     osd_data->num_region = 3;
362 
363     return MPP_OK;
364 }
365 
osd3_test_case_ch_ds_mode(MppEncOSDData3 * osd_data)366 static MPP_RET osd3_test_case_ch_ds_mode(MppEncOSDData3 *osd_data)
367 {
368     MppEncOSDRegion3 *region = &osd_data->region[0];
369     RK_U32 region_width = OSD_PATTERN_WIDTH;
370 
371     region->ch_ds_mode = AVERAGE;
372 
373     region = &osd_data->region[1];
374     memcpy(region, &osd_data->region[0], sizeof(MppEncOSDRegion3));
375     region->lt_x = (region_width + 16);
376     region->rb_x = region->lt_x + region_width - 1;
377     region->ch_ds_mode = DROP;
378 
379     osd_data->num_region = 2;
380 
381     return MPP_OK;
382 }
383 
osd3_test_case_range_trns_sel(MppEncOSDData3 * osd_data)384 static MPP_RET osd3_test_case_range_trns_sel(MppEncOSDData3 *osd_data)
385 {
386     MppEncOSDRegion3 *region = &osd_data->region[0];
387     RK_U32 region_width = OSD_PATTERN_WIDTH;
388 
389     region->range_trns_sel = FULL_TO_LIMIT;
390     region->range_trns_en = 1;
391 
392     region = &osd_data->region[1];
393     memcpy(region, &osd_data->region[0], sizeof(MppEncOSDRegion3));
394     region->lt_x = (region_width + 16);
395     region->rb_x = region->lt_x + region_width - 1;
396     region->range_trns_sel = LIMIT_TO_FULL;
397 
398     osd_data->num_region = 2;
399 
400     return MPP_OK;
401 }
402 
osd3_test_case_max_reginon_num(MppEncOSDData3 * osd_data)403 static MPP_RET osd3_test_case_max_reginon_num(MppEncOSDData3 *osd_data)
404 {
405     MppEncOSDRegion3 *region = &osd_data->region[0];
406     RK_U32 region_width = OSD_PATTERN_WIDTH;
407     RK_U32 i;
408 
409     for (i = 1; i < 8; i++) {
410         region = &osd_data->region[i];
411         memcpy(region, &osd_data->region[0], sizeof(MppEncOSDRegion3));
412         region->lt_x = (region_width + 16) * i;
413         region->rb_x = region->lt_x + region_width - 1;
414     }
415 
416     osd_data->num_region = 8;
417 
418     return MPP_OK;
419 }
420 
421 static OsdCaseCfg osd3_test_cases[OSD_CASE_BUTT] = {
422     {
423         OSD_CASE_FMT_ARGB8888,
424         OSD_FMT_ARGB8888,
425         "osd argb8888",
426         osd3_test_case_fmt,
427     },
428     {
429         OSD_CASE_FMT_RGBA8888,
430         OSD_FMT_RGBA8888,
431         "osd rgba8888",
432         osd3_test_case_fmt,
433     },
434     {
435         OSD_CASE_FMT_BGRA8888,
436         OSD_FMT_BGRA8888,
437         "osd bgra8888",
438         osd3_test_case_fmt,
439     },
440     {
441         OSD_CASE_FMT_ABGR8888,
442         OSD_FMT_ABGR8888,
443         "osd abgr8888",
444         osd3_test_case_fmt,
445     },
446     {
447         OSD_CASE_FMT_ARGB1555,
448         OSD_FMT_ARGB1555,
449         "osd argb1555",
450         osd3_test_case_fmt,
451     },
452     {
453         OSD_CASE_FMT_ABGR1555,
454         OSD_FMT_ABGR1555,
455         "osd abgr1555",
456         osd3_test_case_fmt,
457     },
458     {
459         OSD_CASE_FMT_RGBA5551,
460         OSD_FMT_RGBA5551,
461         "osd rgba5551",
462         osd3_test_case_fmt,
463     },
464     {
465         OSD_CASE_FMT_BGRA5551,
466         OSD_FMT_BGRA5551,
467         "osd bgra5551",
468         osd3_test_case_fmt,
469     },
470     {
471         OSD_CASE_FMT_ARGB4444,
472         OSD_FMT_ARGB4444,
473         "osd argb4444",
474         osd3_test_case_fmt,
475     },
476     {
477         OSD_CASE_FMT_ABGR4444,
478         OSD_FMT_ABGR4444,
479         "osd abgr4444",
480         osd3_test_case_fmt,
481     },
482     {
483         OSD_CASE_FMT_RGBA4444,
484         OSD_FMT_RGBA4444,
485         "osd rgba4444",
486         osd3_test_case_fmt,
487     },
488     {
489         OSD_CASE_FMT_BGRA4444,
490         OSD_FMT_BGRA4444,
491         "osd bgra4444",
492         osd3_test_case_fmt,
493     },
494     {
495         OSD_CASE_FMT_AYUV2BPP,
496         OSD_FMT_AYUV2BPP,
497         "osd ayuv2bpp",
498         osd3_test_case_fmt,
499     },
500     {
501         OSD_CASE_FMT_AYUV1BPP,
502         OSD_FMT_AYUV1BPP,
503         "osd ayuv1bpp",
504         osd3_test_case_fmt,
505     },
506     {
507         OSD_CASE_FG_ALPAH_SEL,
508         OSD_FMT_ARGB8888,
509         "osd fg alpha sel",
510         osd3_test_case_fg_alpha_sel,
511     },
512     {
513         OSD_CASE_CH_DS_MODE,
514         OSD_FMT_ARGB8888,
515         "osd ch ds mode",
516         osd3_test_case_ch_ds_mode,
517     },
518     {
519         OSD_CASE_RANGE_TRNS_SEL,
520         OSD_FMT_ARGB8888,
521         "osd range trns sel",
522         osd3_test_case_range_trns_sel,
523     },
524     {
525         OSD_CASE_MAX_REGINON_NUM,
526         OSD_FMT_ARGB8888,
527         "osd max reginon num",
528         osd3_test_case_max_reginon_num,
529     }
530 };
531 
osd3_get_test_case(MppEncOSDData3 * osd_data,RK_U8 * base_pattern,RK_U32 case_idx,KmppBuffer * osd_buffer)532 MPP_RET osd3_get_test_case(MppEncOSDData3 *osd_data, RK_U8 *base_pattern, RK_U32 case_idx, KmppBuffer *osd_buffer)
533 {
534     KmppBufCfg osd_buf_cfg = NULL;
535     MPP_RET ret = MPP_OK;
536     RK_U32 buffer_size = 0;
537     KmppShmPtr osd_sptr;
538     RK_U8 *dst_ptr =  NULL;
539     MppEncOSDRegion3 *region = NULL;
540     RK_U32 region_width = OSD_PATTERN_WIDTH;
541     RK_U32 region_height = OSD_PATTERN_HEIGHT;
542 
543     if (!osd_data)
544         return MPP_ERR_NOMEM;
545 
546     region = &osd_data->region[0];
547     memset(region, 0, sizeof(MppEncOSDRegion3));
548 
549     if (*osd_buffer) {
550         kmpp_buffer_put(*osd_buffer);
551         *osd_buffer = NULL;
552     }
553 
554     buffer_size = get_frame_size_by_format(osd3_test_cases[case_idx].fmt, region_width, region_height);
555 
556     kmpp_buffer_get(osd_buffer);
557     if (!*osd_buffer)
558         return MPP_ERR_NOMEM;
559 
560     osd_buf_cfg = kmpp_buffer_to_cfg(*osd_buffer);
561     if (!osd_buf_cfg)
562         return MPP_ERR_NOMEM;
563 
564     kmpp_buf_cfg_set_size(osd_buf_cfg, MPP_ALIGN(buffer_size, 16));
565     kmpp_buffer_setup(*osd_buffer);
566     kmpp_buf_cfg_get_sptr(osd_buf_cfg, &osd_sptr);
567     dst_ptr = (RK_U8 *)(uintptr_t)osd_sptr.uaddr;
568 
569     ret = translate_argb(base_pattern, dst_ptr, region_width, region_height, osd3_test_cases[case_idx].fmt, region);
570 
571     region->osd_buf = *kmpp_obj_to_shm(*osd_buffer);
572     region->lt_x = 0;
573     region->lt_y = 0;
574     region->rb_x = region->lt_x + region_width - 1;
575     region->rb_y = region->lt_y + region_height - 1;
576     region->enable = 1;
577 
578     osd_data->num_region = 1;
579 
580     /* black: y=0, u=0x80, v=0x80, white: y=0xff, u=0x80 v=0x80 */
581     region->lut[0] = 0x80;  // v0
582     region->lut[1] = 0x80;  // u0
583     region->lut[2] = 0;     // y0
584     region->lut[3] = 0x80;  // v1
585     region->lut[4] = 0x80;  // u1
586     region->lut[5] = 0xff;  // y1
587     region->lut[6] = 0xff;  // a0
588     region->lut[7] = 0xff;  // a1
589 
590     region->qp_cfg.qp_adj_en = 1;
591     region->qp_cfg.qp_adj_sel = QP_RELATIVE;
592     region->qp_cfg.qp_min = 10;
593     region->qp_cfg.qp_max = 51;
594     region->qp_cfg.qp = -1;
595 
596     ret = osd3_test_cases[case_idx].func(osd_data);
597 
598     mpp_log("osd case %d : %s done\n", case_idx, osd3_test_cases[case_idx].name);
599 
600     return ret;
601 }
602 
603