CR: Add black frame detection in thumbnail, so we can get valid frame(non-blank) form the video stream as the thumbnail.

"Chen, Weian" <[email protected]>
Newsgroups gmane.comp.multimedia.helix.devel
Message-ID <CE50BAB9F318CF49AA37C2AE5CAC06EC2F263C@pdsmsx412.ccr.corp.intel.com>
Synopsis: 

  Add black frame detection support in thumbnail, so we can get valid
frame (non-blank) form the video stream as the thumbnail.

 

Overview: 

   Currently, we always get first key frame of a stream as the
thumbnail, and many of these frames are black, so we can't get the
needed information. Then we add black frame detection, until we get a
valid frame then stop doing thumbnail.

 

Files Added:

  None

 

Files Modified:

  player/hxclientkit/pub/HXClientCallbacks.h

  player/hxclientkit/src/platform/unix/CHXClientThumbnailUnix.cpp

  player/kit/dbus-server/pub/hxplayer.h

  player/kit/dbus-server/src/hxplayer.cpp

  player/kit/dbus-server/src/helix-dbus-server.cpp

 

Image Size and Heap Use impact (Client -Only):

  Little

 

Platforms and Profiles Affected:

  platform:   linux-2.2-libc6-gcc32-i586

  profile:      helix-client-all-defines

 

Distribution Libraries Affected:

  <libhxclient.a> <helix-dbus-server.bin>

 

Distribution library impact and planned action:

  <None>

 

Platforms and Profiles Build Verified:

  Set BIF branch  -> hxdbus_3_1_0_atlas

  Set Target(s)     -> dbus_server_with_video

  Set Profile        -> helix-client-all-defines

  System ID        -> linux-2.2-libc6-gcc32-i586

 

Branch: 

  HEAD, hxclient_3_1_0_atlas

 

Copyright assignment: <MUST be one of the following statements >

2.      Intel has signed and delivered a Joint Copyright Assignment

           to RealNetworks, and received acknowledgment that the 

           agreement was received.  

 

Files Attached:

  hxclient-nonblank-thumbnail.diff

  dbus-nonblank-thumb.diff

 

Weian

_______________________________________________
Helix-client-dev mailing list
[email protected]
http://lists.helixcommunity.org/mailman/listinfo/helix-client-dev
dbus-nonblank-thumb.diff (application/octet-stream, 6.9 KB)
? dbus-nonblank-thumb.diff
Index: dbus-server/pub/hxplayer.h
===================================================================
RCS file: /cvsroot/player/kit/dbus-server/pub/hxplayer.h,v
retrieving revision 1.2.2.16
diff -u -w -r1.2.2.16 hxplayer.h
--- dbus-server/pub/hxplayer.h	27 Jun 2008 01:51:50 -0000	1.2.2.16
+++ dbus-server/pub/hxplayer.h	17 Jul 2008 08:27:03 -0000
@@ -35,6 +35,7 @@
 // higher level application call Pump() (defined in helix-dbus-server.cpp) can do this .
 // we use the following MACRO to disable interl pump() thread.
 #define _ENABLE_INTERNAL_PUMP 0
+#define BLACK_THUMBNAIL_THRD 25
 typedef struct HxPlayer HxPlayer;
 typedef struct TnPlayer TnPlayer;
 
@@ -97,5 +98,6 @@
 					int width,
 					int height);   
     static int ConvertRGB24ToPNG(const guchar* data, int width, int height, const char* filename);
+    bool IsBlackFrame (unsigned char *src, HXThumbnailPicInfo * pThumbPicInfo);
 };
 #endif /* _HXPLAYER_H */
Index: dbus-server/src/helix-dbus-server.cpp
===================================================================
RCS file: /cvsroot/player/kit/dbus-server/src/helix-dbus-server.cpp,v
retrieving revision 1.2.2.32
diff -u -w -r1.2.2.32 helix-dbus-server.cpp
--- dbus-server/src/helix-dbus-server.cpp	27 Jun 2008 01:51:50 -0000	1.2.2.32
+++ dbus-server/src/helix-dbus-server.cpp	17 Jul 2008 08:27:03 -0000
@@ -56,6 +56,8 @@
 
 #define START_TIME 0
 #define PROCESS_TIME_UNIT 100 
