v4l2dec: refine dw=0 [1/1]

PD#SWPL-166086

Problem:
when dw=0, some check failed

Solution:
1、set dw in advance
2、set width = height = 64 when dw=0.

Verify:
ap222

Change-Id: I127e340b695517ab34cd959053e887f423dad6a0
Signed-off-by: hanghang.luo <hanghang.luo@amlogic.com>
diff --git a/src/gstamlv4l2object.c b/src/gstamlv4l2object.c
index 9b5a6b8..cc73fa4 100644
--- a/src/gstamlv4l2object.c
+++ b/src/gstamlv4l2object.c
@@ -41,7 +41,7 @@
 
 #include <gst/video/video.h>
 #include <gst/allocators/gstdmabuf.h>
-#include "gstamlv4l2videodec.h"
+
 
 GST_DEBUG_CATEGORY_EXTERN(aml_v4l2_debug);
 #define GST_CAT_DEFAULT aml_v4l2_debug
@@ -3634,9 +3634,24 @@
     gboolean use_ext_config = FALSE;
     int major = 0,minor = 0;
     struct utsname info;
+    gboolean is_interlaced;
+    guint width, height;
     if (getenv("V4L2DEC_LOW_MEM_MODE"))
         v4l2object->low_memory_mode = TRUE;
     GST_DEBUG("low mem: %d",v4l2object->low_memory_mode);
+    GstStructure *structure = gst_caps_get_structure(caps, 0);
+    if (structure == NULL)
+    {
+        return;
+    }
+    gst_structure_get_uint(structure,"width",&width);
+    gst_structure_get_uint(structure,"height",&height);
+    if (gst_structure_has_field(structure, "interlace-mode"))
+    {
+        char *mode= gst_structure_get_string(structure,"interlace-mode");
+        is_interlaced= !strcmp(mode, "progressive") ? FALSE:TRUE;
+        GST_DEBUG("is_interlaced: %d",is_interlaced);
+    }
 
     if (v4l2object->type == V4L2_BUF_TYPE_VIDEO_OUTPUT || v4l2object->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
     {
@@ -3659,23 +3674,37 @@
            decParm->cfg.metadata_config_flag |= (1 << 15);
         }
 
-        //need to config dw mode in output,
-        //although its value will be replaced by capture,
-        //please don't delete this logic.
         switch (pixFormat)
         {
+
             case V4L2_PIX_FMT_MPEG:
-            case V4L2_PIX_FMT_H264:
                 decParm->cfg.double_write_mode= VDEC_DW_NO_AFBC;
+            case V4L2_PIX_FMT_H264:
+            {
+                if (width > 1920 && height > 1080 && is_interlaced)
+                    decParm->cfg.double_write_mode= VDEC_DW_AFBC_1_4_DW;
+                else
+                    decParm->cfg.double_write_mode= VDEC_DW_NO_AFBC;
                 break;
+            }
             case V4L2_PIX_FMT_HEVC:
+                decParm->cfg.double_write_mode= VDEC_DW_AFBC_AUTO_1_4;
+                if (is_interlaced)
+                    decParm->cfg.double_write_mode= VDEC_DW_AFBC_1_1_DW;
+                if (v4l2object->low_memory_mode)
+                    decParm->cfg.double_write_mode= VDEC_DW_AFBC_ONLY;
+                break;
             case V4L2_PIX_FMT_VP9:
             case V4L2_PIX_FMT_AV1:
-                decParm->cfg.double_write_mode= VDEC_DW_AFBC_AUTO_1_4;
+                decParm->cfg.double_write_mode= v4l2object->low_memory_mode ? VDEC_DW_AFBC_ONLY:VDEC_DW_AFBC_AUTO_1_4;
                 break;
             default:
                 break;
         }
+        env = getenv("V4L2_SET_AMLOGIC_DW_MODE");
+        if (env)
+            decParm->cfg.double_write_mode = atoi(env);
+
         GST_DEBUG_OBJECT(v4l2object->dbg_obj, "output cfg dw mode to %d", decParm->cfg.double_write_mode);
 
         decParm->cfg.ref_buf_margin = GST_AML_V4L2_DEFAULT_CAP_BUF_MARGIN;
@@ -3686,12 +3715,6 @@
             GST_DEBUG_OBJECT(v4l2object->dbg_obj, "cfg margin to %d", decParm->cfg.ref_buf_margin);
         }
 
