1 // Copyright (C) 2022 Beken Corporation
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include <os/os.h>
16 #include <components/log.h>
17
18 #include "media_core.h"
19
20 #include <driver/int.h>
21 #include <os/mem.h>
22 #include <driver/gpio.h>
23 #include <driver/gpio_types.h>
24
25 #include <driver/dma.h>
26 #include <soc/mapping.h>
27 #include <driver/media_types.h>
28
29 #include "frame_buffer.h"
30 #include "mlist.h"
31
32 #define TAG "frame_buffer"
33
34 #include "bk_list.h"
35
36 #define LOGI(...) BK_LOGI(TAG, ##__VA_ARGS__)
37 #define LOGW(...) BK_LOGW(TAG, ##__VA_ARGS__)
38 #define LOGE(...) BK_LOGE(TAG, ##__VA_ARGS__)
39 #define LOGD(...) BK_LOGD(TAG, ##__VA_ARGS__)
40
41
42 frame_buffer_info_t *frame_buffer_info = NULL;
43
44 LIST_HEADER_T jpeg_free_node_list = {&jpeg_free_node_list, &jpeg_free_node_list};
45 LIST_HEADER_T jpeg_ready_node_list = {&jpeg_ready_node_list, &jpeg_ready_node_list};
46
47 LIST_HEADER_T display_free_node_list = {&display_free_node_list, &display_free_node_list};
48 LIST_HEADER_T display_ready_node_list = {&display_ready_node_list, &display_ready_node_list};
49
50
51
frame_buffer_free_frame(frame_buffer_t * buffer)52 void frame_buffer_free_frame(frame_buffer_t *buffer)
53 {
54 LIST_HEADER_T *list = NULL;
55
56 if (buffer->type == FRAME_JPEG)
57 {
58 list = &jpeg_free_node_list;
59 }
60 else if (buffer->type == FRAME_DISPLAY)
61 {
62 list = &display_free_node_list;
63 }
64 else
65 {
66 LOGE("%s unknow type: %d\n", __func__, buffer->type);
67 return;
68 }
69
70 GLOBAL_INT_DECLARATION();
71 GLOBAL_INT_DISABLE();
72
73 if (buffer->lock)
74 {
75 buffer->lock--;
76 }
77 else
78 {
79 frame_buffer_t *tmp = NULL;
80 LIST_HEADER_T *pos, *n;
81
82 list_for_each_safe(pos, n, list)
83 {
84 tmp = list_entry(pos, frame_buffer_t, list);
85 if (tmp->frame == buffer->frame)
86 {
87 LOGW("%s refree\n", __func__);
88 GLOBAL_INT_RESTORE();
89 return;
90 }
91 }
92 }
93
94 LOGD("free: %p, lock: %d\n", buffer->frame, buffer->lock);
95
96 if (buffer->lock == 0)
97 {
98
99 LOGD("free: %p\n");
100 buffer->state = STATE_FRAMED;
101 list_add_tail(&buffer->list, list);
102 }
103
104 GLOBAL_INT_RESTORE();
105 }
106
107
frame_buffer_alloc(frame_type_t type)108 frame_buffer_t *frame_buffer_alloc(frame_type_t type)
109 {
110 frame_buffer_t *frame = NULL, *tmp = NULL;
111 LIST_HEADER_T *free_list = NULL, *ready_list = NULL;
112 LIST_HEADER_T *pos, *n;
113
114 if (type == FRAME_JPEG)
115 {
116 free_list = &jpeg_free_node_list;
117 ready_list = &jpeg_ready_node_list;
118 }
119 else if (type == FRAME_DISPLAY)
120 {
121 free_list = &display_free_node_list;
122 ready_list = &display_ready_node_list;
123 }
124 else
125 {
126 LOGE("%s unknow type: %d\n", __func__, type);
127 return NULL;
128 }
129
130 GLOBAL_INT_DECLARATION();
131
132 GLOBAL_INT_DISABLE();
133
134 list_for_each_safe(pos, n, free_list)
135 {
136 tmp = list_entry(pos, frame_buffer_t, list);
137 if (tmp->state != STATE_ALLOCED)
138 {
139 frame = tmp;
140 list_del(pos);
141 break;
142 }
143 }
144
145 if (frame == NULL)
146 {
147 list_for_each_safe(pos, n, ready_list)
148 {
149 tmp = list_entry(pos, frame_buffer_t, list);
150 if (tmp->state != STATE_ALLOCED)
151 {
152 frame = tmp;
153 list_del(pos);
154 break;
155 }
156 }
157 }
158
159 if (frame != NULL)
160 {
161 frame->state = STATE_ALLOCED;
162 frame->lock++;
163 }
164
165 LOGD("alloc: %p\n", frame->frame);
166
167 GLOBAL_INT_RESTORE();
168
169 return frame;
170 }
171
172
frame_buffer_lock_frame(frame_buffer_t * frame)173 void frame_buffer_lock_frame(frame_buffer_t *frame)
174 {
175 frame->lock++;
176 }
177
frame_buffer_push_frame(frame_buffer_t * buffer)178 void frame_buffer_push_frame(frame_buffer_t *buffer)
179 {
180 LIST_HEADER_T *list = NULL;
181
182 if (buffer->type == FRAME_JPEG)
183 {
184 list = &jpeg_ready_node_list;
185 }
186 else if (buffer->type == FRAME_DISPLAY)
187 {
188 list = &display_ready_node_list;
189 }
190 else
191 {
192 LOGE("%s unknow type: %d\n", __func__, buffer->type);
193 return;
194 }
195
196 GLOBAL_INT_DECLARATION();
197 GLOBAL_INT_DISABLE();
198
199 buffer->lock--;
200 buffer->state = STATE_FRAMED;
201 list_add_tail(&buffer->list, list);
202
203 GLOBAL_INT_RESTORE();
204
205 }
206
207
frame_buffer_pop_frame(frame_type_t type)208 frame_buffer_t *frame_buffer_pop_frame(frame_type_t type)
209 {
210 frame_buffer_t *frame = NULL, *tmp = NULL;
211 LIST_HEADER_T *list = NULL;
212 LIST_HEADER_T *pos, *n;
213
214 if (type == FRAME_JPEG)
215 {
216 list = &jpeg_ready_node_list;
217 }
218 else if (type == FRAME_DISPLAY)
219 {
220 list = &display_ready_node_list;
221 }
222 else
223 {
224 LOGE("%s unknow type: %d\n", __func__, type);
225 return NULL;
226 }
227
228 GLOBAL_INT_DECLARATION();
229
230 GLOBAL_INT_DISABLE();
231
232 list_for_each_safe(pos, n, list)
233 {
234 tmp = list_entry(pos, frame_buffer_t, list);
235 if (tmp->state == STATE_FRAMED)
236 {
237 frame = tmp;
238 list_del(pos);
239 break;
240 }
241 }
242
243 frame->state = STATE_ALLOCED;
244 frame->lock++;
245
246
247 GLOBAL_INT_RESTORE();
248
249 if (frame == NULL)
250 {
251 LOGE("%s get frame failed: %d\n", __func__, type);
252 }
253
254 return frame;
255 }
256
257
frame_buffer_complete_notify(frame_buffer_t * buffer)258 void frame_buffer_complete_notify(frame_buffer_t *buffer)
259 {
260 if (buffer->type == FRAME_JPEG)
261 {
262 if (true == frame_buffer_info->wifi_register
263 && (!frame_buffer_info->wifi_lock)
264 && frame_buffer_info->wifi_comp_cb)
265 {
266 frame_buffer_lock_frame(buffer);
267 frame_buffer_info->wifi_lock = true;
268 frame_buffer_info->wifi_comp_cb(buffer);
269 }
270
271 #ifdef CONFIG_LCD
272
273 if (true == frame_buffer_info->decoder_register
274 && (!frame_buffer_info->decoder_lock)
275 && frame_buffer_info->decoder_comp_cb)
276 {
277 frame_buffer_lock_frame(buffer);
278 frame_buffer_info->decoder_lock = true;
279 frame_buffer_info->decoder_comp_cb(buffer);
280 //LOGD("lcd alloc %p %d:%d:%d\n", buffer, buffer->id, buffer->state, buffer->lock);
281 //lcd_frame_complete_notify(buffer);
282 }
283 #endif
284
285 if (true == frame_buffer_info->capture_register
286 && (!frame_buffer_info->capture_lock)
287 && frame_buffer_info->capture_comp_cb)
288 {
289 frame_buffer_lock_frame(buffer);
290 frame_buffer_info->capture_lock = true;
291 frame_buffer_info->capture_comp_cb(buffer);
292 //storage_capture_frame_notify(buffer);
293 }
294 }
295
296 if (buffer->type == FRAME_DISPLAY)
297 {
298 #ifdef CONFIG_LCD
299
300 if (true == frame_buffer_info->display_register
301 && (!frame_buffer_info->display_lock)
302 && frame_buffer_info->display_comp_cb)
303 {
304 frame_buffer_lock_frame(buffer);
305 frame_buffer_info->display_comp_cb(buffer);
306 }
307
308 #endif
309 }
310
311 frame_buffer_free_frame(buffer);
312 }
313
is_workflow_freezing(frame_type_t type)314 bool is_workflow_freezing(frame_type_t type)
315 {
316 bool ret = true;
317
318 LOGD("WIFI %d:%d, DEC %d:%d\n",
319 frame_buffer_info->wifi_register, frame_buffer_info->wifi_lock,
320 frame_buffer_info->decoder_register, frame_buffer_info->decoder_lock);
321
322 if (type == FRAME_JPEG)
323 {
324 if (true == frame_buffer_info->wifi_register
325 && (!frame_buffer_info->wifi_lock)
326 && frame_buffer_info->wifi_comp_cb)
327 {
328 ret = false;
329 }
330
331 if (true == frame_buffer_info->decoder_register
332 && (!frame_buffer_info->decoder_lock)
333 && frame_buffer_info->decoder_comp_cb)
334 {
335 ret = false;
336 }
337
338 if (true == frame_buffer_info->capture_register
339 && (!frame_buffer_info->capture_lock)
340 && frame_buffer_info->capture_comp_cb)
341 {
342 ret = false;
343 }
344 }
345
346 if (type == FRAME_DISPLAY)
347 {
348 if (true == frame_buffer_info->display_register
349 && (!frame_buffer_info->display_lock)
350 && frame_buffer_info->display_comp_cb)
351 {
352 ret = false;
353 }
354 }
355
356 return ret;
357 }
358
frame_buffer_generate_complete(frame_buffer_t * buffer,frame_type_t type)359 void frame_buffer_generate_complete(frame_buffer_t *buffer, frame_type_t type)
360 {
361 GLOBAL_INT_DECLARATION();
362 GLOBAL_INT_DISABLE();
363
364 frame_buffer_push_frame(buffer);
365
366 if (!is_workflow_freezing(type))
367 {
368 LOGD("notify frame[%d]: %u complete, %d\n", buffer->id, buffer->sequence, type);
369
370 frame_buffer_t *frame = frame_buffer_pop_frame(type);
371 frame_buffer_complete_notify(frame);
372 }
373 else
374 {
375 LOGD("covery frame[%d]: %u complete, %d\n", buffer->id, buffer->sequence, type);
376 }
377
378 GLOBAL_INT_RESTORE();
379 }
380
frame_buffer_frame_register(frame_module_t module,void * callback)381 void frame_buffer_frame_register(frame_module_t module, void *callback)
382 {
383 GLOBAL_INT_DECLARATION();
384 GLOBAL_INT_DISABLE();
385
386 switch (module)
387 {
388 case MODULE_WIFI:
389 frame_buffer_info->wifi_register = true;
390 frame_buffer_info->wifi_comp_cb = callback;
391 break;
392 case MODULE_DECODER:
393 frame_buffer_info->decoder_register = true;
394 frame_buffer_info->decoder_comp_cb = callback;
395 break;
396 case MODULE_RECODER:
397 frame_buffer_info->recoder_register = true;
398 frame_buffer_info->recoder_comp_cb = callback;
399 break;
400 case MODULE_CAPTURE:
401 frame_buffer_info->capture_register = true;
402 frame_buffer_info->capture_lock = false;
403 frame_buffer_info->capture_comp_cb = callback;
404 break;
405 case MODULE_DISPLAY:
406 frame_buffer_info->display_register = true;
407 frame_buffer_info->display_lock = false;
408 frame_buffer_info->display_comp_cb = callback;
409 break;
410 }
411
412 GLOBAL_INT_RESTORE();
413 }
414
frame_buffer_frame_deregister(frame_module_t module)415 void frame_buffer_frame_deregister(frame_module_t module)
416 {
417 GLOBAL_INT_DECLARATION();
418 GLOBAL_INT_DISABLE();
419
420 LOGI("dereg: %d\n", module);
421
422 switch (module)
423 {
424 case MODULE_WIFI:
425 frame_buffer_info->wifi_register = false;
426 frame_buffer_info->wifi_lock = false;
427 frame_buffer_info->wifi_comp_cb = NULL;
428 break;
429 case MODULE_DECODER:
430 frame_buffer_info->decoder_register = false;
431 frame_buffer_info->decoder_lock = false;
432 frame_buffer_info->decoder_comp_cb = NULL;
433 break;
434 case MODULE_RECODER:
435 frame_buffer_info->recoder_register = false;
436 frame_buffer_info->recoder_lock = false;
437 frame_buffer_info->recoder_comp_cb = NULL;
438 break;
439 case MODULE_CAPTURE:
440 frame_buffer_info->capture_register = false;
441 frame_buffer_info->capture_lock = false;
442 frame_buffer_info->capture_comp_cb = NULL;
443 break;
444 case MODULE_DISPLAY:
445 frame_buffer_info->display_register = false;
446 frame_buffer_info->display_lock = false;
447 frame_buffer_info->display_comp_cb = NULL;
448 break;
449 }
450
451 GLOBAL_INT_RESTORE();
452 }
453
454
frame_buffer_free_request(frame_buffer_t * buffer,frame_module_t module)455 void frame_buffer_free_request(frame_buffer_t *buffer, frame_module_t module)
456 {
457 GLOBAL_INT_DECLARATION();
458
459 if (buffer->lock == 0)
460 {
461 LOGE("%s invalid frame free\n", __func__);
462 return;
463 }
464
465 frame_buffer_free_frame(buffer);
466
467 GLOBAL_INT_DISABLE();
468
469 switch (module)
470 {
471 case MODULE_WIFI:
472 frame_buffer_info->wifi_lock = false;
473 LOGD("wifi free %p %d:%d:%d:%d\n", buffer, buffer->id, buffer->state, buffer->lock, buffer->sequence);
474 break;
475 case MODULE_DECODER:
476 frame_buffer_info->decoder_lock = false;
477 LOGD("lcd free %p %d:%d:%d:%d\n", buffer, buffer->id, buffer->state, buffer->lock, buffer->sequence);
478 break;
479 case MODULE_RECODER:
480 break;
481 case MODULE_CAPTURE:
482 LOGD("capture free %p %d:%d:%d:%d\n", buffer, buffer->id, buffer->state, buffer->lock, buffer->sequence);
483 break;
484 case MODULE_DISPLAY:
485 frame_buffer_info->display_lock = false;
486 LOGD("lcd free %p %d:%d:%d:%d\n", buffer, buffer->id, buffer->state, buffer->lock, buffer->sequence);
487 break;
488 }
489
490 GLOBAL_INT_RESTORE();
491 }
492
frame_buffer_jpeg_frame_init(void)493 int frame_buffer_jpeg_frame_init(void)
494 {
495 LOGI("frame_buffer_jpeg_frame_init, %d\n", frame_buffer_info->minimal_layout);
496
497 #ifdef CONFIG_PSRAM
498 frame_buffer_t *tmp = NULL;
499 LIST_HEADER_T *pos, *n;
500
501 if (!list_empty(&jpeg_free_node_list))
502 {
503 list_for_each_safe(pos, n, &jpeg_free_node_list)
504 {
505 tmp = list_entry(pos, frame_buffer_t, list);
506 if (tmp != NULL)
507 {
508 list_del(pos);
509 os_free(tmp);
510 break;
511 }
512 }
513
514 INIT_LIST_HEAD(&jpeg_free_node_list);
515 }
516
517 if (!list_empty(&jpeg_ready_node_list))
518 {
519 list_for_each_safe(pos, n, &jpeg_ready_node_list)
520 {
521 tmp = list_entry(pos, frame_buffer_t, list);
522 if (tmp != NULL)
523 {
524 list_del(pos);
525 os_free(tmp);
526 break;
527 }
528 }
529
530 INIT_LIST_HEAD(&jpeg_ready_node_list);
531 }
532
533 if (frame_buffer_info->minimal_layout == true)
534 {
535 for (int i = 0; i < JPEG_ENC_FRAME_COUNT; i ++)
536 {
537 frame_buffer_t *frame = (frame_buffer_t *)os_malloc(sizeof(frame_buffer_t));
538
539 os_memset(frame, 0, sizeof(frame_buffer_t));
540
541 frame->state = STATE_INVALID;
542
543 frame->frame = psram_map->jpeg_enc[i];
544 frame->size = sizeof(psram_map->jpeg_enc[i]);
545
546 frame->id = i;
547 frame->type = FRAME_JPEG;
548 frame->length = 0;
549 frame->sequence = 0;
550 frame->lock = 0;
551 list_add_tail(&frame->list, &jpeg_free_node_list);
552
553 LOGI("init: %p\n", frame->frame);
554 }
555 }
556 else
557 {
558 for (int i = 0; i < JPEG_ENC_FRAME_COUNT; i ++)
559 {
560 frame_buffer_t *frame = (frame_buffer_t *)os_malloc(sizeof(frame_buffer_t));
561
562 os_memset(frame, 0, sizeof(frame_buffer_t));
563
564 frame->state = STATE_INVALID;
565 frame->frame = psram_720p_map->jpeg_enc[i];
566 frame->size = sizeof(psram_720p_map->jpeg_enc[i]);
567 frame->id = i;
568 frame->type = FRAME_JPEG;
569 frame->length = 0;
570 frame->sequence = 0;
571 frame->lock = 0;
572 list_add_tail(&frame->list, &jpeg_free_node_list);
573 }
574 }
575
576 #endif
577 return BK_OK;
578 }
579
frame_buffer_display_frame_init(void)580 int frame_buffer_display_frame_init(void)
581 {
582 #ifdef CONFIG_PSRAM
583
584 frame_buffer_t *tmp = NULL;
585 LIST_HEADER_T *pos, *n;
586
587 if (!list_empty(&display_free_node_list))
588 {
589 list_for_each_safe(pos, n, &display_free_node_list)
590 {
591 tmp = list_entry(pos, frame_buffer_t, list);
592 if (tmp != NULL)
593 {
594 list_del(pos);
595 os_free(tmp);
596 break;
597 }
598 }
599
600 INIT_LIST_HEAD(&display_free_node_list);
601 }
602
603 if (!list_empty(&display_ready_node_list))
604 {
605 list_for_each_safe(pos, n, &display_ready_node_list)
606 {
607 tmp = list_entry(pos, frame_buffer_t, list);
608 if (tmp != NULL)
609 {
610 list_del(pos);
611 os_free(tmp);
612 break;
613 }
614 }
615
616 INIT_LIST_HEAD(&display_ready_node_list);
617 }
618
619 if (frame_buffer_info->minimal_layout)
620 {
621 for (int i = 0; i < DISPLAY_FRAME_COUNT; i++)
622 {
623 frame_buffer_t *frame = (frame_buffer_t *)os_malloc(sizeof(frame_buffer_t));
624
625 os_memset(frame, 0, sizeof(frame_buffer_t));
626
627 frame->state = STATE_INVALID;
628 frame->frame = psram_map->display[i];
629 frame->size = sizeof(psram_map->display[i]);
630 frame->id = i;
631 frame->type = FRAME_DISPLAY;
632 frame->length = 0;
633 frame->sequence = 0;
634 frame->lock = 0;
635 list_add_tail(&frame->list, &display_free_node_list);
636 }
637 }
638 else
639 {
640 for (int i = 0; i < DISPLAY_720P_FRAME_COUNT; i ++)
641 {
642 frame_buffer_t *frame = (frame_buffer_t *)os_malloc(sizeof(frame_buffer_t));
643
644 os_memset(frame, 0, sizeof(frame_buffer_t));
645
646 frame->state = STATE_INVALID;
647 frame->frame = psram_720p_map->display[i];
648 frame->size = sizeof(psram_720p_map->display[i]);
649 frame->id = i;
650 frame->type = FRAME_DISPLAY;
651 frame->length = 0;
652 frame->sequence = 0;
653 frame->lock = 0;
654 list_add_tail(&frame->list, &display_free_node_list);
655 }
656 }
657
658 #endif
659 return BK_OK;
660 }
661
662
frame_buffer_init(void)663 void frame_buffer_init(void)
664 {
665 if (frame_buffer_info == NULL)
666 {
667 frame_buffer_info = (frame_buffer_info_t *)os_malloc(sizeof(frame_buffer_info_t));
668 os_memset((void *)frame_buffer_info, 0, sizeof(frame_buffer_info_t));
669 }
670 frame_buffer_info->minimal_layout = true;
671
672 LOGI("frame_buffer_init, %d\n", frame_buffer_info->minimal_layout);
673 }
674
frame_buffer_set_ppi(media_ppi_t ppi,frame_type_t type)675 int frame_buffer_set_ppi(media_ppi_t ppi, frame_type_t type)
676 {
677 uint16 width, heigth;
678
679 LOGI("%s, ppi %dX%d\n", __func__, ppi >> 16, ppi & 0xFFFF);
680
681
682 if (frame_buffer_info == NULL)
683 {
684 LOGE("%s frame_buffer_info is NULL\n", __func__);
685 return BK_FAIL;
686 }
687
688 width = ppi_to_pixel_x(ppi);
689 heigth = ppi_to_pixel_y(ppi);
690
691 if (width * heigth > PIXEL_800 * PIXEL_600)
692 {
693 LOGI("%s, 720P Memory Layout Set\n", __func__);
694 frame_buffer_info->minimal_layout = false;
695 }
696 else
697 {
698 frame_buffer_info->minimal_layout = true;
699 }
700
701
702 if (type == FRAME_JPEG)
703 {
704 frame_buffer_jpeg_frame_init();
705 }
706
707 if (type == FRAME_DISPLAY)
708 {
709 frame_buffer_display_frame_init();
710 }
711
712 return BK_OK;
713 }
frame_buffer_get_state(void)714 bool frame_buffer_get_state(void)
715 {
716 bool ret = false;
717
718 if (frame_buffer_info)
719 {
720 ret = frame_buffer_info->enable;
721 }
722
723 return ret;
724 }
725
frame_buffer_enable(bool enable)726 void frame_buffer_enable(bool enable)
727 {
728 LOGI("%s, %d\n", __func__, enable);
729
730 if (frame_buffer_info)
731 {
732 os_memset((void *)frame_buffer_info, 0, sizeof(frame_buffer_info_t));
733
734 frame_buffer_info->enable = enable;
735 }
736 frame_buffer_info->minimal_layout = true;
737 }
738
frame_buffer_deinit(void)739 void frame_buffer_deinit(void)
740 {
741 if (frame_buffer_info)
742 {
743 os_free(frame_buffer_info);
744 frame_buffer_info = NULL;
745 frame_buffer_info->minimal_layout = true;
746 }
747 }
748