Skip duplicated QBUF operation 68/238468/7 accepted/tizen_6.0_unified accepted/tizen_6.0_unified_hotfix tizen_6.0 tizen_6.0_hotfix accepted/tizen/6.0/unified/20201030.123520 accepted/tizen/6.0/unified/hotfix/20201103.053043 accepted/tizen/unified/20200715.115525 submit/tizen/20200715.014600 submit/tizen_6.0/20201029.205101 submit/tizen_6.0_hotfix/20201102.192501 submit/tizen_6.0_hotfix/20201103.114801 tizen_6.0.m2_release
authorJeongmo Yang <jm80.yang@samsung.com>
Tue, 14 Jul 2020 06:55:31 +0000 (15:55 +0900)
committerJeongmo Yang <jm80.yang@samsung.com>
Wed, 15 Jul 2020 01:35:16 +0000 (10:35 +0900)
- If queued buffer is queued again, kernel warning could be occurred when call VIDIOC_DQBUF.

[Version] 1.1.2
[Profile] Common
[Issue Type] Bug fix

Change-Id: I1486968d37189a90859823a99669ed9cea4b6717
Signed-off-by: Jeongmo Yang <jm80.yang@samsung.com>
packaging/nx-video-api.spec
src/Makefile.am
src/nx_video_alloc.c
src/nx_video_alloc.h
src/nx_video_dec.c

index e7a9bb3..8ed295e 100644 (file)
@@ -1,5 +1,5 @@
 Name:    nx-video-api
-Version: 1.1.1
+Version: 1.1.2
 Release: 0
 License: LGPL-2.1+
 Summary: Nexell video APIs
index 11dc398..8c9a948 100644 (file)
@@ -7,7 +7,7 @@ AM_CFLAGS = \
 
 libnx_video_api_la_LTLIBRARIES = libnx_video_api.la
 libnx_video_api_ladir = ${libdir}
-libnx_video_api_la_LDFLAGS = -L${libdir} -ldrm -ltbm $(DLOG_LIBS)
+libnx_video_api_la_LDFLAGS = -L${libdir} -ldrm -ltbm $(DLOG_LIBS) -lpthread
 
 libnx_video_api_la_SOURCES = \
        nx_video_alloc.c        \
index 4379d0c..e8c6fd8 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/videodev2_nxp_media.h>
 #ifdef TIZEN_FEATURE_ARTIK530
 #include <tbm_bufmgr.h>
+#include <xf86drm.h>
 #endif
 #include "nx_video_log.h"
 
@@ -399,9 +400,11 @@ NX_AllocateVideoMemory (void *bufmgr, int width, int height, int32_t planes, uin
       goto alloc_bo_fail;
 #endif
   }
-  pVidMem->surface = tbm_surface_internal_create_with_bos (&info, pVidMem->bo, planes);
+#ifdef TIZEN_FEATURE_ARTIK530
+  pVidMem->surface = tbm_surface_internal_create_with_bos (&info, (tbm_bo *)pVidMem->bo, planes);
   if (!pVidMem->surface)
     goto alloc_bo_fail;
+#endif
 
   return pVidMem;
 
index 3b6a042..4dec7c3 100644 (file)
@@ -56,6 +56,7 @@ extern "C"
 #ifdef TIZEN_FEATURE_ARTIK530
     void *bo[NX_MAX_PLANES];   // tbm bo
     tbm_surface_h surface;
+    int isQueued;
 #endif
   } NX_VID_MEMORY_INFO, *NX_VID_MEMORY_HANDLE;
 
index 9acaebf..7c2fe19 100644 (file)
@@ -29,6 +29,9 @@
 #include <nx_video_alloc.h>
 #include <nx_video_api.h>
 #include "nx_video_log.h"
+#ifdef TIZEN_FEATURE_ARTIK530
+#include <pthread.h>
+#endif
 
 
 /*----------------------------------------------------------------------------*/
