amlogic/vvc1: calculate PTS from DTS for PTS_ON_KEYFRAME
authorRay <1458889+Raybuntu@users.noreply.github.com>
Wed, 6 Mar 2019 08:01:57 +0000 (09:01 +0100)
committerNick Xie <nick@khadas.com>
Fri, 12 Jul 2019 05:36:36 +0000 (13:36 +0800)
drivers/amlogic/media_modules/frame_provider/decoder/vc1/vvc1.c

index 2cae8a0..a488970 100644 (file)
@@ -127,6 +127,7 @@ static u32 stat;
 static u32 buf_size = 32 * 1024 * 1024;
 static u32 buf_offset;
 static u32 avi_flag;
+static u32 keyframe_pts_only;
 static u32 vvc1_ratio;
 static u32 vvc1_format;
 
@@ -137,6 +138,8 @@ static u32 pts_by_offset = 1;
 static u32 total_frame;
 static u32 next_pts;
 static u64 next_pts_us64;
+static u32 next_IP_pts;
+static u64 next_IP_pts_us64;
 static bool is_reset;
 static struct work_struct set_clk_work;
 static struct work_struct error_wd_work;
@@ -277,7 +280,7 @@ static irqreturn_t vvc1_isr(int irq, void *dev_id)
        u32 picture_type;
        u32 buffer_index;
        unsigned int pts, pts_valid = 0, offset = 0;
-       u32 v_width, v_height;
+       u32 v_width, v_height, dur;
        u64 pts_us64 = 0;
 
        reg = READ_VREG(VC1_BUFFEROUT);
@@ -300,6 +303,9 @@ static irqreturn_t vvc1_isr(int irq, void *dev_id)
                        vvc1_amstream_dec_info.height = v_height;
                        frame_height = v_height;
                }
+               repeat_count = READ_VREG(VC1_REPEAT_COUNT);
+               buffer_index = reg & 0x7;
+               picture_type = (reg >> 3) & 7;
 
                if (pts_by_offset) {
                        offset = READ_VREG(VC1_OFFSET_REG);
@@ -307,6 +313,24 @@ static irqreturn_t vvc1_isr(int irq, void *dev_id)
                                        PTS_TYPE_VIDEO,
                                        offset, &pts, 0, &pts_us64) == 0) {
                                pts_valid = 1;
+                               if (keyframe_pts_only) {
+                                       //pr_info("PT:%d rpc:%d pts64:%lld\n", picture_type , repeat_count, pts_us64);
+                                       dur = DUR2PTS(vvc1_amstream_dec_info.rate);
+                                       if (picture_type == B_PICTURE)
+                                       {
+                                               next_IP_pts = pts;
+                                               next_IP_pts_us64 = pts_us64;
+                                               pts -= dur;
+                                               pts_us64 -= (dur * 100) / 9;
+                                       }
+                                       else if (next_IP_pts)
+                                       {
+                                               pts = next_IP_pts;
+                                               next_IP_pts = 0;
+                                               pts_us64 = next_IP_pts_us64;
+                                               next_IP_pts_us64 = 0;
+                                       }
+                               }
 #ifdef DEBUG_PTS
                                pts_hit++;
 #endif
@@ -919,13 +943,16 @@ static void vvc1_local_init(void)
        /* vvc1_ratio = vvc1_amstream_dec_info.ratio; */
        vvc1_ratio = 0x100;
 
-       avi_flag = (unsigned long) vvc1_amstream_dec_info.param;
+       avi_flag = (unsigned long) vvc1_amstream_dec_info.param & 0x1;
+       keyframe_pts_only = (unsigned long)vvc1_amstream_dec_info.param & 0x100;
 
        total_frame = 0;
 
        next_pts = 0;
 
        next_pts_us64 = 0;
+       next_IP_pts = 0;
+       next_IP_pts_us64 = 0;
        saved_resolution = 0;
        frame_width = frame_height = frame_dur = 0;
 #ifdef DEBUG_PTS