amvideo: add dv support for video_receiver [1/2]
authorBrian Zhu <brian.zhu@amlogic.com>
Tue, 26 Nov 2019 17:55:13 +0000 (01:55 +0800)
committerBrian Zhu <brian.zhu@amlogic.com>
Mon, 2 Dec 2019 07:01:27 +0000 (00:01 -0700)
PD#SWPL-17393

Problem:
video receiver has no dv vframe operation.

Solution:
Add dv vframe operation.

Verify:
Verifed by u212

Change-Id: I0caf24d85a0d6d8382c13d72d9a439390ac21047
Signed-off-by: Brian Zhu <brian.zhu@amlogic.com>
drivers/amlogic/media/video_sink/video.c
drivers/amlogic/media/video_sink/video_priv.h
drivers/amlogic/media/video_sink/video_receiver.c

index eb1334bb87add3e316f0ff5315d79a546d802fda..ed17b68c402443f60d11721b03241a34645dc5d0 100644 (file)
@@ -2392,6 +2392,7 @@ static int dvel_swap_frame(struct vframe_s *vf)
                        dvel_changed = true;
                        dvel_size = new_dvel_w;
                        need_disable_vd2 = false;
+                       safe_switch_videolayer(1, true, true);
                }
                /* check the el size */
                if (dvel_size != new_dvel_w)
@@ -2409,7 +2410,7 @@ static int dvel_swap_frame(struct vframe_s *vf)
        return ret;
 }
 
