source: trunk/src/testing/app/hd-video-player/Utils.cpp @ 4

Revision 4, 23.6 KB checked in by ajaworski, 13 years ago (diff)

Added modified SAGE sources

Line 
1/******************************************************************************
2 * SAGE - Scalable Adaptive Graphics Environment
3 *
4 * Copyright (C) 2004 Electronic Visualization Laboratory,
5 * University of Illinois at Chicago
6 *
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met:
11 *
12 *  * Redistributions of source code must retain the above copyright
13 *    notice, this list of conditions and the following disclaimer.
14 *  * Redistributions in binary form must reproduce the above
15 *    copyright notice, this list of conditions and the following disclaimer
16 *    in the documentation and/or other materials provided with the distribution.
17 *  * Neither the name of the University of Illinois at Chicago nor
18 *    the names of its contributors may be used to endorse or promote
19 *    products derived from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
25 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 *
33 * Direct questions, comments etc about SAGE to http://www.evl.uic.edu/cavern/forum/
34 *
35 *****************************************************************************/
36
37//------------------------------------------------------------------------------------
38// $Id: Utils.cpp,v 1.10 2006/04/11 01:13:06 ivanr Exp $
39//
40// Desc: DirectShow utility class implementation
41//
42// Copyright (c) Blackmagic Design 2005. All rights reserved.
43//------------------------------------------------------------------------------------
44
45#include "stdafx.h"
46#include "Utils.h"
47
48//-----------------------------------------------------------------------------
49// CDSUtils - Directshow utility class
50//-----------------------------------------------------------------------------
51//-----------------------------------------------------------------------------
52// AddFilter
53// Attempts to locate a filter of a given class ID and name     and add it to the graph
54// If your DirectShow application supports playback of DRM-protected files,
55// then you generally should not use RenderFile to create the filter graph
56// because there is no way to specify which DRM rights you are requesting before the file is opened.
57// The WM ASF Reader by default asks for only playback rights.
58// The filter is not added to the graph, and is therefore not discoverable by applications, until a file is successfully opened.
59HRESULT CDSUtils::AddFilter(IGraphBuilder* pGraph, const GUID &clsid, LPCWSTR pName, IBaseFilter** ppFilter)
60{
61        HRESULT hr = S_OK;
62
63        if (pGraph && pName && ppFilter)
64        {
65                *ppFilter = NULL;
66                IBaseFilter* pFilter = NULL;
67                hr = CoCreateInstance(clsid, 0, CLSCTX_INPROC_SERVER, IID_IBaseFilter, reinterpret_cast<void**>(&pFilter));
68                if (SUCCEEDED(hr))
69                {
70                        hr = pGraph->AddFilter(pFilter, pName);
71                        if (SUCCEEDED(hr))
72                        {
73                                *ppFilter = pFilter;
74                        }
75                        else
76                        {
77                                SAFE_RELEASE(pFilter);
78                        }
79                }
80        }
81        else
82        {
83                hr = E_INVALIDARG;
84        }
85
86        return hr;
87}
88
89//-----------------------------------------------------------------------------
90// AddFilter2
91// Attempts to locate a filter of a given class category and name
92HRESULT CDSUtils::AddFilter2(IGraphBuilder* pGraph, const GUID &clsid, LPCWSTR pName, IBaseFilter** ppFilter)
93{
94        HRESULT hr = S_OK;
95
96        if (pGraph && pName && ppFilter)
97        {
98                // first enumerate the system devices for the specifed class and filter name
99                CComPtr<ICreateDevEnum> pSysDevEnum = NULL;
100                hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, reinterpret_cast<void**>(&pSysDevEnum));
101
102                if (SUCCEEDED(hr))
103                {
104                        CComPtr<IEnumMoniker> pEnumCat = NULL;
105                        hr = pSysDevEnum->CreateClassEnumerator(clsid, &pEnumCat, 0);
106
107                        if (S_OK == hr)
108                        {
109                                IMoniker* pMoniker = NULL;
110                                bool Loop = true;
111                                while ((S_OK == pEnumCat->Next(1, &pMoniker, NULL)) && Loop)
112                                {
113                                        IPropertyBag* pPropBag = NULL;
114                                        hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, reinterpret_cast<void**>(&pPropBag));
115
116                                        if (SUCCEEDED(hr))
117                                        {
118                                                VARIANT varName;
119                                                VariantInit(&varName);
120                                                hr = pPropBag->Read(L"FriendlyName", &varName, 0);
121                                                if (SUCCEEDED(hr))
122                                                {
123                                                        if (0 == wcscmp(varName.bstrVal, pName))
124                                                        {
125                                                                hr = pMoniker->BindToObject(NULL, NULL, IID_IBaseFilter, reinterpret_cast<void**>(ppFilter));
126                                                                Loop = false;
127                                                        }
128                                                }
129
130                                                VariantClear(&varName);
131
132                                                // contained within a loop, decrement the reference count
133                                                SAFE_RELEASE(pPropBag);
134                                        }
135                                        SAFE_RELEASE(pMoniker);
136                                }
137                        }
138                }
139
140                // if a filter has been located add it to the graph
141                if (*ppFilter)
142                {
143                        hr = pGraph->AddFilter(reinterpret_cast<IBaseFilter*>(*ppFilter), pName);
144                }
145                else
146                {
147                        hr = E_FAIL;
148                }
149        }
150        else
151        {
152                hr = E_INVALIDARG;
153        }
154
155        return hr;
156}
157
158//-------------------------------------------------------------------------------------------------
159// GetUnconnectedPin
160// Attemptes to locate an unconnected pin on filter
161HRESULT CDSUtils::GetUnconnectedPin(IBaseFilter* pFilter, PIN_DIRECTION PinDir, IPin** ppPin)
162{
163        HRESULT hr = S_OK;
164
165        if (pFilter && ppPin)
166        {
167                CComPtr<IEnumPins> pEnum = NULL;
168                IPin* pPin = NULL;
169
170                hr = pFilter->EnumPins(&pEnum);
171                if (SUCCEEDED(hr))
172                {
173                        while (pEnum->Next(1, &pPin, NULL) == S_OK)
174                        {
175                                PIN_DIRECTION ThisPinDir;
176                                pPin->QueryDirection(&ThisPinDir);
177                                if (ThisPinDir == PinDir)
178                                {
179                                        IPin* pPinTemp = NULL;
180
181                                        hr = pPin->ConnectedTo(&pPinTemp);
182                                        if (SUCCEEDED(hr))
183                                        {
184                                                SAFE_RELEASE(pPinTemp);
185                                        }
186                                        else
187                                        {
188                                                // unconnected, return this pin
189                                                *ppPin = pPin;
190                                                hr = S_OK;
191                                                break;
192                                        }
193                                }
194                                SAFE_RELEASE(pPin);
195                        }
196                }
197
198                if (NULL == *ppPin)
199                {
200                        // failed to find an unconnected pin
201                        hr = E_FAIL;
202                }
203        }
204        else
205        {
206                hr = E_INVALIDARG;
207        }
208
209        return hr;
210}
211
212//-----------------------------------------------------------------------------
213// GetPin
214// Find the pin of the specified name on the given filter
215// This method leaves an outstanding reference on the pin if successful
216HRESULT CDSUtils::GetPin(IBaseFilter* pFilter, const wchar_t* pName, IPin** ppPin)
217{
218        HRESULT hr = S_OK;
219
220        if (pFilter && pName && ppPin)
221        {
222                CComPtr<IEnumPins> pIEnumPins = NULL;
223                hr = pFilter->EnumPins(&pIEnumPins);
224                if (SUCCEEDED(hr))
225                {
226                        IPin* pIPin = NULL;
227                        while (S_OK == pIEnumPins->Next(1, &pIPin, NULL))
228                        {
229                                PIN_INFO info = {0};
230                                hr = pIPin->QueryPinInfo(&info);
231                                if (SUCCEEDED(hr))
232                                {
233                                        SAFE_RELEASE(info.pFilter);
234
235                                        if (0 == wcsncmp(info.achName, pName, wcslen(pName)))
236                                        {
237                                                // matched the pin category
238                                                *ppPin = pIPin;
239                                                break;
240                                        }
241                                }
242                                SAFE_RELEASE(pIPin);
243                        }
244                }
245
246                if (NULL == *ppPin)
247                {
248                        // failed to find the named pin
249                        hr = E_FAIL;
250                }
251        }
252        else
253        {
254                hr = E_INVALIDARG;
255        }
256
257        return hr;
258}
259
260//-----------------------------------------------------------------------------
261// GetPin
262// Find the pin of the specified format type on the given filter
263// This method leaves an outstanding reference on the pin if successful
264HRESULT CDSUtils::GetPin(IBaseFilter* pFilter, const GUID* pFormat, PIN_DIRECTION PinDir, IPin** ppPin)
265{
266        HRESULT hr = S_OK;
267
268        if (pFilter && pFormat && ppPin)
269        {
270                CComPtr<IEnumPins> pIEnumPins = NULL;
271                hr = pFilter->EnumPins(&pIEnumPins);
272                if (SUCCEEDED(hr))
273                {
274                        // find the pin with the specified format
275                        IPin* pIPin = NULL;
276                        while (S_OK == pIEnumPins->Next(1, &pIPin, NULL))
277                        {
278                                // match the pin direction
279                                PIN_DIRECTION pinDir;
280                                pIPin->QueryDirection(&pinDir);
281                                if (pinDir == PinDir)
282                                {
283                                        // match pin direction check the first media type returned from the upstream pin
284                                        CComPtr<IEnumMediaTypes> pIEnumMT = NULL;
285                                        hr = pIPin->EnumMediaTypes(&pIEnumMT);
286                                        if (SUCCEEDED(hr))
287                                        {
288                                                AM_MEDIA_TYPE* pmt = NULL;
289                                                hr = pIEnumMT->Next(1, &pmt, NULL);
290                                                if (S_OK == hr)
291                                                {
292                                                        if (pmt->majortype == *pFormat)
293                                                        {
294                                                                // found the pin with the specified format
295                                                                *ppPin = pIPin;
296                                                                DeleteMediaType(pmt);
297                                                                break;
298                                                        }
299                                                        else
300                                                        {
301                                                                DeleteMediaType(pmt);
302                                                        }
303                                                }
304                                        }
305                                }
306                                SAFE_RELEASE(pIPin);
307                        }
308
309                        if (NULL == *ppPin)
310                        {
311                                // failed to find the named pin
312                                hr = E_FAIL;
313                        }
314                }
315        }
316        else
317        {
318                hr = E_INVALIDARG;
319        }
320
321        return hr;
322}
323
324//-----------------------------------------------------------------------------
325// ConnectFiltersNamedPin
326// Connects two filters using the pin names, if no name is supplied the first
327// unconnected pin is used
328HRESULT CDSUtils::ConnectFilters(IGraphBuilder* pGraph, IBaseFilter* pUpstream, wchar_t* pUpstreamPinName, IBaseFilter* pDownstream, wchar_t* pDownstreamPinName)
329{
330        HRESULT hr = S_OK;
331
332        if (pUpstream && pDownstream)
333        {
334                // get the upstream output pin
335                CComPtr<IPin> pIPinOutput = NULL;
336                if (pUpstreamPinName)
337                {
338                        hr = GetPin(pUpstream, pUpstreamPinName, &pIPinOutput);
339                }
340                else
341                {
342                        hr = GetUnconnectedPin(pUpstream, PINDIR_OUTPUT, &pIPinOutput);
343                }
344
345                if (SUCCEEDED(hr))
346                {
347                        // get the downstream input pin
348                        CComPtr<IPin> pIPinInput = NULL;
349                        if (pDownstreamPinName)
350                        {
351                                hr = GetPin(pDownstream, pDownstreamPinName, &pIPinInput);
352                        }
353                        else
354                        {
355                                hr = GetUnconnectedPin(pDownstream, PINDIR_INPUT, &pIPinInput);
356                        }
357
358                        if (SUCCEEDED(hr))
359                        {
360                                // connect the pins
361                                hr = pGraph->Connect(pIPinOutput, pIPinInput);
362                        }
363                }
364        }
365        else
366        {
367                hr = E_INVALIDARG;
368        }
369
370        return hr;
371}
372
373//-----------------------------------------------------------------------------
374// ConnectFilters
375// Connects two filters by finding a pin on the upstream filter with the specified
376// major format type, e.g. For connecting an audio pin to a downstream filter
377HRESULT CDSUtils::ConnectFilters(IGraphBuilder* pGraph, IBaseFilter* pUpstream, IBaseFilter* pDownstream, const GUID* pFormat)
378{
379        HRESULT hr = S_OK;
380
381        if (pUpstream && pDownstream && pFormat)
382        {
383                // find the upstream output pin with the specified format
384                CComPtr<IPin> pIPinOutput = NULL;
385                hr = GetPin(pUpstream, pFormat, PINDIR_OUTPUT, &pIPinOutput);
386                if (SUCCEEDED(hr))
387                {
388                        // get the downstream input pin
389                        CComPtr<IPin> pIPinInput = NULL;
390                        hr = GetPin(pDownstream, pFormat, PINDIR_INPUT, &pIPinInput);
391
392                        if (SUCCEEDED(hr))
393                        {
394                                // connect the pins
395                                hr = pGraph->Connect(pIPinOutput, pIPinInput);
396                        }
397                }
398        }
399        else
400        {
401                hr = E_INVALIDARG;
402        }
403
404        return hr;
405}
406
407//-----------------------------------------------------------------------------
408// RenderFilter
409// Renders the named output pin of the filter, or the first unconnected output if
410// no name is provided
411HRESULT CDSUtils::RenderFilter(IGraphBuilder* pGraph, IBaseFilter* pUpstream, wchar_t* pUpstreamPinName)
412{
413        HRESULT hr = S_OK;
414
415        if (pUpstream)
416        {
417                CComPtr<IPin> pIPinOutput = NULL;
418                if (pUpstreamPinName)
419                {
420                        hr = GetPin(pUpstream, pUpstreamPinName, &pIPinOutput);
421                }
422                else
423                {
424                        hr = GetUnconnectedPin(pUpstream, PINDIR_OUTPUT, &pIPinOutput);
425                }
426
427                if (SUCCEEDED(hr))
428                {
429                        hr = pGraph->Render(pIPinOutput);
430                }
431        }
432        else
433        {
434                hr = E_INVALIDARG;
435        }
436
437        return hr;
438}
439
440//-----------------------------------------------------------------------------
441// DisconnectAllPins
442// Disconnect all the pins of the filters in a graph
443HRESULT CDSUtils::DisconnectAllPins(IGraphBuilder* pGraph)
444{
445        HRESULT hr = S_OK;
446
447        if (pGraph)
448        {
449                CComPtr<IEnumFilters> pIEnumFilters = NULL;
450                hr = pGraph->EnumFilters(&pIEnumFilters);
451                if (SUCCEEDED(hr))
452                {
453                        IBaseFilter* pFilter = NULL;
454                        while (S_OK == pIEnumFilters->Next(1, &pFilter, NULL))
455                        {
456                                CComPtr<IEnumPins> pIEnumPins = NULL;
457                                hr = pFilter->EnumPins(&pIEnumPins);
458                                if (SUCCEEDED(hr))
459                                {
460                                        IPin* pIPin = NULL;
461                                        while (S_OK == pIEnumPins->Next(1, &pIPin, NULL))
462                                        {
463                                                IPin* pIPinConnection = NULL;
464                                                if (S_OK == pIPin->ConnectedTo(&pIPinConnection))
465                                                {
466                                                        // pins are connected, to disconnect filters, both pins must be disconnected
467                                                        hr = pGraph->Disconnect(pIPin);
468                                                        hr = pGraph->Disconnect(pIPinConnection);
469                                                        SAFE_RELEASE(pIPinConnection);
470                                                }
471                                                SAFE_RELEASE(pIPin);
472                                        }
473                                }
474                                SAFE_RELEASE(pFilter);
475                        }
476                }
477        }
478        else
479        {
480                hr = E_INVALIDARG;
481        }
482
483        return hr;
484}
485
486//-----------------------------------------------------------------------------
487// FindFilterInterface
488// Attempt to locate the specified interface
489HRESULT CDSUtils::FindFilterInterface(IBaseFilter* pFilter, const IID& riid, void** ppvInterface)
490{
491        HRESULT hr = S_OK;
492
493        if (pFilter && ppvInterface)
494        {
495                hr = pFilter->QueryInterface(riid, ppvInterface);
496        }
497        else
498        {
499                hr = E_INVALIDARG;
500        }
501
502        return hr;
503}
504
505//-----------------------------------------------------------------------------
506// FindPinInterface
507// Attempt to locate the interface on the named pin or on the first pin if no
508// name is provided.
509HRESULT CDSUtils::FindPinInterface(IBaseFilter* pFilter, wchar_t* pName, const IID& riid, void** ppvInterface)
510{
511        HRESULT hr = S_OK;
512
513        if (pFilter && ppvInterface)
514        {
515                CComPtr<IPin> pIPin = NULL;
516                if (pName)
517                {
518                        hr = GetPin(pFilter, pName, &pIPin);
519                }
520                else
521                {
522                        CComPtr<IEnumPins> pIEnumPins = NULL;
523                        hr = pFilter->EnumPins(&pIEnumPins);
524                        if (SUCCEEDED(hr))
525                        {
526                                hr = pIEnumPins->Next(1, &pIPin, NULL);
527                        }
528                }
529
530                if (SUCCEEDED(hr))
531                {
532                        hr = pIPin->QueryInterface(riid, ppvInterface);
533                }
534        }
535        else
536        {
537                hr = E_INVALIDARG;
538        }
539
540        return hr;
541}
542
543//-----------------------------------------------------------------------------
544// FindPinInterface
545// Attempt to locate the interface on the pin with the specified format or on the first pin if no
546// format is provided.
547HRESULT CDSUtils::FindPinInterface(IBaseFilter* pFilter, const GUID* pFormat, PIN_DIRECTION PinDir, const IID& riid, void** ppvInterface)
548{
549        HRESULT hr = S_OK;
550
551        if (pFilter && ppvInterface)
552        {
553                CComPtr<IPin> pIPin = NULL;
554                if (pFormat)
555                {
556                        hr = GetPin(pFilter, pFormat, PinDir, &pIPin);
557                }
558                else
559                {
560                        CComPtr<IEnumPins> pIEnumPins = NULL;
561                        hr = pFilter->EnumPins(&pIEnumPins);
562                        if (SUCCEEDED(hr))
563                        {
564                                hr = pIEnumPins->Next(1, &pIPin, NULL);
565                        }
566                }
567
568                if (SUCCEEDED(hr))
569                {
570                        hr = pIPin->QueryInterface(riid, ppvInterface);
571                }
572        }
573        else
574        {
575                hr = E_INVALIDARG;
576        }
577
578        return hr;
579}
580
581//-----------------------------------------------------------------------------
582// AddGraphToRot
583// Adds a DirectShow filter graph to the Running Object Table,
584// allowing GraphEdit to "spy" on a remote filter graph.
585HRESULT CDSUtils::AddGraphToRot(IUnknown* pUnkGraph, DWORD* pdwRegister)
586{
587    HRESULT hr = S_OK;
588
589    if (pUnkGraph && pdwRegister)
590        {
591                CComPtr<IRunningObjectTable> pROT = NULL;
592                hr = GetRunningObjectTable(0, &pROT);
593                if (SUCCEEDED(hr))
594                {
595                        WCHAR wsz[128];
596                        StringCchPrintfW(wsz, 128, L"FilterGraph %08x pid %08x\0", (DWORD_PTR)pUnkGraph, GetCurrentProcessId());
597
598                        CComPtr<IMoniker> pMoniker = NULL;
599                        hr = CreateItemMoniker(L"!", wsz, &pMoniker);
600                        if(SUCCEEDED(hr))
601                        {
602                                // Use the ROTFLAGS_REGISTRATIONKEEPSALIVE to ensure a strong reference
603                                // to the object.  Using this flag will cause the object to remain
604                                // registered until it is explicitly revoked with the Revoke() method.
605                                //
606                                // Not using this flag means that if GraphEdit remotely connects
607                                // to this graph and then GraphEdit exits, this object registration
608                                // will be deleted, causing future attempts by GraphEdit to fail until
609                                // this application is restarted or until the graph is registered again.
610                                hr = pROT->Register(ROTFLAGS_REGISTRATIONKEEPSALIVE, pUnkGraph, pMoniker, pdwRegister);
611                        }
612                }
613        }
614        else
615        {
616                hr = E_INVALIDARG;
617        }
618
619    return hr;
620}
621
622//-----------------------------------------------------------------------------
623// RemoveGraphFromRot
624// Removes a filter graph from the Running Object Table
625void CDSUtils::RemoveGraphFromRot(DWORD pdwRegister)
626{
627    CComPtr<IRunningObjectTable> pROT = NULL;
628
629    if (SUCCEEDED(GetRunningObjectTable(0, &pROT)))
630    {
631        pROT->Revoke(pdwRegister);
632    }
633}
634
635//------------------------------------------------------------------------------------
636// CRegUtils - Registry utility class
637//------------------------------------------------------------------------------------
638//------------------------------------------------------------------------------------
639// Constructor
640//
641CRegUtils::CRegUtils()
642        : m_hKey(NULL)
643{
644}
645
646//------------------------------------------------------------------------------------
647// Destructor
648//
649CRegUtils::~CRegUtils()
650{
651        Close();
652}
653
654//------------------------------------------------------------------------------------
655// Open
656// Opens the specified subkey
657LONG CRegUtils::Open(LPCTSTR lpSubKey)
658{
659        Close();
660        m_subKeyName = "Software\\Blackmagic Design\\Samples\\";
661        m_subKeyName += lpSubKey;
662        return RegOpenKeyEx(HKEY_LOCAL_MACHINE, m_subKeyName.c_str(), 0, KEY_ALL_ACCESS, &m_hKey);
663}
664
665//------------------------------------------------------------------------------------
666// Create
667// Creates the specified subkey
668LONG CRegUtils::Create(LPCTSTR lpSubKey)
669{
670        Close();
671        m_subKeyName = "Software\\Blackmagic Design\\Samples\\";
672        m_subKeyName += lpSubKey;
673        return RegCreateKeyEx(HKEY_LOCAL_MACHINE, m_subKeyName.c_str(), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &m_hKey, NULL);
674}
675
676//------------------------------------------------------------------------------------
677// Close
678// Closes the subkey
679void CRegUtils::Close()
680{
681        RegCloseKey(m_hKey);
682        m_hKey = NULL;
683        m_subKeyName.empty();
684}
685
686//------------------------------------------------------------------------------------
687// SetString
688// Set the key for the named value of type string
689LONG CRegUtils::SetString(LPCTSTR valueName, const BYTE* lpData, DWORD cbData)
690{
691        return RegSetValueEx(m_hKey, valueName, 0, REG_SZ, lpData, cbData);
692}
693
694//------------------------------------------------------------------------------------
695// GetString
696// Query the key for the named value of type string
697LONG CRegUtils::GetString(LPCTSTR valueName, LPBYTE lpData, DWORD cbData)
698{
699        LONG ret = ERROR_SUCCESS;
700        DWORD size = cbData, type = 0;
701        ret = RegQueryValueEx(m_hKey, valueName, NULL, &type, lpData, &size);
702        if ((size != cbData) || (REG_SZ != type))
703        {
704                ret = ERROR_INVALID_PARAMETER;
705        }
706        return ret;
707}
708
709//------------------------------------------------------------------------------------
710// SetBinary
711// Set the key for the named value of type binary
712LONG CRegUtils::SetBinary(LPCTSTR valueName, const BYTE* lpData, DWORD cbData)
713{
714        return RegSetValueEx(m_hKey, valueName, 0, REG_BINARY, lpData, cbData);
715}
716
717//------------------------------------------------------------------------------------
718// GetBinary
719// Query the key for the named value of type binary
720LONG CRegUtils::GetBinary(LPCTSTR valueName, LPBYTE lpData, DWORD cbData)
721{
722        LONG ret = ERROR_SUCCESS;
723        DWORD size = cbData, type = 0;
724        ret = RegQueryValueEx(m_hKey, valueName, NULL, &type, lpData, &size);
725        if ((size != cbData) || (REG_BINARY != type))
726        {
727                ret = ERROR_INVALID_PARAMETER;
728        }
729        return ret;
730}
731
732//------------------------------------------------------------------------------------
733// SetDword
734// Set the key for the named value of type DWORD
735LONG CRegUtils::SetDword(LPCTSTR valueName, const BYTE* lpData, DWORD cbData)
736{
737        return RegSetValueEx(m_hKey, valueName, 0, REG_DWORD, lpData, cbData);
738}
739
740//------------------------------------------------------------------------------------
741// GetDword
742// Query the key for the named value of type DWORD
743LONG CRegUtils::GetDword(LPCTSTR valueName, LPBYTE lpData, DWORD cbData)
744{
745        LONG ret = ERROR_SUCCESS;
746        DWORD size = cbData, type = 0;
747        ret = RegQueryValueEx(m_hKey, valueName, NULL, &type, lpData, &size);
748        if ((size != cbData) || (REG_DWORD != type))
749        {
750                ret = ERROR_INVALID_PARAMETER;
751        }
752        return ret;
753}
754
755//------------------------------------------------------------------------------------
756// CUtils - utility class
757//------------------------------------------------------------------------------------
758//-----------------------------------------------------------------------------
759// GetBMIHeader
760// Returns the BITMAPINFOHEADER structure from media type format extension
761BITMAPINFOHEADER* CUtils::GetBMIHeader(const AM_MEDIA_TYPE* pamt)
762{
763        BITMAPINFOHEADER* pbmih = NULL;
764
765        if (pamt)
766        {
767                if (FORMAT_VideoInfo == pamt->formattype)
768                {
769                        VIDEOINFOHEADER* pvih = reinterpret_cast<VIDEOINFOHEADER*>(pamt->pbFormat);
770                        ASSERT(sizeof(VIDEOINFOHEADER) <= pamt->cbFormat);
771                        pbmih = &pvih->bmiHeader;
772                }
773                else if (FORMAT_VideoInfo2 == pamt->formattype)
774                {
775                        VIDEOINFOHEADER2* pvih = reinterpret_cast<VIDEOINFOHEADER2*>(pamt->pbFormat);
776                        ASSERT(sizeof(VIDEOINFOHEADER2) <= pamt->cbFormat);
777                        pbmih = &pvih->bmiHeader;
778                }
779        }
780
781        return pbmih;
782}
783
784//-----------------------------------------------------------------------------
785// GetBMIHeader
786// Returns the BITMAPINFOHEADER structure from media type format extension
787BITMAPINFOHEADER* CUtils::GetBMIHeader(const CMediaType& mt)
788{
789        BITMAPINFOHEADER* pbmih = NULL;
790
791        if (FORMAT_VideoInfo == mt.formattype)
792        {
793                VIDEOINFOHEADER* pvih = reinterpret_cast<VIDEOINFOHEADER*>(mt.pbFormat);
794                ASSERT(sizeof(VIDEOINFOHEADER) <= mt.cbFormat);
795                pbmih = &pvih->bmiHeader;
796        }
797        else if (FORMAT_VideoInfo2 == mt.formattype)
798        {
799                VIDEOINFOHEADER2* pvih = reinterpret_cast<VIDEOINFOHEADER2*>(mt.pbFormat);
800                ASSERT(sizeof(VIDEOINFOHEADER2) <= mt.cbFormat);
801                pbmih = &pvih->bmiHeader;
802        }
803
804        return pbmih;
805}
806
807//-----------------------------------------------------------------------------
808// GetAvgTimePerFrame
809// Returns the average time per frame from media type format extension
810REFERENCE_TIME CUtils::GetAvgTimePerFrame(const AM_MEDIA_TYPE* pamt)
811{
812        REFERENCE_TIME rtAvgTimePerFrame = 0;
813
814        if (pamt)
815        {
816                if (FORMAT_VideoInfo == pamt->formattype)
817                {
818                        VIDEOINFOHEADER* pvih = reinterpret_cast<VIDEOINFOHEADER*>(pamt->pbFormat);
819                        ASSERT(sizeof(VIDEOINFOHEADER) <= pamt->cbFormat);
820                        rtAvgTimePerFrame = pvih->AvgTimePerFrame;
821                }
822                else if (FORMAT_VideoInfo2 == pamt->formattype)
823                {
824                        VIDEOINFOHEADER2* pvih = reinterpret_cast<VIDEOINFOHEADER2*>(pamt->pbFormat);
825                        ASSERT(sizeof(VIDEOINFOHEADER2) <= pamt->cbFormat);
826                        rtAvgTimePerFrame = pvih->AvgTimePerFrame;
827                }
828        }
829
830        return rtAvgTimePerFrame;
831}
832
833//------------------------------------------------------------------------------------
834// GetImageSize
835// Calculates the image size
836unsigned long CUtils::GetImageSize(BITMAPINFOHEADER* pbmih)
837{
838        unsigned long dwImageSize = 0;
839
840        if (pbmih)
841        {
842                switch (pbmih->biCompression)
843                {
844                        default:
845                        case BI_RGB:
846                                dwImageSize = (pbmih->biWidth * abs(pbmih->biHeight) * pbmih->biBitCount) >> 3;
847                                break;
848
849                        case 'YVYU':
850                        case '2YUY':
851                                dwImageSize = (pbmih->biWidth * abs(pbmih->biHeight) * 16) >> 3;
852                                break;
853                }
854        }
855
856        return dwImageSize;
857}
858
Note: See TracBrowser for help on using the repository browser.