SubtitleVMR9Filter.cpp

Go to the documentation of this file.
00001 //===========================================================================
00002 //Copyright (C) 2004 Zentaro Kavanagh
00003 //
00004 //Redistribution and use in source and binary forms, with or without
00005 //modification, are permitted provided that the following conditions
00006 //are met:
00007 //
00008 //- Redistributions of source code must retain the above copyright
00009 //  notice, this list of conditions and the following disclaimer.
00010 //
00011 //- Redistributions in binary form must reproduce the above copyright
00012 //  notice, this list of conditions and the following disclaimer in the
00013 //  documentation and/or other materials provided with the distribution.
00014 //
00015 //- Neither the name of Zentaro Kavanagh nor the names of contributors 
00016 //  may be used to endorse or promote products derived from this software 
00017 //  without specific prior written permission.
00018 //
00019 //THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00020 //``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00021 //LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
00022 //PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE ORGANISATION OR
00023 //CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00024 //EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00025 //PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00026 //PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00027 //LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00028 //NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00029 //SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00030 //===========================================================================
00031 #include "stdafx.h"
00032 #include "subtitlevmr9filter.h"
00033 
00034 
00035 //COM Factory Template
00036 CFactoryTemplate g_Templates[] = 
00037 {
00038     { 
00039                 L"Subtitle VMR9 Filter",                                        // Name
00040             &CLSID_SubtitleVMR9Filter,                          // CLSID
00041             SubtitleVMR9Filter::CreateInstance,         // Method to create an instance of Speex Decoder
00042         NULL,                                                                   // Initialization function
00043         NULL                                                                    // Set-up information (for filters)
00044     }
00045 
00046 };
00047 
00048 // Generic way of determining the number of items in the template
00049 int g_cTemplates = sizeof(g_Templates) / sizeof(g_Templates[0]); 
00050 
00051 CUnknown* WINAPI SubtitleVMR9Filter::CreateInstance(LPUNKNOWN pUnk, HRESULT *pHr) 
00052 {
00053         //This routine is the COM implementation to create a new Filter
00054         SubtitleVMR9Filter *pNewObject = new SubtitleVMR9Filter();
00055     if (pNewObject == NULL) {
00056         *pHr = E_OUTOFMEMORY;
00057     }
00058         return pNewObject;
00059 } 
00060 
00061 //***********************&!*(#&$()*&!@()*#&!@()*#&()!@*&#)(!@*&#()*!@&#)(*!@&#)*(!@
00062 //This esentially disables the filter...
00063 HRESULT SubtitleVMR9Filter::Receive(IMediaSample *pMediaSample) {
00064         return S_OK;
00065 }
00066 //&)(*Q&#$()*!@&#$()!*@&#)(*!@&#)(*!@&#)(*&!@)#(*&!@)(#*&()!@*#&)(!*@&#()!*@&#()!@*&#
00067 
00068 SubtitleVMR9Filter::SubtitleVMR9Filter(void)
00069         :       CBaseRenderer(CLSID_SubtitleVMR9Filter, NAME("Subtitle VMR9 Filter") ,NULL,&mHR)
00070         ,       mBitmapMixer(NULL)
00071         ,       mVideoWindow(NULL)
00072         ,       mWindowLess(NULL)
00073 {
00074         //debugLog.open("G:\\logs\\vmr9_subs.log", ios_base::out);
00075         //mOutputPin = new SubtitleVMR9OutputPin(this, m_pLock, NAME("SubtitleVMR9OutputPin"), L"Subtitle Out");
00076 }
00077 
00078 SubtitleVMR9Filter::~SubtitleVMR9Filter(void)
00079 {
00080         //debugLog<<"Destructor for subtitle renderer"<<endl;
00081         //debugLog.close();
00082 
00083         if (mBitmapMixer != NULL) {
00084                 mBitmapMixer->Release();
00085         }
00086 
00087         if (mVideoWindow != NULL) {
00088                 mVideoWindow->Release();
00089         }
00090 
00091         if (mWindowLess != NULL) {
00092                 mWindowLess->Release();
00093         }
00094 }
00095 
00096 STDMETHODIMP SubtitleVMR9Filter::GetState(DWORD dw, FILTER_STATE *pState)
00097 {
00098     CheckPointer(pState, E_POINTER);
00099     *pState = m_State;
00100         if (m_State == State_Paused) {
00101         return VFW_S_CANT_CUE;
00102         } else {
00103         return S_OK;
00104         }
00105 }
00106 int SubtitleVMR9Filter::GetPinCount(void) {
00107         return 1;
00108 }
00109 CBasePin* SubtitleVMR9Filter::GetPin(int inPinNo) {
00110         if (inPinNo == 0) {
00111                 return CBaseRenderer::GetPin(inPinNo);
00112         } else {
00113                 return NULL;
00114         }
00115 }
00116 
00117 HRESULT SubtitleVMR9Filter::CheckMediaType(const CMediaType* inMediaType) {
00118         return S_OK;
00119 }
00120 HRESULT SubtitleVMR9Filter::DoRenderSample(IMediaSample* inMediaSample) {
00121         //debugLog<<"DoRenderSample : "<<endl;
00122         LONGLONG locStart, locEnd;
00123         inMediaSample->GetTime(&locStart, &locEnd);
00124         //debugLog<<"DoRenderSample : Time = "<<locStart<<" to "<<locEnd<<endl;
00125         inMediaSample->GetMediaTime(&locStart, &locEnd);
00126         //debugLog<<"DoRenderSample : Media Time = "<<locStart<<" to "<<locEnd<<endl;
00127         static int c = 0;
00128         const int hm = 50;
00129         if (mBitmapMixer == NULL) {
00130                 IFilterGraph* locFilterGraph = NULL;
00131                 locFilterGraph = GetFilterGraph();
00132 
00133         
00134                 IBaseFilter* locVMR9 = NULL;
00135                 HRESULT locHR = locFilterGraph->FindFilterByName(L"Video Mixing Renderer 9", &locVMR9);
00136                 if (locVMR9 != NULL) {
00137                         //debugLog<<"DoRenderSample : Getting VMR9 pointer..."<<endl;
00138                         HRESULT locHR = locVMR9->QueryInterface(IID_IVMRMixerBitmap9, (void**)&mBitmapMixer);
00139                         locHR = locVMR9->QueryInterface(IID_IVMRWindowlessControl9, (void**)&mWindowLess);
00140 
00141                         locHR = locVMR9->QueryInterface(IID_IVideoWindow, (void**)&mVideoWindow);
00142                         locVMR9->Release();
00143                 } else {
00144                         return S_OK;
00145                 }
00146         } else {
00147                 /*c++;
00148                 string x;
00149                 switch ((c / hm) % 4) {
00150                         case 0:
00151                 x = "One";
00152                                 SetSubtitle(x);
00153                                 break;
00154                         case 1:
00155                 x = "Two";
00156                                 SetSubtitle(x);
00157                                 break;
00158 
00159                         case 2:
00160                 x = "Three";
00161                                 SetSubtitle(x);
00162                                 break;
00163                         case 3:
00164                 x = "Four";
00165                                 SetSubtitle(x);
00166                                 break;
00167                         default:
00168                                 break;
00169 
00170 
00171                 }*/
00172                 
00173                 if (inMediaSample->GetActualDataLength() > 0) {
00174                         wchar_t* locStr = NULL;
00175                         BYTE* locBuff = NULL;
00176                         inMediaSample->GetPointer(&locBuff);
00177                         locStr = new wchar_t[inMediaSample->GetActualDataLength() / sizeof(wchar_t)];
00178                         memcpy((void*)locStr, (const void*) locBuff, inMediaSample->GetActualDataLength());
00179                         wstring x = locStr;
00180                         //debugLog<<"DoRenderSample : Subtile = "<<x<<endl;
00181                         SetSubtitle(x);
00182                         //debugLog<<"DoRenderSample : SetSubtitle Returns"<<endl<<endl;
00183                         delete locStr;
00184                 } else {
00185                         //debugLog<<"DoRenderSample : Clearing Subtitle..."<<endl;
00186                         SetSubtitle(L"");
00187                 }
00188 
00189 
00190                 return S_OK;
00191         }
00192         //debugLog<<"DoRenderSample : NEVER SHOULD BE HERE !!!!!!"<<endl;
00193 }
00194 
00195 
00196 
00197 
00198 HRESULT SubtitleVMR9Filter::SetSubtitle(wstring inSubtitle) {
00199  //   LONG cx, cy;
00200  //   HRESULT locHR;
00201 
00202  //   // Read the default video size
00203  //   //hr = pWC->GetNativeVideoSize(&cx, &cy, NULL, NULL);
00204  //   //if (FAILED(hr))
00205  //   //{
00206  //   //    Msg(TEXT("GetNativeVideoSize FAILED!  hr=0x%x\r\n"), hr);
00207  //   //    return hr;
00208  //   //}
00209 
00210  //   // Create a device context compatible with the current window
00211 
00212         //locHR = mBitmapMixer->GetAlphaBitmapParameters(&mAlphaBitmap);
00213  //   //HDC hdc = GetDC(hwndApp);
00214  //   HDC locHDCBitmap = CreateCompatibleDC(mAlphaBitmap.hdc);
00215 
00216  //   // Write with a known font by selecting it into our HDC
00217  //   HFONT locFontHandle = (HFONT) SelectObject(locHDCBitmap, g_hFont);
00218 
00219  //   // Determine the length of the string, then determine the
00220  //   // dimensions (in pixels) of the character string using the
00221  //   // currently selected font.  These dimensions are used to create
00222  //   // a bitmap below.
00223  //   int locLength, locTextBmpWidth, locTextBmpHeight;
00224  //   SIZE sz={0};
00225  //   locLength = inSubtitle.size();
00226  //   GetTextExtentPoint32(locHDCBitmap, inSubtitle.c_str(), locLength, &sz);
00227  //   locTextBmpHeight = sz.cy;
00228  //   locTextBmpWidth  = sz.cx;
00229 
00230  //   // Create a new bitmap that is compatible with the current window
00231  //   HBITMAP locBitmapHandle = CreateCompatibleBitmap(mAlphaBitmap.hdc, locTextBmpWidth, locTextBmpHeight);
00232  //   //ReleaseDC(hwndApp, hdc);
00233 
00234  //   // Select our bitmap into the device context and save the old one
00235  //   BITMAP locBitmap;
00236  //   HBITMAP locOldBitmapHandle;
00237  //   GetObject(locBitmapHandle, sizeof(locBitmap), &locBitmap);
00238  //   locOldBitmapHandle = (HBITMAP)SelectObject(locBitmapHandle, locBitmapHandle);
00239 
00240  //   // Set initial bitmap settings
00241  //   RECT rcText;
00242  //   SetRect(&rcText, 0, 0, nTextBmpWidth, nTextBmpHeight);
00243  //   SetBkColor(locBitmapHandle, RGB(255, 255, 255)); // Pure white background
00244  //   SetTextColor(locBitmapHandle, g_rgbColors);      // Write text with requested color
00245 
00246  //   // Draw the requested text string onto the bitmap
00247  //   TextOut(locBitmapHandle, 0, 0, inSubtitle.c_str(), locLength);
00248 
00249  //   // Configure the VMR's bitmap structure
00250  //   //VMR9AlphaBitmap bmpInfo;
00251  //   ZeroMemory(&mAlphaBitmap, sizeof(mAlphaBitmap) );
00252  //   mAlphaBitmap.dwFlags = VMRBITMAP_HDC;
00253  //   mAlphaBitmap.hdc = locHDCBitmap;  // DC which has selected our bitmap
00254 
00255  //   // Remember the width of this new bitmap
00256  //   g_nImageWidth = bm.bmWidth;
00257 
00258  //   // Save the ratio of the bitmap's width to the width of the video file.
00259  //   // This value is used to reposition the bitmap in composition space.
00260  //   g_fBitmapCompWidth = (float)g_nImageWidth / (float)cx;
00261 
00262  //   // Display the bitmap in the bottom right corner.
00263  //   // rSrc specifies the source rectangle in the GDI device context 
00264  //   // rDest specifies the destination rectangle in composition space (0.0f to 1.0f)
00265  //   mAlphaBitmap.rDest.left  = 0.0f + X_EDGE_BUFFER;
00266  //   mAlphaBitmap.rDest.right = 1.0f - X_EDGE_BUFFER;
00267  //   mAlphaBitmap.rDest.top = (float)(cy - bm.bmHeight) / (float)cy - Y_EDGE_BUFFER;
00268  //   bmAlphaBitmap.rDest.bottom = 1.0f - Y_EDGE_BUFFER;
00269  //   mAlphaBitmap.rSrc = rcText;
00270 
00271  //   // Transparency value 1.0 is opaque, 0.0 is transparent.
00272  //   mAlphaBitmap.fAlpha = TRANSPARENCY_VALUE;
00273 
00274  //   // Set the COLORREF so that the bitmap outline will be transparent
00275  //   SetColorRef(mAlphaBitmap);
00276 
00277  //   // Give the bitmap to the VMR for display
00278  //   locHR = mBitmapMixer->SetAlphaBitmap(&mAlphaBitmap);
00279  //   if (FAILED(hr))
00280  //       Msg(TEXT("SetAlphaBitmap FAILED!  hr=0x%x\r\n\r\n%s\0"), hr,
00281  //           STR_VMR_DISPLAY_WARNING);
00282 
00283  //   // Select the initial objects back into our device context
00284  //   DeleteObject(SelectObject(locBitmapHDC,locOldBitmapHandle ));
00285  //   SelectObject(locHDCBitmap, locFont);
00286 
00287  //   // Clean up resources
00288  //   DeleteObject(hbm);
00289  //   DeleteDC(hdcBmp);
00290 
00291  //   return hr;
00292 
00293 
00294         // Text font information
00295         HFONT g_hFont=0;
00296         LONG g_lFontPointSize   = DEFAULT_FONT_SIZE;
00297         COLORREF g_rgbColors    = DEFAULT_FONT_COLOR;
00298         TCHAR g_szFontName[100] = {DEFAULT_FONT_NAME};
00299         TCHAR g_szFontStyle[32] = {DEFAULT_FONT_STYLE};
00300 
00301         LONG cx, cy;
00302     HRESULT hr;
00303 
00304     // Read the default video size
00305         if (mWindowLess != NULL) {
00306                 hr = mWindowLess->GetNativeVideoSize(&cx, &cy, NULL, NULL);
00307         } else {
00308                 mVideoWindow->get_Width(&cx);
00309                 mVideoWindow->get_Height(&cy);
00310         }
00311     //if (FAILED(hr))
00312     //{
00313     //    Msg(TEXT("GetNativeVideoSize FAILED!  hr=0x%x\r\n"), hr);
00314     //    return hr;
00315     //}
00316 
00317     // Create a device context compatible with the current window
00318         hr = mBitmapMixer->GetAlphaBitmapParameters(&mAlphaBitmap);
00319         //HWND hwndApp;
00320         //OAHWND oah;
00321         //mVideoWindow->get_Owner(&oah);
00322         HDC hdc = GetDC(NULL);
00323     //HDC hdc = mAlphaBitmap.hdc;
00324     HDC hdcBmp = CreateCompatibleDC(hdc);
00325 
00326     // Write with a known font by selecting it into our HDC
00327     HFONT hOldFont = (HFONT) SelectObject(hdcBmp, g_hFont);
00328 
00329     // Determine the length of the string, then determine the
00330     // dimensions (in pixels) of the character string using the
00331     // currently selected font.  These dimensions are used to create
00332     // a bitmap below.
00333     int nLength, nTextBmpWidth, nTextBmpHeight;
00334     SIZE sz={0};
00335     
00336         TCHAR* szNewText = (TCHAR*)inSubtitle.c_str();//_T("Annodex Me Baby !");//inSubtitle.c_str();
00337         nLength = _tcslen(szNewText); ;//(int) inSubtitle.size();
00338 
00339     GetTextExtentPoint32(hdcBmp, szNewText, nLength, &sz);
00340     nTextBmpHeight = sz.cy;
00341     nTextBmpWidth  = sz.cx;
00342 
00343     // Create a new bitmap that is compatible with the current window
00344     HBITMAP hbm = CreateCompatibleBitmap(hdc, nTextBmpWidth, nTextBmpHeight);
00345     //ReleaseDC(hwndApp, hdc);
00346 
00347     // Select our bitmap into the device context and save the old one
00348     BITMAP bm;
00349     HBITMAP hbmOld;
00350     GetObject(hbm, sizeof(bm), &bm);
00351     hbmOld = (HBITMAP)SelectObject(hdcBmp, hbm);
00352 
00353     // Set initial bitmap settings
00354     RECT rcText;
00355     SetRect(&rcText, 0, 0, nTextBmpWidth, nTextBmpHeight);
00356     SetBkColor(hdcBmp, RGB(255, 255, 255)); // Pure white background
00357     SetTextColor(hdcBmp, g_rgbColors);      // Write text with requested color
00358 
00359     // Draw the requested text string onto the bitmap
00360     BOOL ret = TextOut(hdcBmp, 0, 0, szNewText, nLength);
00361 
00362     // Configure the VMR's bitmap structure
00363     VMR9AlphaBitmap bmpInfo;
00364     ZeroMemory(&bmpInfo, sizeof(bmpInfo) );
00365     bmpInfo.dwFlags = VMRBITMAP_HDC;
00366     bmpInfo.hdc = hdcBmp;  // DC which has selected our bitmap
00367 
00368     // Remember the width of this new bitmap
00369     //g_nImageWidth = bm.bmWidth;
00370 
00371     // Save the ratio of the bitmap's width to the width of the video file.
00372     // This value is used to reposition the bitmap in composition space.
00373     //g_fBitmapCompWidth = (float)g_nImageWidth / (float)cx;
00374 
00375     // Display the bitmap in the bottom right corner.
00376     // rSrc specifies the source rectangle in the GDI device context 
00377     // rDest specifies the destination rectangle in composition space (0.0f to 1.0f)
00378 
00379         const float X_EDGE_BUFFER=0.05f; // Pixel buffer between bitmap and window edge
00380                                  // (represented in composition space [0 - 1.0f])
00381         const float Y_EDGE_BUFFER=0.05f;
00382 
00383     bmpInfo.rDest.left  = 0.0f + X_EDGE_BUFFER;
00384     bmpInfo.rDest.right = 1.0f - X_EDGE_BUFFER;
00385     bmpInfo.rDest.top = (float)(cy - bm.bmHeight) / (float)cy - Y_EDGE_BUFFER;
00386         //bmpInfo.rDest.top = (float)(200.0f - bm.bmHeight) / (float)200.0f - Y_EDGE_BUFFER;
00387         //bmpInfo.rDest.top = 0.8f;//(float)(200.0f - bm.bmHeight) / (float)200.0f - Y_EDGE_BUFFER;
00388     bmpInfo.rDest.bottom = 1.0f - Y_EDGE_BUFFER;
00389     bmpInfo.rSrc = rcText;
00390 
00391     // Transparency value 1.0 is opaque, 0.0 is transparent.
00392     bmpInfo.fAlpha = TRANSPARENCY_VALUE;
00393 
00394     // Set the COLORREF so that the bitmap outline will be transparent
00395     SetColorRef(bmpInfo);
00396 
00397     // Give the bitmap to the VMR for display
00398     hr = mBitmapMixer->SetAlphaBitmap(&bmpInfo);
00399     //if (FAILED(hr))
00400         //Msg(TEXT("SetAlphaBitmap FAILED!  hr=0x%x\r\n\r\n%s\0"), hr,
00401           //  STR_VMR_DISPLAY_WARNING);
00402 
00403     // Select the initial objects back into our device context
00404     DeleteObject(SelectObject(hdcBmp, hbmOld));
00405     SelectObject(hdc, hOldFont);
00406 
00407     // Clean up resources
00408     DeleteObject(hbm);
00409     DeleteDC(hdcBmp);
00410 
00411         //debugLog<<"SetSubtitle : End of method: hr = "<<hr<<endl;
00412     return hr;
00413 }
00414 
00415 void SubtitleVMR9Filter::SetColorRef(VMR9AlphaBitmap& bmpInfo)
00416 {
00417     // Set the COLORREF so that the bitmap outline will be transparent
00418     bmpInfo.clrSrcKey = RGB(255, 255, 255);  // Pure white
00419     bmpInfo.dwFlags |= VMRBITMAP_SRCCOLORKEY;
00420 }

Generated on Tue Feb 15 14:54:20 2005 for oggdsf by  doxygen 1.3.9