+#define THUMBNAIL_REPEAT_TIME 5
+#define SECTION_NUMBER 10
 
 struct HelixDbusServer {
     DBusConnection *connection;
@@ -1336,6 +1338,8 @@
     long int startTime = START_TIME;
     long int processTimeUnit = PROCESS_TIME_UNIT;
     int size = 0;
+    int nRepeatTime = 0;
+    int preStartTime = 0;
 
     memset (pThumbPicInfo, 0, sizeof (HXThumbnailPicInfo));
 
@@ -1346,6 +1350,10 @@
         return;
     }
 
+    bool bBlackFrame = true;
+    while (bBlackFrame)
+    {
+        HX_VECTOR_DELETE (pBuf);
     retcode = CreateThumbnailFromPlugin (uri, &pBuf, &pThumbPicInfo, startTime, processTimeUnit);
     if(!retcode)
     {
@@ -1354,6 +1362,25 @@
         return;
     }
    
+        nRepeatTime ++;
+        startTime = (nRepeatTime * pThumbPicInfo->duration) / SECTION_NUMBER;
+     
+
+        if (nRepeatTime > THUMBNAIL_REPEAT_TIME)
+            break;
+
+        if (pBuf && pThumbPicInfo)
+        {
+             bBlackFrame = rgbColourConvert.IsBlackFrame (pBuf, pThumbPicInfo);
+        }
+        else 
+        {
+            HX_DELETE (pThumbPicInfo);
+            HX_VECTOR_DELETE (pBuf);
+            return;
+        }
+    }  
+
     if (pBuf)
     {
     	char * pRgb = new char [pThumbPicInfo->width * pThumbPicInfo->height * 3];
Index: dbus-server/src/hxplayer.cpp
===================================================================
RCS file: /cvsroot/player/kit/dbus-server/src/hxplayer.cpp,v
retrieving revision 1.2.2.31
diff -u -w -r1.2.2.31 hxplayer.cpp
--- dbus-server/src/hxplayer.cpp	27 Jun 2008 01:51:50 -0000	1.2.2.31
+++ dbus-server/src/hxplayer.cpp	17 Jul 2008 08:27:03 -0000
@@ -1639,6 +1639,118 @@
     return true;
 }
 
