vh265: fix h265 playback freeze issue in frame mode with kodi [1/1]
authorHui Zhang <hui.zhang@amlogic.com>
Thu, 3 Dec 2020 08:36:49 +0000 (16:36 +0800)
committerHui Zhang <hui.zhang@amlogic.com>
Thu, 17 Dec 2020 06:51:17 +0000 (22:51 -0800)
PD#SWPL-37390

Problem:
with Kodi, this stream will send I frame with eos nal in head of
chunk. decode  will idscard all frame data once meet eos nal.
it will cause I frame missed

Solution:
in frame mode, decoder will check shiftbytes and  decode size when
eos nal meet. if eos nal in the beginning of the chunks. don't skip
the left data, go on decoding

Verify:
AC214

Signed-off-by: Hui Zhang <hui.zhang@amlogic.com>
Change-Id: I7900df3cfaa70811c5d9d52df0c68fa6616f36d4

drivers/frame_provider/decoder/h265/vh265.c

index feffe991fe460232b5c9263a4d8fcbf0e48a7eef..bb5870f028cbe00a66102aea0d498e8b813395d0 100644 (file)
@@ -10770,6 +10770,7 @@ force_output:
                }
                if (naltype == NAL_UNIT_EOS) {
                        struct PIC_s *pic;
+                       bool eos_in_head = false;
 
                        hevc_print(hevc, 0, "get NAL_UNIT_EOS, flush output\n");
 #ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
@@ -10780,7 +10781,7 @@ force_output:
 #endif
                        /*Detects frame whether has an over decode error*/
                        if ((!vdec_dual(vdec)) &&
-                                       hevc->empty_flag == 0) {
+                                       hevc->empty_flag == 0 && input_stream_based(vdec)) {
                                        hevc->over_decode =
                                                (READ_VREG(HEVC_SHIFT_STATUS) >> 15) & 0x1;
                                        if (hevc->over_decode)
@@ -10795,9 +10796,23 @@ force_output:
                        hevc->m_pocRandomAccess = MAX_INT;
                        flush_output(hevc, pic);
                        clear_poc_flag(hevc);
+                       if (input_frame_based(vdec)) {
+                               u32 shiftbyte = READ_VREG(HEVC_SHIFT_BYTE_COUNT);
+                               if (shiftbyte < 0x8 && (hevc->decode_size - shiftbyte) > 0x100) {
+                                       hevc_print(hevc, 0," shiftbytes 0x%x  decode_size 0x%x\n", shiftbyte, hevc->decode_size);
+                                       eos_in_head = true;
+                               }
+                       }
                        WRITE_VREG(HEVC_DEC_STATUS_REG, HEVC_DISCARD_NAL);
                        /* Interrupt Amrisc to excute */
                        WRITE_VREG(HEVC_MCPU_INTR_REQ, AMRISC_MAIN_REQ);
+
+                       /* eos is in the head of the chunk and followed by sps/pps/IDR
+                         * so need to go on decoding
+                         */
+                       if (eos_in_head)
+                               return IRQ_HANDLED;
+
 #ifdef MULTI_INSTANCE_SUPPORT
                        if (hevc->m_ins_flag) {
                                hevc->decoded_poc = INVALID_POC; /*