AML: v4l2_qbuf
authorRay <1458889+Raybuntu@users.noreply.github.com>
Wed, 6 Mar 2019 08:25:36 +0000 (09:25 +0100)
committerNick Xie <nick@khadas.com>
Fri, 12 Jul 2019 05:36:34 +0000 (13:36 +0800)
drivers/amlogic/media/deinterlace/deinterlace.c
drivers/amlogic/media/deinterlace/deinterlace.h
drivers/amlogic/media/frame_sync/ptsserv.c
drivers/amlogic/media/video_processor/video_dev/amlvideo.c
drivers/amlogic/media/video_processor/video_dev/amlvideo.h

index a553f17..9f189d0 100644 (file)
@@ -4403,6 +4403,7 @@ static void vscale_skip_disable_post(struct di_buf_s *di_buf, vframe_t *disp_vf)
        disp_vf->height = di_buf_i->vframe->height;
        disp_vf->duration = di_buf_i->vframe->duration;
        disp_vf->pts = di_buf_i->vframe->pts;
+       disp_vf->pts_us64 = di_buf_i->vframe->pts_us64;
        disp_vf->flag = di_buf_i->vframe->flag;
        disp_vf->canvas0Addr = di_post_idx[di_post_stru.canvas_id][0];
        disp_vf->canvas1Addr = di_post_idx[di_post_stru.canvas_id][0];
@@ -5265,16 +5266,20 @@ void drop_frame(int check_drop, int throw_flag, struct di_buf_s *di_buf)
        int i = 0, drop_flag = 0;
 
        di_lock_irqfiq_save(irq_flag2);