-static struct vframe_s *dvel_toggle_frame(
+struct vframe_s *dvel_toggle_frame(
        struct vframe_s *vf, bool new_frame)
 {
        struct vframe_s *toggle_vf = NULL;
@@ -4268,10 +4269,6 @@ SET_FILTER:
                path2_new_frame =
                        gvideo_recv[0]->func->dequeue_frame(gvideo_recv[0]);
                if (vd1_path_id == gvideo_recv[0]->path_id) {
-                       /* FIXME: need DV dual layer case */
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
-                       dv_new_vf = dvel_toggle_frame(vf, true);
-#endif
                        amvecm_on_vs(
                                (gvideo_recv[0]->cur_buf !=
                                 &gvideo_recv[0]->local_buf)
@@ -4307,10 +4304,6 @@ SET_FILTER:
                path3_new_frame =
                        gvideo_recv[1]->func->dequeue_frame(gvideo_recv[1]);
                if (vd1_path_id == gvideo_recv[1]->path_id) {
-                       /* FIXME: need DV dual layer case */
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
-                       dv_new_vf = dvel_toggle_frame(vf, true);
-#endif
                        amvecm_on_vs(
                                (gvideo_recv[1]->cur_buf !=
                                 &gvideo_recv[1]->local_buf)
@@ -4742,8 +4735,13 @@ SET_FILTER:
                VD2_PATH);
 #endif
 
-       if (need_disable_vd2)
+       if (need_disable_vd2) {
                safe_switch_videolayer(1, false, true);
+#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
+               /* reset dvel statue when disable vd2 */
+               dvel_status = false;
+#endif
+       }
 
        /* filter setting management */
        frame_par_di_set = primary_render_frame(
index f10625b436e57884add9d7f58bf933e90f2f1308..238fe2018aa0ded41e08f63e9b32e1c265910fae 100644 (file)
@@ -405,6 +405,10 @@ int get_video_debug_flags(void);
 int _video_set_disable(u32 val);
 int _videopip_set_disable(u32 val);
 struct device *get_video_device(void);
+#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
+struct vframe_s *dvel_toggle_frame(
+       struct vframe_s *vf, bool new_frame);
+#endif
 
 #ifdef CONFIG_AMLOGIC_MEDIA_VIDEOCAPTURE
 int ext_frame_capture_poll(int endflags);
index db4439239449e44f9d5c33a8327d00e187540756..1018772a9ab08de7dedf21434c4b653ffd8a0571 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/amlogic/media/vfm/vframe_receiver.h>
 #include <linux/amlogic/media/video_sink/vpp.h>
 #include <linux/amlogic/media/video_sink/video.h>
+#include <linux/amlogic/media/amdolbyvision/dolby_vision.h>
 
 #include "video_priv.h"
 #include "video_receiver.h"
@@ -115,8 +116,7 @@ static inline void common_vf_put(
        vfp = vf_get_provider(ins->recv_name);
        if (vfp && vf) {
                vf_put(vf, ins->recv_name);
-/* FIXME: chek if need enable */
-#ifdef ENABLE_DV /* CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION */
+#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
                if ((glayer_info[0].display_path_id == ins->path_id) &&
                    is_dolby_vision_enable())
                        dolby_vision_vf_put(vf);
@@ -229,11 +229,31 @@ static int common_receiver_event_fun(
        return 0;
 }
 
+static inline int recycle_dvel_vf_put(void)
+{
+#define DVEL_RECV_NAME "dvel"
+
+       int event = 0, ret = 0;
+       struct vframe_s *vf = NULL;
+       struct vframe_provider_s *vfp = vf_get_provider(DVEL_RECV_NAME);
+
+       if (vfp) {
+               vf = vf_get(DVEL_RECV_NAME);
+               if (vf) {
+                       vf_put(vf, DVEL_RECV_NAME);
+                       event |= VFRAME_EVENT_RECEIVER_PUT;
+                       vf_notify_provider(DVEL_RECV_NAME, event, NULL);
+                       ret = 1;
+               }
+       }
+       return ret;
+}
+
 static const struct vframe_receiver_op_s common_recv_func = {
        .event_cb = common_receiver_event_fun
 };
 
-#ifdef ENABLE_DV /* CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION */
+#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
 static int dolby_vision_need_wait_common(struct video_recv_s *ins)
 {
        struct vframe_s *vf;
@@ -311,6 +331,8 @@ static struct vframe_s *recv_common_dequeue_frame(
        struct video_recv_s *ins)
 {
        struct vframe_s *vf = NULL;
+       struct vframe_s *toggle_vf = NULL;
+       s32 drop_count = -1;
 
        if (!ins) {
                pr_err("recv_common_dequeue_frame error, empty ins\n");
@@ -318,33 +340,76 @@ static struct vframe_s *recv_common_dequeue_frame(
        }
 
        vf = common_vf_peek(ins);
-/* FIXME: chek if need enable */
-#ifdef ENABLE_DV /* CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION */
-       if ((glayer_info[0].display_path_id == ins->path_id) && vf &&
+#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
+       if ((glayer_info[0].display_path_id == ins->path_id) &&
            is_dolby_vision_enable()) {
-               dolby_vision_check_hdr10(vf);
-               dolby_vision_check_hdr10plus(vf);
-               dolby_vision_check_hlg(vf);
+               struct provider_aux_req_s req;
+               u32 i, bl_cnt = 0xffffffff;
+
+               if (vf) {
+                       dolby_vision_check_mvc(vf);
+                       dolby_vision_check_hdr10(vf);
+                       dolby_vision_check_hdr10plus(vf);
+                       dolby_vision_check_hlg(vf);
+               }
+               if (vf_peek("dvel")) {
+                       req.vf = NULL;
+                       req.bot_flag = 0;
+                       req.aux_buf = NULL;
+                       req.aux_size = 0xffffffff;
+                       req.dv_enhance_exist = 0;
+                       vf_notify_provider_by_name(
+                               "dvbldec",
+                               VFRAME_EVENT_RECEIVER_GET_AUX_DATA,
+                               (void *)&req);
+                       bl_cnt = req.aux_size;
+
+                       req.vf = NULL;
+                       req.bot_flag = 0;
+                       req.aux_buf = NULL;
+                       req.aux_size = 0xffffffff;
+                       req.dv_enhance_exist = 0;
+                       vf_notify_provider_by_name(
+                               "dveldec",
+                               VFRAME_EVENT_RECEIVER_GET_AUX_DATA,
+                               (void *)&req);
+                       if ((req.aux_size != 0xffffffff) &&
+                           (bl_cnt != 0xffffffff) &&
+                           (bl_cnt > req.aux_size)) {
+                               i = bl_cnt - req.aux_size;
+                               while (i > 0) {
+                                       if (!recycle_dvel_vf_put())
+                                               break;
+                                       i--;
+                               }
+                       }
+               }
        }
 #endif
        while (vf) {
                if (!vf->frame_dirty) {
-#ifdef ENABLE_DV /* CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION */
+#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
                        if ((glayer_info[0].display_path_id == ins->path_id) &&
                            dolby_vision_need_wait_common(ins))
                                break;
 #endif
                        vf = common_vf_get(ins);
-                       if (vf)
+                       if (vf) {
                                common_toggle_frame(ins, vf);
+                               toggle_vf = vf;
+#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
+                               dvel_toggle_frame(vf, true);
+#endif
+                       }
                } else {
                        vf = common_vf_get(ins);
                        if (vf)
                                common_vf_put(ins, vf);
                }
+               drop_count++;
                vf = common_vf_peek(ins);
        }
-       return vf;
+       return toggle_vf;
 }
 
 static s32 recv_common_return_frame(