-        GstStructure *structure= gst_caps_get_structure(caps, 0);
-        if (structure == NULL)
-        {
-            return;
-        }
-
         // dv
         gboolean dv_bl_present_flag, dv_el_present_flag;
         int dvBaseLayerPresent = -1;
@@ -3986,24 +4009,11 @@
     {
         struct aml_dec_params vdecParm;
         GstAmlV4l2VideoDec *self = (GstAmlV4l2VideoDec*) v4l2object->element;
-        gboolean is_interlaced;
-        guint width, height;
         if (!get_amlogic_vdec_parm(v4l2object,&vdecParm))
         {
             GST_ERROR_OBJECT(v4l2object->dbg_obj, "can't get vdec parm");
             return;
         }
-        GstStructure *structure = gst_caps_get_structure(caps, 0);
-        if (structure == NULL)
-        {
-            return;
-        }
-        if (gst_structure_has_field(structure, "interlace-mode"))
-        {
-            char *mode= gst_structure_get_string(structure,"interlace-mode");
-            is_interlaced= !strcmp(mode, "progressive") ? FALSE:TRUE;
-            GST_DEBUG("is_interlaced: %d",is_interlaced);
-        }
 
         switch (self->v4l2output->fmtdesc->pixelformat)
         {
@@ -4012,8 +4022,6 @@
                 vdecParm.cfg.double_write_mode= VDEC_DW_NO_AFBC;
             case V4L2_PIX_FMT_H264:
             {
-                gst_structure_get_uint(structure,"width",&width);
-                gst_structure_get_uint(structure,"height",&height);
                 if (width > 1920 && height > 1080 && is_interlaced)
                     vdecParm.cfg.double_write_mode= VDEC_DW_AFBC_1_4_DW;
                 else
@@ -5037,6 +5045,8 @@
             width = (width/2) *2; /* align for dw*/
             height = (height/2) *2; /* align for dw*/
         }
+        if (dw_mode == VDEC_DW_AFBC_ONLY)
+            height = width = 64;
     }
     GST_DEBUG_OBJECT(v4l2object->dbg_obj, "final w:%d, h:%d", width, height);
 
diff --git a/src/gstamlv4l2videodec.c b/src/gstamlv4l2videodec.c
index cb7697f..b47704e 100644
--- a/src/gstamlv4l2videodec.c
+++ b/src/gstamlv4l2videodec.c
@@ -517,6 +517,7 @@
     caps = gst_caps_copy(self->probed_srccaps);
     gst_caps_set_features_simple(caps, gst_caps_features_from_string(GST_CAPS_FEATURE_MEMORY_DMABUF));
     gst_caps_append(self->probed_srccaps, caps);
+
     if (ret)
         self->input_state = gst_video_codec_state_ref(state);
     else
@@ -925,6 +926,7 @@
     GstStructure *s;
     gint width = 0;
     gint height = 0;
+    GST_DEBUG("%d   %d",info.width, info.height);
     output_state = gst_video_decoder_set_output_state(decoder,
                    info.finfo->format, info.width, info.height, self->input_state);
     memset(&sel, 0, sizeof(struct v4l2_selection));
@@ -947,10 +949,10 @@
         s = gst_caps_get_structure(output_state->caps, 0);
         if (s)
         {
-            gst_structure_set(s,"coded_width",G_TYPE_INT,info.width,NULL);
-            gst_structure_set(s,"coded_height",G_TYPE_INT,info.height,NULL);
-            gst_structure_set(s,"width",G_TYPE_INT,width,NULL);
-            gst_structure_set(s,"height",G_TYPE_INT,height,NULL);
+            gst_structure_set(s,"src_width",G_TYPE_INT,width,NULL);
+            gst_structure_set(s,"src_height",G_TYPE_INT,height,NULL);
+            gst_structure_set(s,"width",G_TYPE_INT,info.width,NULL);
+            gst_structure_set(s,"height",G_TYPE_INT,info.height,NULL);
             GST_DEBUG_OBJECT(self, "output_state->caps: %" GST_PTR_FORMAT, output_state->caps);
             gst_video_codec_state_unref(output_state);
         }