@@ -69,6 +72,8 @@ struct NX_V4L2DEC_INFO
 #ifdef TIZEN_FEATURE_ARTIK530
   /* buffer manager */
   void *bufmgr;
+  uint32_t queuedCnt;
+  pthread_mutex_t bufferLock;
 #endif
 };
 
@@ -603,6 +608,9 @@ NX_V4l2DecOpen (uint32_t codecType)
   }
 
   hDec->codecType = codecType;
+#ifdef TIZEN_FEATURE_ARTIK530
+  pthread_mutex_init(&hDec->bufferLock, NULL);
+#endif
 
   return hDec;
 
@@ -653,8 +661,9 @@ NX_V4l2DecClose (NX_V4L2DEC_HANDLE hDec)
     }
   }
 #ifdef TIZEN_FEATURE_ARTIK530
-    if (hDec->bufmgr)
-      tbm_bufmgr_deinit (hDec->bufmgr);
+  pthread_mutex_destroy(&hDec->bufferLock);
+  if (hDec->bufmgr)
+    tbm_bufmgr_deinit (hDec->bufmgr);
 #endif
 
   free (hDec);
@@ -948,6 +957,11 @@ NX_V4l2DecInit (NX_V4L2DEC_HANDLE hDec, NX_V4L2DEC_SEQ_IN * pSeqIn)
         _E ("failed to ioctl: VIDIOC_QBUF(Output YUV - %d)\n", i);
         return -1;
       }
+#ifdef TIZEN_FEATURE_ARTIK530
+      hDec->hImage[i]->isQueued = 1;
+      hDec->queuedCnt++;
+      _D ("INIT QBUF [%2d] %p (%d)", i, hDec->hImage[i], hDec->queuedCnt);
+#endif
     }
 
     type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