-       if ((frame_count == 0) && check_drop)
+       if ((frame_count == 0) && check_drop) {
                di_post_stru.start_pts = di_buf->vframe->pts;
+               di_post_stru.start_pts_us64 = di_buf->vframe->pts_us64;
+       }
        if ((check_drop && (frame_count < start_frame_drop_count))
        || throw_flag) {
                drop_flag = 1;
        } else {
                if (check_drop && (frame_count == start_frame_drop_count)) {
                        if ((di_post_stru.start_pts)
-                       && (di_buf->vframe->pts == 0))
+                       && (di_buf->vframe->pts == 0)) {
                                di_buf->vframe->pts = di_post_stru.start_pts;
+                               di_buf->vframe->pts_us64 = di_post_stru.start_pts_us64;
+                       }
                        di_post_stru.start_pts = 0;
                }
                for (i = 0; i < 3; i++) {
index 0e38fdd..18fb777 100644 (file)
@@ -374,6 +374,7 @@ struct di_post_stru_s {
        bool            toggle_flag;
        bool            vscale_skip_flag;
        uint            start_pts;
+       u64             start_pts_us64;
        int             buf_type;
        int de_post_process_done;
        int post_de_busy;
index 82e1213..c24d225 100644 (file)
@@ -230,7 +230,8 @@ int calculation_stream_delayed_ms(u8 type, u32 *latestbitrate,
                        outtime = timestamp_pcrscr_get();
        if (outtime == 0 || outtime == 0xffffffff)
                outtime = pTable->last_checkout_pts;
-       timestampe_delayed = (pTable->last_checkin_pts - outtime) / 90;
+       if (pTable->last_checkin_pts > outtime)
+               timestampe_delayed = (pTable->last_checkin_pts - outtime) / 90;
        pTable->last_pts_delay_ms = timestampe_delayed;
        if (get_buf_by_type_cb && stbuf_level_cb && stbuf_space_cb) {
                if ((timestampe_delayed < 10)
@@ -276,7 +277,7 @@ int calculation_stream_delayed_ms(u8 type, u32 *latestbitrate,
                                                type)))
                                diff = diff2;
                }
-               delay_ms = diff * 1000 / (1 + pTable->last_avg_bitrate / 8);
+               delay_ms = (diff * 1000) / (int)(1 + pTable->last_avg_bitrate / 8);
                if ((timestampe_delayed < 10) ||
                        ((abs
                        (timestampe_delayed - delay_ms) > (3 * 1000))
@@ -919,7 +920,7 @@ static int pts_lookup_offset_inline_locked(u8 type, u32 offset, u32 *val,
                         */
                        if (!pTable->first_lookup_ok) {
                                *val = pTable->first_checkin_pts;
-                               *uS64 = (u64)(*val) << 32;
+                               *uS64 = div64_u64((u64)pTable->first_checkin_pts * 100, 9);
                                pTable->first_lookup_ok = 1;
                                pTable->first_lookup_is_fail = 1;
 
index 35fac2a..f65c24a 100644 (file)
@@ -76,6 +76,8 @@ AMLVIDEO_MINOR_VERSION, AMLVIDEO_RELEASE)
 #define AMLVIDEO_POOL_SIZE 16
 /*extern bool omx_secret_mode;*/
 
+static u32 omx_freerun_index = 0;
+
 #define DUR2PTS(x) ((x) - ((x) >> 4))
 #define DUR2PTS_RM(x) ((x) & 0xf)
 
@@ -189,11 +191,12 @@ static int amlvideo_vf_states(struct vframe_states *states, void *op_arg)
        /* unsigned long flags; */
        /* spin_lock_irqsave(&lock, flags); */
        struct vivi_dev *dev = (struct vivi_dev *)op_arg;
+       int avail_count = vfq_level(&dev->q_ready) + vfq_level(&dev->q_omx);
 
        states->vf_pool_size = AMLVIDEO_POOL_SIZE;
        states->buf_recycle_num = 0;
-       states->buf_free_num = AMLVIDEO_POOL_SIZE - vfq_level(&dev->q_ready);
-       states->buf_avail_num = vfq_level(&dev->q_ready);
+       states->buf_free_num = AMLVIDEO_POOL_SIZE - avail_count;
+       states->buf_avail_num = avail_count;
        /* spin_unlock_irqrestore(&lock, flags); */
        return 0;
 }
@@ -240,6 +243,8 @@ static int video_receiver_event_fun(int type, void *data, void *private_data)
                dev->first_frame = 0;
                vfq_init(&dev->q_ready, AMLVIDEO_POOL_SIZE + 1,
                        &dev->amlvideo_pool_ready[0]);
+               vfq_init(&dev->q_omx, AMLVIDEO_POOL_SIZE + 1,
+                                &dev->amlvideo_pool_omx[0]);
        }
        if (type == VFRAME_EVENT_PROVIDER_REG) {
                AMLVIDEO_DBG("AML:VFRAME_EVENT_PROVIDER_REG\n");
@@ -271,6 +276,8 @@ static int video_receiver_event_fun(int type, void *data, void *private_data)
                        omx_secret_mode = true;
                        vfq_init(&dev->q_ready, AMLVIDEO_POOL_SIZE + 1,
                                        &dev->amlvideo_pool_ready[0]);
+                       vfq_init(&dev->q_omx, AMLVIDEO_POOL_SIZE + 1,
+                                        &dev->amlvideo_pool_omx[0]);
                        vf_provider_init(&dev->video_vf_prov,
                                                dev->vf_provider_name,
                                                &amlvideo_vf_provider, dev);
@@ -289,6 +296,8 @@ static int video_receiver_event_fun(int type, void *data, void *private_data)
                dev->first_frame = 0;
                vfq_init(&dev->q_ready, AMLVIDEO_POOL_SIZE + 1,
                        &dev->amlvideo_pool_ready[0]);
+               vfq_init(&dev->q_omx, AMLVIDEO_POOL_SIZE + 1,
+                       &dev->amlvideo_pool_omx[0]);
 
                vf_notify_receiver(dev->vf_provider_name,
                        VFRAME_EVENT_PROVIDER_RESET, data);
@@ -528,6 +537,28 @@ static int vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *p)
 
 static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p)
 {
+       u32 index;
+       struct vframe_s *vf;
+       struct vivi_dev *dev = video_drvdata(file);
+       while ((vf = vfq_peek(&dev->q_omx)))
+       {
+               index = (u32)vf->pts_us64;
+               if (p->index > index)
+               {
+                       vf_put(vfq_pop(&dev->q_omx), dev->vf_receiver_name);
+                       printk("vidioc_qbuf skip: index:%u:%u\n", p->index, index);
+                       continue;
+               }
+               else if (p->index == index)
+               {
+                       vf = (vfq_pop(&dev->q_omx));
+                       if (p->flags & V4L2_BUF_FLAG_DONE)
+                               vf_put(vf, dev->vf_receiver_name);
+                       else
+                               vfq_push(&dev->q_ready, vf);
+               }
+               break;
+       }
        return 0;
 }
 
@@ -562,6 +593,9 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
        dev->am_parm.master_display_colour
                = dev->vf->prop.master_display_colour;
 
+       if (!dev->vf->pts_us64)
+               dev->vf->pts_us64 = ((u64)dev->vf->pts * 100) / 9;
+
        if (dev->vf->pts_us64) {
                dev->first_frame = 1;
                pts_us64 = dev->vf->pts_us64;
@@ -584,12 +618,13 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
        if (dev->vf->next_vf_pts_valid)
                dev->vf->next_vf_pts = next_vf->pts;
 
-       vfq_push(&dev->q_ready, dev->vf);
-       p->index = 0;
+       p->index = omx_freerun_index;
 
        p->timestamp.tv_sec = pts_us64 >> 32;
        p->timestamp.tv_usec = pts_us64 & 0xFFFFFFFF;
        dev->last_pts_us64 = pts_us64;
+       dev->vf->pts_us64 = omx_freerun_index++;
+       vfq_push(&dev->q_omx, dev->vf);
 
        if ((dev->vf->type & VIDTYPE_COMPRESS) != 0) {
                p->timecode.type = dev->vf->compWidth;
@@ -600,11 +635,6 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
        }
        p->sequence = dev->frame_num++;
 
-       vf_notify_receiver(
-                       dev->vf_provider_name,
-                       VFRAME_EVENT_PROVIDER_VFRAME_READY,
-                       NULL);
-
        return ret;
 }
 
index e1ea5c9..ab5c1a2 100644 (file)
@@ -75,10 +75,12 @@ struct vivi_dev {
 
        struct videobuf_res_privdata *res;
        struct vfq_s q_ready;
+       struct vfq_s q_omx;
        u8 first_frame;
        u64 last_pts_us64;
        struct vframe_s *vf;
        struct vframe_s *amlvideo_pool_ready[AMLVIDEO_POOL_SIZE + 1];
+       struct vframe_s *amlvideo_pool_omx[AMLVIDEO_POOL_SIZE + 1];
        int index;
        struct mutex vfpMutex;
        int amlvideo_v4l_num;