{"id":759,"date":"2011-10-28T17:14:39","date_gmt":"2011-10-28T11:44:39","guid":{"rendered":"http:\/\/www.e-consystems.com\/blog\/windowsce\/?p=759"},"modified":"2023-08-15T12:31:28","modified_gmt":"2023-08-15T07:01:28","slug":"exploring-vmr-features-windows-embedded-compact-7","status":"publish","type":"post","link":"https:\/\/www.e-consystems.com\/blog\/windowsce\/exploring-vmr-features-windows-embedded-compact-7\/","title":{"rendered":"Exploring VMR Features on Windows CE 7.0"},"content":{"rendered":"<p>As you may know that Windows Embedded Compact 7 has new component for DirectShow video rendering(Video Mixing Render) which is more advanced than the old video render used in Windows Embedded CE 6.0.However the VMR has been available  in PC side DirectX for a long time.<\/p>\n<p>I am planning to explore few features of VMR on WEC7starting with bitmap mixing. Mixing the bitmap is not a cakewalk in Windows Embedded CE 6.0.We have to develop a transform filter to perform this, again the performance is not assured. But in WEC7 VMR facilitates the bitmap mixing easily by writing few lines of code.<\/p>\n<p>This blog is the continuation of \u201c<a href=\"https:\/\/www.e-consystems.com\/blog\/windowsce\/building-simple-camera-directshow-filter-graph-application-wec7\/\">Building a Simple Camera DirectShow Filter graph Application in WEC7<\/a>\u201d written by Prabu Kumar. He has already explained \u2013 How to include VMR on Filter graph with a simple application. I am exploring the VMR feature with the same sample application by including my source codeon it. So that it can be easy to follow. Also you can click here to download the <a href=\"https:\/\/vmrwec7.codeplex.com\/downloads\/get\/297231\">Sample application code<\/a>. This application is developed in VS2008 using the OMAP EVM SDK and tested in OMAP EVM.<\/p>\n<p>&nbsp;<\/p>\n<h2>Exploring Bitmap Mixing<\/h2>\n<p>VMR expose bitmap mixing through IVMRMixerBitmap interface and it is having few methods which help us to implement bitmap mixing in a simple and straight forward method. I have explained the bitmap mixing by alpha blending a bitmap and also create strobe effect on bitmap with the preview streaming from the camera.<\/p>\n<p>Now I am explaining you on how to blend a bitmap image with the below given source code snippets. As I already told, I am continuing with sample application given by Prabu Kumar. So add the following code between step 3 and 4 of the above given blog.<\/p>\n<table border=\"1\" cellspacing=\"0\" cellpadding=\"0\" width=\"630\">\n<tbody>\n<tr>\n<td width=\"630\" valign=\"top\">\n<ul> <em><br \/>\n\/\/Get the interface for configuring the VMR<br \/>\nCHK(pVideoRenderer.QueryInterface(&amp;pVMRConfig ));<\/em><\/ul>\n<ul><em><br \/>\n\/\/Set VMR to Windowed Mode<br \/>\nCHK(pVMRConfig-&gt;SetRenderingMode( VMRMode_Windowed));<\/em><\/ul>\n<ul><em><br \/>\n\/\/Set the input stream for VMR as 2 to perform bitmap Mixing<br \/>\nCHK(pVMRConfig-&gt;SetNumberOfStreams(2));<\/em><\/ul>\n<ul><em><br \/>\n\/\/Retrieve the Bitmap mixer interface<br \/>\nCHK(pVideoRenderer.QueryInterface(&amp;pVMRMixerBitmap) );<\/em><\/ul>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>We need two streams to perform bitmap mixing. One is the main video stream and another stream is bitmap. . Using IVMRFilterConfig ::SetNumberOfStreams() set the number of stream required as 2. Add the following code after  step5.<\/p>\n<table border=\"1\" cellspacing=\"0\" cellpadding=\"0\" width=\"630\">\n<tbody>\n<tr>\n<td width=\"630\" valign=\"top\">\n<ul><em><br \/>\nCHK(BlendBitMap( m_hwnd));<\/em><\/ul>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Also see the below given definition of the function BlendBitMap().I have explained below about the steps involved in loading and mixing the bitmap image with the live camera preview.<\/p>\n<p>&nbsp;<\/p>\n<p>1)\tLoad the bitmap and map with the windows compactible DC. This DC will be used as parameter for VMR bitmap mixer API as shown in the step 2.Following code snippet will perform this.<\/p>\n<table border=\"1\" cellspacing=\"0\" cellpadding=\"0\" width=\"630\">\n<tbody>\n<tr>\n<td width=\"630\" valign=\"top\">\n<ul><em><br \/>\nHRESULT BlendBitMap(HWND hwndApp)<br \/>\n{<br \/>\nLONG cx=480, cy=480;<br \/>\nHRESULT hr;<br \/>\nRECT rc={0};<br \/>\n\/\/ Load the multi-image bitmap to alpha blend from the resource file<br \/>\nHBITMAP hbm = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_BITMAP1));<br \/>\nBITMAP bm;<br \/>\nHBITMAP hbmOld;<br \/>\nHDC hdc = GetDC(hwndApp);<br \/>\nHDC hdcBmp = CreateCompatibleDC(hdc);<br \/>\nReleaseDC(hwndApp, hdc);<br \/>\nGetObject(hbm, sizeof(bm), &amp;bm);<br \/>\nhbmOld = (HBITMAP)SelectObject(hdcBmp, hbm);<\/em><\/ul>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>&nbsp;<\/p>\n<p>2)\tMap the DC to VMR bitmap mixer, Configure the source and destination rectangle. Source reactance used to define the area where you are going to draw from bitmap image and destination rectangle used to define the area where you are going to draw on the live video stream.Following code snippet will do this.<\/p>\n<table border=\"1\" cellspacing=\"0\" cellpadding=\"0\" width=\"630\">\n<tbody>\n<tr>\n<td width=\"630\" valign=\"top\">\n<ul><em><br \/>\n\/\/ Configure the VMR&#8217;s bitmap structure<br \/>\nVMRALPHABITMAP bmpInfo;<br \/>\nZeroMemory(&amp;bmpInfo, sizeof(bmpInfo) );<br \/>\nbmpInfo.dwFlags = VMRBITMAP_HDC;<br \/>\nbmpInfo.hdc = hdcBmp;<br \/>\n\/\/ Display the bitmap in the bottom right corner. rSrc specifies the source rectangle in the GDI \/\/device context.<br \/>\nSetRect(&amp;rc, 0, 0,  bm.bmWidth, bm.bmHeight);<br \/>\nbmpInfo.rSrc = rc;<br \/>\n\/\/ rDest specifies the destination rectangle in composition space (0.0f to 1.0f)<br \/>\nbmpInfo.rDest.left   = (float)(cx &#8211; bm.bmWidth) \/ (float)cx &#8211; EDGE_BUFFER;<br \/>\nbmpInfo.rDest.top    = (float)(cy &#8211; bm.bmHeight)   \/ (float)cy &#8211; EDGE_BUFFER;<br \/>\nbmpInfo.rDest.right  = 1.0f &#8211; EDGE_BUFFER;<br \/>\nbmpInfo.rDest.bottom = 1.0f &#8211; EDGE_BUFFER;<\/em><\/ul>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>&nbsp;<\/p>\n<p>3)\tSet the alpha value based on your requirement and set the VMR configuration structure  using<br \/>\nIVMRMixerBitmap ::SetAlphaBitmap. In my case, I use the alpha value as 0.0 to hide the bitmap at the beginning.<\/p>\n<table border=\"1\" cellspacing=\"0\" cellpadding=\"0\" width=\"630\">\n<tbody>\n<tr>\n<td width=\"630\" valign=\"top\">\n<ul><em><br \/>\n\/\/ Transparency value 1.0 is opaque, 0.0 is transparent. For initially setting the bitmap, we&#8217;ll make \/\/ it transparent<br \/>\nbmpInfo.fAlpha = 0.0;<br \/>\n\/\/ Set the COLORREF so that the bitmap outline will be transparent<br \/>\nSetColorRef(bmpInfo);<br \/>\n\/\/ Give the bitmap to the VMR.  Since the alpha value is 0, nothing willbe displayed yet on the \/\/screen, but the VMR will have the information that it needs to allow us to modify the bitmap.<br \/>\nhr = pVMRMixerBitmap-&gt;SetAlphaBitmap(&amp;bmpInfo);<br \/>\nif (FAILED(hr))<br \/>\nRETAILMSG(1,(TEXT(&#8220;SetAlphaBitmap FAILED!  Bitmap operations will fail. hr=0x%x\\r\\n&#8221;), hr));<br \/>\n\/\/ Clean up GDI resources<br \/>\nDeleteObject(SelectObject(hdcBmp, hbmOld));<br \/>\nDeleteObject(hbm);<br \/>\nDeleteDC(hdcBmp);<br \/>\nreturnhr;<br \/>\n}<\/em><\/ul>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>&nbsp;<\/p>\n<h2>Creating Strobe effect with bitmap mixer<\/h2>\n<p>I have explained the usage of IVMRMixerBitmap ::GetAlphaBitmapParameters and IVMRMixerBitmap::UpdateAlphaBitmapParameters functions by creating the strobe effect. Strobe effects can be created by changing the alpha value with the minimum delta value range between 0.0 to 1.0.<\/p>\n<p><strong>Following steps explain you to create the strobe effect<\/strong><\/p>\n<p>1)\tCreate a function called StrobeEffect. Using <strong>GetAlphaBitmapParameters<\/strong>, we can get the current alpha value, apply the delta and update the new value using <strong>UpdateAlphaBitmapParameters<\/strong>. Following code snippet shows the usage.<\/p>\n<table border=\"1\" cellspacing=\"0\" cellpadding=\"0\" width=\"630\">\n<tbody>\n<tr>\n<td width=\"630\" valign=\"top\">\n<ul><em><br \/>\nconst float STROBE_VALUE = 0.125f;<br \/>\nvoidStrobeEffect(void)<br \/>\n{<br \/>\nHRESULT hr;<br \/>\nVMRALPHABITMAP bmpInfo={0};<br \/>\nstaticint Increase=1;<br \/>\nfloatfAlpha=0.0f;<br \/>\nhr = pVMRMixerBitmap-&gt;GetAlphaBitmapParameters(&amp;bmpInfo);<br \/>\n\/\/ Slowly increase the alpha value<br \/>\nif(bmpInfo.fAlpha&gt;=1.0f)<br \/>\nIncrease=0;<br \/>\nelse if(bmpInfo.fAlpha&lt;=0.0f) \t\tIncrease=1; \tif(Increase) \t\tfAlpha= bmpInfo.fAlpha + STROBE_VALUE; \telse fAlpha = bmpInfo.fAlpha &#8211; STROBE_VALUE; bmpInfo.fAlpha = fAlpha;     \/\/ Set the COLORREF so that the bitmap outline will be transparent SetColorRef(bmpInfo);<br \/>\n\/\/ If the bitmap is currently disabled, this call will fail hr = pVMRMixerBitmap-&gt;UpdateAlphaBitmapParameters(&amp;bmpInfo);<br \/>\n}<br \/>\n<\/em><\/ul>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>&nbsp;<\/p>\n<p>2)\tCreate a TimerProc and and call the StrobeEffect function in a required period.<\/p>\n<table border=\"1\" cellspacing=\"0\" cellpadding=\"0\" width=\"630\">\n<tbody>\n<tr>\n<td width=\"630\" valign=\"top\">\n<ul><em><br \/>\nVOID CALLBACK TimerProc(<br \/>\nHWND hwnd,         \/\/ handle to window<br \/>\nUINT uMsg,         \/\/ WM_TIMER message<br \/>\nUINT_PTR idEvent,  \/\/ timer identifier<br \/>\nDWORD dwTime       \/\/ current system time<br \/>\n)<br \/>\n{<br \/>\nStrobeEffect();<br \/>\n}<\/em><\/ul>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>&nbsp;<\/p>\n<p>3)\tYou can start and stop the Strobe effect by using SetTimer and KillTimer APIs.  The functions StartTimer and StopTimer are invoked from the Menu item.<\/p>\n<table border=\"1\" cellspacing=\"0\" cellpadding=\"0\" width=\"630\">\n<tbody>\n<tr>\n<td width=\"630\" valign=\"top\">\n<ul><em><br \/>\nvoidStartTimer(void)<br \/>\n{<br \/>\nif (!gnTimer)<br \/>\ngnTimer = (int) SetTimer(NULL, MAIN_TIMER, MAIN_TIMEOUT, TimerProc);<br \/>\n}<br \/>\nvoidStopTimer(void)<br \/>\n{<br \/>\nif (gnTimer)<br \/>\n{<br \/>\nKillTimer(NULL, gnTimer);<br \/>\ngnTimer = 0;<br \/>\n}<br \/>\n}<\/em><\/ul>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>&nbsp;<\/p>\n<p>Hope this blog provides some pointers on VMR Bitmap Mixer on Windows Embedded Compact 7.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>As you may know that Windows Embedded Compact 7 has new component for DirectShow video&#8230;<\/p>\n","protected":false},"author":12,"featured_media":1396,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[192],"tags":[111,114,115,113,93],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.e-consystems.com\/blog\/windowsce\/wp-json\/wp\/v2\/posts\/759"}],"collection":[{"href":"https:\/\/www.e-consystems.com\/blog\/windowsce\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.e-consystems.com\/blog\/windowsce\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.e-consystems.com\/blog\/windowsce\/wp-json\/wp\/v2\/users\/12"}],"replies":[{"embeddable":true,"href":"https:\/\/www.e-consystems.com\/blog\/windowsce\/wp-json\/wp\/v2\/comments?post=759"}],"version-history":[{"count":26,"href":"https:\/\/www.e-consystems.com\/blog\/windowsce\/wp-json\/wp\/v2\/posts\/759\/revisions"}],"predecessor-version":[{"id":1958,"href":"https:\/\/www.e-consystems.com\/blog\/windowsce\/wp-json\/wp\/v2\/posts\/759\/revisions\/1958"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.e-consystems.com\/blog\/windowsce\/wp-json\/wp\/v2\/media\/1396"}],"wp:attachment":[{"href":"https:\/\/www.e-consystems.com\/blog\/windowsce\/wp-json\/wp\/v2\/media?parent=759"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.e-consystems.com\/blog\/windowsce\/wp-json\/wp\/v2\/categories?post=759"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.e-consystems.com\/blog\/windowsce\/wp-json\/wp\/v2\/tags?post=759"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}