vmh264: fixed vf being output repeatly issue. [2/2]
authorHui Zhang <hui.zhang@amlogic.com>
Fri, 28 Aug 2020 11:36:07 +0000 (19:36 +0800)
committerHui Zhang <hui.zhang@amlogic.com>
Sun, 13 Sep 2020 04:09:20 +0000 (21:09 -0700)
PD#SWPL-31351

Problem:
sometimes frame was output twice, because there is race
condition between vf_put and get_smallest_poc. so it
need lock to protect critical code

Solution:
add lock to protect critiacl code

Verify:
AC214

Change-Id: I6c7aed70f3a9e3f4d72ff53f5256b117a62c7399
Signed-off-by: Hui Zhang <hui.zhang@amlogic.com>
drivers/frame_provider/decoder/h264_multi/h264_dpb.c
drivers/frame_provider/decoder/h264_multi/h264_dpb.h
drivers/frame_provider/decoder/h264_multi/vmh264.c

index 958c7fa0224268edbe537d67b218facf446adeb9..8ab6103b53bedba4992c7ba479d12e53d8ac2e18 100644 (file)
@@ -2212,8 +2212,11 @@ static void get_smallest_poc(struct DecodedPictureBuffer *p_Dpb, int *poc,
                             int *pos)
 {
        unsigned int i;
+       unsigned long flags;
        struct h264_dpb_stru *p_H264_Dpb = container_of(p_Dpb,
                                struct h264_dpb_stru, mDPB);
+       struct vdec_s *vdec= (struct vdec_s *)p_H264_Dpb->vdec;
+       void *p = vh264_get_bufspec_lock(vdec);
        dpb_print(p_H264_Dpb->decoder_index,
                PRINT_FLAG_DPB_DETAIL, "%s\n", __func__);
        if (p_Dpb->used_size < 1) {
@@ -2224,6 +2227,9 @@ static void get_smallest_poc(struct DecodedPictureBuffer *p_Dpb, int *poc,
 
        *pos = -1;
        *poc = INT_MAX;
+       if (p == NULL)
+               return;
+       spin_lock_irqsave(p, flags);
        for (i = 0; i < p_Dpb->used_size; i++) {
 #ifdef OUTPUT_BUFFER_IN_C
                /* rain */
@@ -2237,6 +2243,7 @@ static void get_smallest_poc(struct DecodedPictureBuffer *p_Dpb, int *poc,
                        *pos = i;
                }
        }
+       spin_unlock_irqrestore(p, flags);
 }
 
 int output_frames(struct h264_dpb_stru *p_H264_Dpb, unsigned char flush_flag)
index 3f5ad900fc4a7eae5f054cad137f73dce633531f..ac549b0b02297c45a899004d1b7976a8d139209e 100644 (file)
@@ -976,6 +976,8 @@ void dump_dpb(struct DecodedPictureBuffer *p_Dpb, u8 force);
 
 void dump_pic(struct h264_dpb_stru *p_H264_Dpb);
 
+void * vh264_get_bufspec_lock(struct vdec_s *vdec);
+
 enum PictureStructure get_cur_slice_picture_struct(
        struct h264_dpb_stru *p_H264_Dpb);
 
index c918618a19813c54acf5b0417d338225c75de443..b367c958d6e01922a3b02d01edd1dd3f715819c5 100644 (file)
@@ -4215,7 +4215,14 @@ static void vh264_vf_put(struct vframe_s *vf, void *op_arg)
        if (hw->buffer_empty_flag)
                WRITE_VREG(ASSIST_MBOX1_IRQ_REG, 0x1);
 }
-
+void * vh264_get_bufspec_lock(struct vdec_s *vdec)
+{
+       struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)vdec->private;
+       if (hw)
+               return (&hw->bufspec_lock);
+       else
+               return NULL;
+}
 static int vh264_event_cb(int type, void *data, void *op_arg)
 {
        unsigned long flags;