+bool CColourConvert::IsBlackFrame (unsigned char *src, HXThumbnailPicInfo * pThumbPicInfo)
+{
+    int width = pThumbPicInfo->width;
+    int height = pThumbPicInfo->height;
+
+    if (!strcmp ("video/X-HX-I420", pThumbPicInfo->mimeType))
+    {
+        unsigned int SAD = 0;
+        unsigned int pixNumber = width * height;
+        // we only select the middle two lines and columns to detect
+        // and for I420, we will only detect Y component 
+    	for (int i = 0; i < width; i++)
+    	{
+        	SAD += src [(pixNumber >> 1) + i];
+    	}
+    	for (int i = 0; i < width; i++)
+    	{
+        	SAD += src [(pixNumber >> 1) + width + i];
+    	}
+    	
+    	int index = width >> 1;
+    	for (int j = 0; j < height; j++)
+    	{
+        	SAD += src [index];
+        	SAD += src [index + 1];
+        	index += width;
+    	}
+
+    	if (SAD <  (width * 2 + height * 2 -4) * BLACK_THUMBNAIL_THRD)
+        	return true;
+    	else 
+        	return false;   	
+    }
+    else if (!strcmp ("video/X-HX-RGB", pThumbPicInfo->mimeType))
+    {
+        unsigned int rSAD = 0;
+        unsigned int gSAD = 0;
+        unsigned int bSAD = 0;
+
+        if (pThumbPicInfo->bitsPerPixel == 32)
+        {
+            unsigned int rgbPixNumber = height * width * 4;
+
+            for (int i = 0; i < width; i++)
+            {
+                rSAD += src [(rgbPixNumber >> 1) + (i << 2)];
+                gSAD += src [(rgbPixNumber >> 1) + (i << 2) + 1];
+                bSAD += src [(rgbPixNumber >> 1) + (i << 2) + 2];
+            }
+            for (int i = 0; i < width; i++)
+            {
+                rSAD += src [(rgbPixNumber >> 1) + ((width + i) << 2)];
+                gSAD += src [(rgbPixNumber >> 1) + ((width + i) << 2) + 1];
+                bSAD += src [(rgbPixNumber >> 1) + ((width + i) << 2) + 2];
+            }
+            int index = width << 1;
+            for (int j = 0; j < height; j++)
+            {
+                rSAD += src [index];
+                gSAD += src [index + 1];
+                bSAD += src [index + 2];
+                rSAD += src [index + 4];
+                gSAD += src [index + 5];
+                bSAD += src [index + 6];
+                index += (width << 2);
+            }
+
+            if ((rSAD  + gSAD + bSAD) <  (width * 2 + height * 2 -4) * BLACK_THUMBNAIL_THRD * 3)
+                return true;
+            else 
+                return false;   
+        }
+
+        if (pThumbPicInfo->bitsPerPixel == 24)
+        {
+            unsigned int rgbPixNumber = height * width * 3;
+            for (int i = 0; i < width; i++)
+            {
+                rSAD += src [(rgbPixNumber >> 1) + i * 3];
+                gSAD += src [(rgbPixNumber >> 1) + i * 3 + 1];
+                bSAD += src [(rgbPixNumber >> 1) + i * 3 + 2];
+            }
+            for (int i = 0; i < width; i++)
+            {
+                rSAD += src [(rgbPixNumber >> 1) + (width + i) * 3];
+                gSAD += src [(rgbPixNumber >> 1) + (width + i) * 3 + 1];
+                bSAD += src [(rgbPixNumber >> 1) + (width + i) * 3 + 2];
+            }
+            int index = (width * 3) >> 1;
+            for (int j = 0; j < height; j++)
+            {
+                rSAD += src [index];
+                gSAD += src [index + 1];
+                bSAD += src [index + 2];
+                rSAD += src [index + 3];
+                gSAD += src [index + 4];
+                bSAD += src [index + 5];
+                index += (width * 3);
+            }
+
+           if ((rSAD  + gSAD + bSAD) <  (width * 2 + height * 2 -4) * BLACK_THUMBNAIL_THRD * 3)
+                return true;
+           else 
+                return false;   
+        }
+        else 
+            return false;
+    }
+    else 
+        return false;
+}
+
 static int CColourConvert::ConvertRGB24ToPNG(const guchar* data, int width, int height, const char* filename)
 {
     //I'm using hardcode because i know the format of the data
hxclient-nonblank-thumbnail.diff (application/octet-stream, 1.3 KB)
Index: pub/HXClientCallbacks.h
===================================================================
RCS file: /cvsroot/player/hxclientkit/pub/HXClientCallbacks.h,v
retrieving revision 1.20.2.3
diff -u -w -r1.20.2.3 HXClientCallbacks.h
--- pub/HXClientCallbacks.h	27 Jun 2008 01:50:47 -0000	1.20.2.3
+++ pub/HXClientCallbacks.h	17 Jul 2008 08:06:41 -0000
@@ -148,6 +148,7 @@
 	UInt32 dataLen;
 	UInt32 bitsPerPixel;
         char    mimeType[MAX_LEN];
+    UInt32 duration;
 }
 HXThumbnailPicInfo;
 
Index: src/platform/unix/CHXClientThumbnailUnix.cpp
===================================================================
RCS file: /cvsroot/player/hxclientkit/src/platform/unix/CHXClientThumbnailUnix.cpp,v
retrieving revision 1.1.2.9
diff -u -w -r1.1.2.9 CHXClientThumbnailUnix.cpp
--- src/platform/unix/CHXClientThumbnailUnix.cpp	27 Jun 2008 01:50:48 -0000	1.1.2.9
+++ src/platform/unix/CHXClientThumbnailUnix.cpp	17 Jul 2008 08:06:42 -0000
@@ -863,6 +863,7 @@
     UINT32 width  = 0;
     UINT32 height = 0;
     UINT32 bitsPerPixel = 0;
+    UINT32 duration = 0;
 
     pValues->GetPropertyULONG32("Width", width);
     if (width)
@@ -882,6 +883,12 @@
         thumbPicInfo.bitsPerPixel = bitsPerPixel;
     }
 
+    pValues->GetPropertyULONG32("Duration", duration);
+    if (duration)
+    {
+        thumbPicInfo.duration = duration;
+    }
+
     return HXR_OK;
 }
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.