@@ -1056,6 +1070,15 @@ NX_V4l2DecDecodeFrame (NX_V4L2DEC_HANDLE hDec, NX_V4L2DEC_IN * pDecIn,
 
   if (pDecOut->dispIdx >= 0) {
     pDecOut->hImg = *hDec->hImage[buf.index];
+#ifdef TIZEN_FEATURE_ARTIK530
+    pthread_mutex_lock(&hDec->bufferLock);
+
+    hDec->hImage[buf.index]->isQueued = 0;
+    hDec->queuedCnt--;
+    /*_D ("DQBUF [%2d] %p (%d)", buf.index,  hDec->hImage[buf.index], hDec->queuedCnt);*/
+
+    pthread_mutex_unlock(&hDec->bufferLock);
+#endif
     pDecOut->timeStamp[DISPLAY_FRAME] =
         ((uint64_t) buf.timestamp.tv_sec) * 1000 + buf.timestamp.tv_usec / 1000;
     pDecOut->outFrmReliable_0_100[DISPLAY_FRAME] = buf.reserved;
@@ -1103,6 +1126,9 @@ NX_V4l2DecClrDspFlag (NX_V4L2DEC_HANDLE hDec, NX_VID_MEMORY_HANDLE hFrameBuf,
 
   if (iFrameIdx >= 0) {
     index = iFrameIdx;
+#ifdef TIZEN_FEATURE_ARTIK530
+    hFrameBuf = hDec->hImage[index];
+#endif
   } else {
     /* Search Buffer Index */
     if (hFrameBuf != NULL) {
@@ -1119,6 +1145,20 @@ NX_V4l2DecClrDspFlag (NX_V4L2DEC_HANDLE hDec, NX_VID_MEMORY_HANDLE hFrameBuf,
     _E ("Fail, Invalid FrameBuffer or FrameIndex.\n");
     return -1;
   }
+#ifdef TIZEN_FEATURE_ARTIK530
+  if (!hFrameBuf) {
+    _E ("No frame buffer for index %d", index);
+    return -1;
+  }
+
+  pthread_mutex_lock(&hDec->bufferLock);
+
+  if (hFrameBuf->isQueued) {
+    _E ("This buffer[%2d] is already queued, skip QBUF", index);
+    pthread_mutex_unlock(&hDec->bufferLock);
+    return -1;
+  }
+#endif
 
   memset (&buf, 0, sizeof (buf));
   buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
@@ -1136,9 +1176,19 @@ NX_V4l2DecClrDspFlag (NX_V4L2DEC_HANDLE hDec, NX_VID_MEMORY_HANDLE hFrameBuf,
   if (ioctl (hDec->fd, VIDIOC_QBUF, &buf) != 0) {
     _E ("Fail, ioctl(): VIDIOC_QBUF.(Clear Display Index, index = %d)\n",
         index);
+#ifdef TIZEN_FEATURE_ARTIK530
+    pthread_mutex_unlock(&hDec->bufferLock);
+#endif
     return -1;
   }
 
+#ifdef TIZEN_FEATURE_ARTIK530
+  hFrameBuf->isQueued = 1;
+  hDec->queuedCnt++;
+  /*_D ("QBUF [%2d] %p (%d)", index,  hFrameBuf, hDec->queuedCnt);*/
+
+  pthread_mutex_unlock(&hDec->bufferLock);
+#endif
   return 0;
 }
 
@@ -1152,31 +1202,45 @@ NX_V4l2DecFlush (NX_V4L2DEC_HANDLE hDec)
     _E ("Fail, Invalid Handle.\n");
     return -1;
   }
-
+#ifdef TIZEN_FEATURE_ARTIK530
+  pthread_mutex_lock(&hDec->bufferLock);
+  hDec->queuedCnt = 0;
+#endif
   type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   if (ioctl (hDec->fd, VIDIOC_STREAMOFF, &type) != 0) {
     _E ("failed to ioctl: VIDIOC_STREAMOFF(Stream)\n");
+#ifdef TIZEN_FEATURE_ARTIK530
+    pthread_mutex_unlock(&hDec->bufferLock);
+#endif
     return -1;
   }
 
   type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   if (ioctl (hDec->fd, VIDIOC_STREAMOFF, &type) != 0) {
     _E ("failed to ioctl: VIDIOC_STREAMOFF(Image)\n");
+#ifdef TIZEN_FEATURE_ARTIK530
+    pthread_mutex_unlock(&hDec->bufferLock);
+#endif
     return -1;
   }
 
   type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   if (ioctl (hDec->fd, VIDIOC_STREAMON, &type) != 0) {
     _E ("Fail, ioctl(): VIDIOC_STREAMON. (Input)\n");
+#ifdef TIZEN_FEATURE_ARTIK530
+    pthread_mutex_unlock(&hDec->bufferLock);
+#endif
     return -1;
   }
 
   type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   if (ioctl (hDec->fd, VIDIOC_STREAMON, &type) != 0) {
     _E ("failed to ioctl: VIDIOC_STREAMON\n");
+#ifdef TIZEN_FEATURE_ARTIK530
+    pthread_mutex_unlock(&hDec->bufferLock);
+#endif
     return -1;
   }
-
   {
     struct v4l2_plane planes[3];
     struct v4l2_buffer buf;
@@ -1198,10 +1262,21 @@ NX_V4l2DecFlush (NX_V4L2DEC_HANDLE hDec)
 
       if (ioctl (hDec->fd, VIDIOC_QBUF, &buf) != 0) {
         _E ("failed to ioctl: VIDIOC_QBUF(Output YUV - %d)\n", i);
+#ifdef TIZEN_FEATURE_ARTIK530
+        pthread_mutex_unlock(&hDec->bufferLock);
+#endif
         return -1;
       }
+#ifdef TIZEN_FEATURE_ARTIK530
+      hDec->hImage[i]->isQueued = 1;
+      hDec->queuedCnt++;
+      _D ("FLUSH QBUF [%2d] %p (%d)", i, hDec->hImage[i], hDec->queuedCnt);
+#endif
     }
   }
+#ifdef TIZEN_FEATURE_ARTIK530
+  pthread_mutex_unlock(&hDec->bufferLock);
+#endif
 
   return 0;
 }