Project

General

Profile

Support Request #7982 » DSInput.cpp

adtf-device-toolbox 3.0.0 - hidden, 2019-08-01 11:09

 
1
/**
2
 *
3
 * Direct show input.
4
 *
5
 * @file
6
 * Copyright © Audi Electronics Venture GmbH. All rights reserved
7
 *
8
 * $Author: voigtlpi $
9
 * $Date: 2016-06-30 10:51:16 +0200 (Do, 30 Jun 2016) $
10
 * $Revision: 58032 $
11
 *
12
 * @remarks
13
 *
14
 */
15

    
16

    
17
#include "./dsvideo.h"
18
//#include <atlconv.h>
19

    
20

    
21
#define RELEASE_IF_NOT_NULL(pIObj) if ((pIObj)!=NULL) { (pIObj)->Release(); (pIObj)=NULL; }
22

    
23
//*****************************************************************************
24
#define SET_STREAM_CONFIGURATION 1
25

    
26
tInt cDSInput::m_nCOMIntances = 0;
27

    
28
//*****************************************************************************
29
adtf_util::cString cDSInput::GetDSError(HRESULT hResult)
30
{
31
    tChar szMsg[1024];
32
    AMGetErrorText(hResult, szMsg, sizeof(szMsg));
33

    
34
    return adtf_util::cString(szMsg);
35
}
36

    
37
//*****************************************************************************
38
cDSInput::cDSInput()
39
{
40
   // ::CoInitialize(NULL);
41

    
42
    m_hWnd                       = NULL;
43
    m_pGraph                     = NULL;
44
    m_pMediaControl              = NULL;
45
    m_pEvent                     = NULL;
46
    m_pRenderer                  = NULL;
47
    m_psStreamEventSink          = NULL;
48
    m_pCaptureGraphBuilder       = NULL;
49
    m_sBitmapFormat.m_nPaletteSize = 0;
50
    m_pPalette                   = NULL;
51
    m_pGreyscalePalette          = NULL;
52
    m_nAvgTimePerFrame           = 0;
53
    m_bFormatChanged             = tTrue;
54
    m_bFlipVertical              = tFalse;
55
}
56

    
57
//*****************************************************************************
58
cDSInput::~cDSInput()
59
{
60
    Stop();
61

    
62
    Release();
63

    
64
    //::CoUninitialize();
65
}
66

    
67
//*****************************************************************************
68
bool cDSInput::Release()
69
{
70
    CleanUp();
71

    
72
    if (m_nCOMIntances > 0)
73
    {
74
        m_nCOMIntances--;
75
        if (m_nCOMIntances == 0)
76
        {
77
            ::CoUninitialize();
78
            m_nCOMIntances = 0;
79
        }
80
    }
81

    
82
    return true;
83
}
84

    
85
//*****************************************************************************
86
bool cDSInput::Open(const char* strDeviceName,
87
                    HWND hWnd,
88
                    IDSStreamEventSink* psEventSink,
89
                    tDeviceConfig* pDeviceConfig,
90
                    int nGraphEventMsg,
91
                    HRESULT* phr)
92
{
93

    
94
    if (m_nCOMIntances <= 0)
95
    {
96
        ::CoInitialize(NULL);
97
        m_nCOMIntances++;
98
    }
99

    
100
    HRESULT hr = S_OK;
101

    
102
    m_nRequestedSubFormat = pDeviceConfig->nSubFormat;
103
    m_nSubFormatIdx = 0;
104
    m_sRequestedFormat = pDeviceConfig->sBitmapFormat;
105

    
106

    
107
    if (m_sRequestedFormat.m_strFormatName == ADTF_IMAGE_FORMAT(RGB_8))
108
    {
109
        m_RequestedSubtype = MEDIASUBTYPE_RGB8;
110
    }
111
    else if (m_sRequestedFormat.m_strFormatName == ADTF_IMAGE_FORMAT(RGB_555))
112
    {
113
        m_RequestedSubtype = MEDIASUBTYPE_RGB555;
114
    }
115
    else if (m_sRequestedFormat.m_strFormatName == ADTF_IMAGE_FORMAT(RGB_565))
116
    {
117
        m_RequestedSubtype = MEDIASUBTYPE_RGB565;
118
    }
119
    else if (m_sRequestedFormat.m_strFormatName == ADTF_IMAGE_FORMAT(BGR_24)
120
        || m_sRequestedFormat.m_strFormatName == ADTF_IMAGE_FORMAT(RGB_24))
121
    {
122
        m_RequestedSubtype = MEDIASUBTYPE_RGB24;
123
    }
124
    else if (m_sRequestedFormat.m_strFormatName == ADTF_IMAGE_FORMAT(BGR_32)
125
             || m_sRequestedFormat.m_strFormatName == ADTF_IMAGE_FORMAT(RGB_32))
126
    {
127
        m_RequestedSubtype = MEDIASUBTYPE_RGB32;
128
    }
129
    else
130
    {
131
        memset(&m_RequestedSubtype, 0, sizeof(m_RequestedSubtype));
132
    }
133
    pDeviceConfig->sBitmapFormat.m_nBitsPerPixel = adtf::streaming::stream_image_format_get_generic_pixel_size(pDeviceConfig->sBitmapFormat);
134

    
135
    m_sRequestedFormat = pDeviceConfig->sBitmapFormat;
136

    
137
    m_bFormatChanged = tTrue;
138

    
139
    if (nGraphEventMsg == 0)
140
    {
141
        nGraphEventMsg = WM_USER + 0x123;
142
    }
143

    
144
    m_psStreamEventSink = psEventSink;
145

    
146
    m_hWnd = hWnd;
147

    
148
    if (m_hWnd == NULL)
149
    {
150
        if (!m_oBlindWnd.Create(this, nGraphEventMsg))
151
        {
152
            return false;
153
        }
154

    
155
        m_hWnd = m_oBlindWnd.GetHandle();
156
    }
157

    
158
    IBaseFilter* pSourceFilter = NULL;
159

    
160
    ::IPin* pPinSource_Output = NULL;
161
    ::IPin* pPinRenderer_Input = NULL;
162

    
163
    bool l_bFailure = false;
164

    
165
    // filter graph / graph builder
166
    hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC, IID_IFilterGraph2, (void **)&m_pGraph);
167
    if (FAILED(hr))
168
    {
169
        LOG_ERROR(GetDSError(hr));
170
        l_bFailure = true;
171
    }
172

    
173
    if (!l_bFailure)
174
    {
175
        hr = CoCreateInstance(CLSID_CaptureGraphBuilder2,
176
                              NULL, CLSCTX_INPROC,
177
                              IID_ICaptureGraphBuilder2,
178
                              (void **) &m_pCaptureGraphBuilder);
179
    }
180

    
181
    if (FAILED(hr))
182
    {
183
        LOG_ERROR(GetDSError(hr));
184
        l_bFailure = true;
185
    }
186

    
187
    if (!l_bFailure)
188
    {
189
        hr = m_pCaptureGraphBuilder->SetFiltergraph(m_pGraph);
190
        if (FAILED(hr))
191
        {
192
            LOG_ERROR(GetDSError(hr));
193
            l_bFailure = true;
194
        }
195
    }
196

    
197
    m_bMonikerSetToGraph = tFalse;
198
    if (!l_bFailure)
199
    {
200
        hr = FindCaptureDevice(strDeviceName, &pSourceFilter);
201
        if (hr != S_OK)
202
        {
203
            // Don't display a message because FindCaptureDevice will handle it
204
            l_bFailure = true;
205
        }
206
    }
207

    
208
    if (!l_bFailure && !m_bMonikerSetToGraph)
209
    {
210
        hr = m_pGraph->AddFilter(pSourceFilter, L"VideoCapture");
211
        if (FAILED(hr))
212
        {
213
            /*
214
            DisplayText(TEXT("Couldn't add the capture filter to the graph!  hr=0x%x\r\n\r\n") 
215
                TEXT("If you have a working video capture device, please make sure\r\n")
216
                TEXT("that it is connected and is not being used by another application.\r\n\r\n")
217
                TEXT("The sample will now close."), hr);
218
            */
219
            LOG_ERROR(GetDSError(hr));
220
            l_bFailure = true;
221
        }
222
    }
223
    else if (m_bMonikerSetToGraph)
224
    {
225
        //to to set name to filter
226
    }
227

    
228
    if (!l_bFailure)
229
    {
230
        #if (SET_STREAM_CONFIGURATION)
231
            hr = S_OK;
232
            tResult nErr = ConfigureCaptureDevice(pSourceFilter, pDeviceConfig, &hr);
233
            if (IS_FAILED(nErr))
234
            {
235
                LOG_ERROR(GetDSError(hr));
236
                l_bFailure = true;
237
            }
238
        #endif
239
    }
240

    
241
    // renderer
242
    if (!l_bFailure)
243
    {
244
        m_pRenderer = new cDSRenderer(this);
245
        if (m_pRenderer == NULL)
246
        {
247
            l_bFailure = true;
248
        }
249
    }
250

    
251
    if (!l_bFailure)
252
    {
253
        hr = m_pGraph->AddFilter(m_pRenderer, L"ADTFDefaultRenderer");
254
        if (FAILED(hr))
255
        {
256
            LOG_ERROR(GetDSError(hr));
257
            l_bFailure = true;
258
        }
259
        else
260
        {
261
            pPinRenderer_Input = GetPin(m_pRenderer, PINDIR_INPUT);
262
            if (pPinRenderer_Input == NULL)
263
            {
264
                l_bFailure = true;
265
            }
266
        }
267
    }
268

    
269
    if (!l_bFailure)
270
    {
271
        // Render the capture or preview  pin on the video capture filter
272
        hr = m_pCaptureGraphBuilder->RenderStream (&PIN_CATEGORY_CAPTURE,
273
                                                   &MEDIATYPE_Video,
274
                                                   pSourceFilter,
275
                                                   NULL,
276
                                                   m_pRenderer);
277
        if (FAILED(hr))
278
        {
279
            hr = m_pCaptureGraphBuilder->RenderStream (&PIN_CATEGORY_PREVIEW,
280
                                                       &MEDIATYPE_Video,
281
                                                       pSourceFilter,
282
                                                       NULL,
283
                                                       m_pRenderer);
284
            if (FAILED(hr))
285
            {
286
                // device may already be in use by another application
287
                LOG_ERROR(GetDSError(hr));
288
                l_bFailure = true;
289
            }
290
        }
291
    }
292

    
293
    if (!l_bFailure)
294
    {
295
        // get controller interfaces
296
        m_pGraph->QueryInterface(IID_IMediaEventEx, (void **)&m_pEvent);
297
        if (m_pEvent != NULL)
298
        {
299
            m_pEvent->SetNotifyWindow((OAHWND)m_hWnd, nGraphEventMsg, 0);
300
        }
301

    
302
    }
303

    
304
    RELEASE_IF_NOT_NULL(pPinSource_Output);
305
    RELEASE_IF_NOT_NULL(pPinRenderer_Input);
306
    RELEASE_IF_NOT_NULL(pSourceFilter);
307

    
308
    // get media control interface
309
    if (!l_bFailure)
310
    {
311
        hr = m_pGraph->QueryInterface(IID_IMediaControl, (void **)&m_pMediaControl);
312
        if (FAILED(hr))
313
        {
314
            LOG_ERROR(GetDSError(hr));
315
            l_bFailure = true;
316
        }
317
    }
318

    
319
    if (phr != NULL)
320
    {
321
        *phr = hr;
322
    }
323

    
324
    if (l_bFailure)
325
    {
326
        Release();
327
        
328
        return false;
329
    }
330

    
331
    return true;
332
}
333

    
334
::IPin* cDSInput::GetPin(IBaseFilter *pFilter, PIN_DIRECTION PinDir)
335
{
336
    BOOL bFound = FALSE;
337
    IEnumPins *pEnum;
338
    ::IPin *pPin;
339

    
340
    HRESULT hr = pFilter->EnumPins(&pEnum);
341
    if (FAILED(hr))
342
    {
343
        return NULL;
344
    }
345

    
346
    while(pEnum->Next(1, &pPin, 0) == S_OK)
347
    {
348
        PIN_DIRECTION PinDirThis;
349
        pPin->QueryDirection(&PinDirThis);
350
        if (bFound = (PinDir == PinDirThis))
351
            break;
352
        pPin->Release();
353
    }
354

    
355
    pEnum->Release();
356
    return (bFound ? pPin : NULL);
357
}
358

    
359
//*****************************************************************************
360
HRESULT cDSInput::FindCaptureDevice(const char* strDeviceName, IBaseFilter ** ppSrcFilter)
361
{
362
    IBaseFilter* pSrc = NULL;
363
    IMoniker* pMoniker = NULL;
364
    IEnumMoniker* pClassEnum = NULL;
365
    ICreateDevEnum* pDevEnum = NULL;
366
    bool l_bFailure = false;
367
    char strDeviceDisplayName[512];
368

    
369
    if (ppSrcFilter == NULL || strDeviceName == NULL)
370
    {
371
        return E_POINTER;
372
    }
373

    
374
    *ppSrcFilter = NULL;
375

    
376
    adtf_util::cString strDeviceSpec(strDeviceName);
377
    strDeviceSpec.Trim();
378
    strDeviceSpec.ToLower();
379
    tUInt32 nNameSeparator = (tUInt32)strDeviceSpec.Find(':');
380
    if (nNameSeparator != UINT32_MAX)
381
    {
382
        strDeviceSpec.Delete(0, nNameSeparator + 1);
383
    }
384

    
385
    tInt nDeviceNum = -1;
386
    if (strDeviceSpec.Compare("default") == 0)
387
    {
388
        nDeviceNum = 1;
389
        strDeviceSpec = "";
390
    }
391
    else
392
    {
393
        nDeviceNum = atoi(strDeviceSpec.GetPtr());
394
        if (nDeviceNum == 0 && strDeviceSpec.Compare("0") != 0)
395
        {
396
            nDeviceNum = -1;
397
        }
398
        else
399
        {
400
            strDeviceSpec = "";
401
        }
402
    }
403

    
404
    // Create the system device enumerator
405
    HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum,
406
                          NULL,
407
                          CLSCTX_INPROC,
408
                          IID_ICreateDevEnum,
409
                          (void **) &pDevEnum);
410
    if (FAILED(hr))
411
    {
412
        LOG_ERROR(GetDSError(hr));
413
        l_bFailure = true;
414
    }
415

    
416
    if (!l_bFailure)
417
    {
418
        // Create an enumerator for the video capture devices
419
        hr = pDevEnum->CreateClassEnumerator (CLSID_VideoInputDeviceCategory,
420
                                              &pClassEnum,
421
                                              0);
422
        if (FAILED(hr))
423
        {
424
            LOG_ERROR(GetDSError(hr));
425
            l_bFailure = true;
426
        }
427
    }
428

    
429
    if (!l_bFailure)
430
    {
431
        // If there are no enumerators for the requested type, then 
432
        // CreateClassEnumerator will succeed, but pClassEnum will be NULL.
433
        if (pClassEnum == NULL)
434
        {
435
            LOG_ERROR("No video capture device was detected.");
436
            l_bFailure = true;
437
            hr = ERROR_NOT_READY;
438
        }
439
    }
440

    
441
    bool bDeviceFound = false;
442

    
443
    if (!l_bFailure)
444
    {
445
        // Process the device list.
446
        // Note that if the Next() call succeeds but there are no monikers,
447
        // it will return S_FALSE (which is not a failure).  Therefore, we
448
        // check that the return code is S_OK instead of using SUCCEEDED() macro.
449
       
450
        ULONG cFetched;
451
        pClassEnum->Reset();
452

    
453
        tInt nDeviceIdx = 1;
454
        LPOLESTR wstrMonikerName = NULL;
455
        
456
        while (!bDeviceFound  &&  (S_OK == pClassEnum->Next (1, &pMoniker, &cFetched)))
457
        {
458
            // get a human-readable string for evaluation during debugging
459
            strcpy_s(strDeviceDisplayName, 512, "Failed to read friendly name!");
460

    
461
            IPropertyBag *pBag = NULL;
462
            hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pBag);
463
            if (SUCCEEDED(hr))
464
            {
465
                VARIANT var;
466
                VariantInit(&var);
467
                hr = pBag->Read(L"FriendlyName", &var, NULL);
468
                if (SUCCEEDED(hr))
469
                {
470
                    WideCharToMultiByte(CP_ACP, 0, var.bstrVal, -1,
471
                                        strDeviceDisplayName, sizeof(strDeviceDisplayName),
472
                                        NULL, NULL);
473
                }
474

    
475
                VariantClear(&var);
476
                pBag->Release();
477
            }
478

    
479
            LOG_INFO(adtf_util::cString::Format("Found device #%d: \"%s\"", nDeviceIdx, strDeviceDisplayName));
480
 
481
            if (!strDeviceSpec.IsEmpty())
482
            {
483
                adtf_util::cString strFoundDeviceNameLowerCase(strDeviceDisplayName);
484
                strFoundDeviceNameLowerCase.ToLower();
485
                if (strFoundDeviceNameLowerCase.Find(strDeviceSpec) != -1)
486
                {
487
                    // found device specified by name
488
                    bDeviceFound = tTrue;
489
                }
490
            }
491
            else if (nDeviceNum == nDeviceIdx)
492
            {
493
                // found device specified by number
494
                bDeviceFound = tTrue;
495
            }
496

    
497
            if (bDeviceFound)
498
            {
499
                hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**) &pSrc);
500
                if (FAILED(hr))
501
                {
502
                    //try to add with moniker to graph
503
                    hr = m_pGraph->AddSourceFilterForMoniker(pMoniker, 0, L"VideoCapture", &pSrc);
504
                    if (FAILED(hr))
505
                    {
506
                        LOG_ERROR("Device not ready");
507
                        l_bFailure = tTrue;
508
                    }
509
                }
510
                if (!l_bFailure)
511
                {
512
                    LOG_INFO(adtf_util::cString::Format("Using device #%d: \"%s\"",
513
                                             nDeviceIdx, strDeviceDisplayName));
514
                }
515
            }
516

    
517
            nDeviceIdx++;
518
            RELEASE_IF_NOT_NULL(pMoniker);
519
        }
520
    }
521

    
522
    if (!l_bFailure && !bDeviceFound)
523
    {
524
        LOG_ERROR("Device not found \"" + adtf_util::cString(strDeviceName) + "\"");
525
        l_bFailure = true;
526
        hr = ERROR_BAD_UNIT;
527
    }
528

    
529
    RELEASE_IF_NOT_NULL(pMoniker);
530
    RELEASE_IF_NOT_NULL(pClassEnum);
531
    RELEASE_IF_NOT_NULL(pDevEnum);
532

    
533
    // Copy the found filter pointer to the output parameter.
534
    // Do NOT Release() the reference, since it will still be used
535
    // by the calling function.
536
    if (!l_bFailure)
537
    {
538
        *ppSrcFilter = pSrc;
539
    }
540

    
541
    return hr;
542
}
543

    
544
//*****************************************************************************
545
bool cDSInput::Play()
546
{
547
    m_bFormatChanged = tTrue;
548
    
549
    // Run the graph
550
    IVideoWindow *pVidWin = NULL;
551

    
552
    if (m_pMediaControl != NULL)
553
    {
554
        OAFilterState eFilterState ;
555
        HRESULT hr = m_pMediaControl->GetState(INFINITE, &eFilterState );
556
        if (FAILED(hr))
557
        {
558
            return false;
559
        }
560

    
561
        if (eFilterState == State_Running)
562
        {
563
            hr = m_pMediaControl->Stop();
564
        }
565

    
566
        if (m_pEvent != NULL)
567
        {
568
            long levCode = 0;
569
            m_pEvent->WaitForCompletion(INFINITE, &levCode);
570
        }
571

    
572
        m_pMediaControl->Run();
573

    
574
        return true;
575
    }
576

    
577
    return false;
578
}
579

    
580
//*****************************************************************************
581
bool cDSInput::Pause()
582
{
583
    if (m_pMediaControl != NULL)
584
    {
585
        m_pMediaControl->Pause();
586

    
587
        return true;
588
    }
589

    
590
    return false;
591
}
592

    
593
//*****************************************************************************
594
bool cDSInput::Stop()
595
{
596
    if (m_pMediaControl != NULL)
597
    {
598
        LONGLONG pos = 0;
599
        HRESULT hr = m_pMediaControl->Stop();
600
 
601
        if (m_pEvent != NULL)
602
        {
603
            long levCode = 0;
604
            m_pEvent->WaitForCompletion(INFINITE, &levCode);
605
        }
606

    
607
        return true;
608
    }
609

    
610
    return false;
611
}
612

    
613
//*****************************************************************************
614
void cDSInput::CleanUp()
615
{
616
    long levCode = 0;
617

    
618
    Stop();
619

    
620
    if (m_pEvent != NULL)
621
    {
622
        m_pEvent->WaitForCompletion(INFINITE, &levCode);
623
    }
624

    
625
    if (m_pMediaControl != NULL)
626
    {
627
        m_pMediaControl->Release();
628
        m_pMediaControl = NULL;
629
    }
630

    
631
    if (m_pEvent != NULL)
632
    {
633
        m_pEvent->Release();
634
        m_pEvent = NULL;
635
    }
636

    
637
    if (m_pRenderer != NULL)
638
    {
639
        // delete m_pRenderer; --> don't delete: Graph->Release() will do that!
640
        m_pRenderer = NULL;
641
    }
642

    
643
    if (m_pCaptureGraphBuilder != NULL)
644
    {
645
        m_pCaptureGraphBuilder->Release();
646
        m_pCaptureGraphBuilder = NULL;
647
    }
648
    if (m_pGraph != NULL)
649
    {
650
        m_pGraph->Release();
651
        m_pGraph = NULL;
652
    }
653

    
654
    m_oBlindWnd.Release();
655

    
656
    FreePalette();
657
}
658

    
659
//*****************************************************************************
660
bool cDSInput::UpdateStatus()
661
{
662
    if (m_pEvent == NULL)
663
    {
664
        return FALSE;
665
    }
666

    
667
    long lEventCode = 0;
668
    LONG_PTR lParam1 = 0;
669
    LONG_PTR lParam2 = 0;
670

    
671
    HRESULT hr = m_pEvent->GetEvent(&lEventCode, &lParam1, &lParam2, INFINITE);
672
    if (FAILED(hr))
673
    {
674
        return false;
675
    }
676

    
677
    if (lEventCode == EC_COMPLETE)
678
    {
679
        Stop();
680
    }
681
    else if (lEventCode == EC_USERABORT)
682
    {
683
        Stop();
684
    }
685

    
686
    if (m_psStreamEventSink != NULL)
687
    {
688
        m_psStreamEventSink->OnStreamEvent(lEventCode, (tInt)lParam1, (tInt)lParam2);
689
    }
690

    
691
    m_pEvent->FreeEventParams(lEventCode, lParam1, lParam2);
692

    
693
    return true;
694
}
695

    
696
//*****************************************************************************
697
HRESULT cDSInput::GetEvent(long *lEventCode, long *lParam1, long *lParam2, long msTimeout)
698
{
699
    if (m_pEvent == NULL)
700
    {
701
        return E_NOTIMPL;
702
    }
703

    
704
    LONG_PTR* lpParam1 = (LONG_PTR*)&lParam1;
705
    LONG_PTR* lpParam2 = (LONG_PTR*)&lParam2;
706

    
707
    HRESULT hr = m_pEvent->GetEvent(lEventCode, lpParam1, lpParam2, msTimeout);
708
    if (SUCCEEDED(hr))
709
    {
710
        m_pEvent->FreeEventParams(*lEventCode, *lParam1, *lParam2);
711
    }
712

    
713
    return hr;
714
}
715

    
716
//*****************************************************************************
717
void cDSInput::OnGraphEvent()
718
{
719
    UpdateStatus();
720
}
721

    
722
//*****************************************************************************
723
HWND cDSInput::GetHWnd()
724
{
725
    return m_hWnd;
726
}
727

    
728
//*****************************************************************************
729
bool cDSInput::DoModal()
730
{
731
    return m_oBlindWnd.DoModal();
732
}
733

    
734
//*****************************************************************************
735
bool cDSInput::ProcessMessages(int nWait)
736
{
737
    return m_oBlindWnd.ProcessMessages(nWait);
738
}
739

    
740
//*****************************************************************************
741
HRESULT cDSInput::OnQueryMediaType(const CMediaType* pMediaType)
742
{
743
    if (pMediaType == NULL)
744
    {
745
        return E_POINTER;
746
    }
747

    
748
    if (pMediaType->majortype != MEDIATYPE_Video)
749
    {
750
        return S_FALSE;
751
    }
752

    
753
    if (pMediaType->subtype != MEDIASUBTYPE_RGB8   &&
754
             pMediaType->subtype != MEDIASUBTYPE_RGB555 &&
755
             pMediaType->subtype != MEDIASUBTYPE_RGB565 &&
756
             pMediaType->subtype != MEDIASUBTYPE_RGB24  &&
757
             pMediaType->subtype != MEDIASUBTYPE_RGB32)
758
    {
759
        // none of the supported formats is available
760
        return S_FALSE;
761
    }
762

    
763
    const BITMAPINFOHEADER* pBitmapInfoHeader = NULL;
764
    const VIDEOINFOHEADER*  pInfo             = NULL;
765
    const VIDEOINFOHEADER2* pInfo2            = NULL;
766

    
767
    if (pMediaType->formattype == FORMAT_VideoInfo2)
768
    {
769
        pInfo2 = (VIDEOINFOHEADER2*) pMediaType->pbFormat;
770
        pBitmapInfoHeader = &pInfo2->bmiHeader;
771
    }
772
    else if (pMediaType->formattype == FORMAT_VideoInfo)
773
    {
774
        pInfo = (VIDEOINFOHEADER*) pMediaType->pbFormat;
775
        pBitmapInfoHeader = &pInfo->bmiHeader;
776
    }
777
    else
778
    {
779
        return S_FALSE;
780
    }
781

    
782
    // check sub-format idx if specified
783
    m_nSubFormatIdx++;
784
    if (m_nRequestedSubFormat != 0 &&
785
        m_nSubFormatIdx != m_nRequestedSubFormat)
786
    {
787
        return S_FALSE;
788
    }
789

    
790
    return S_OK;
791
}
792

    
793
//*****************************************************************************
794
HRESULT cDSInput::OnSetMediaType(const CMediaType* pMediaType)
795
{
796
    if (pMediaType == NULL)
797
    {
798
        return E_POINTER;
799
    }
800

    
801
    if (IS_FAILED(UpdateFormat(pMediaType)))
802
    {
803
        return S_FALSE;
804
    }
805

    
806
    return S_OK;
807
}
808

    
809
tResult cDSInput::ConfigureCaptureDevice(IBaseFilter* pObject, 
810
                                         tDeviceConfig* pDeviceConfig,
811
                                         HRESULT* phr)
812
{
813
    LOG_INFO("ConfigureCaptureDevice start");
814

    
815
    RETURN_IF_POINTER_NULL(pDeviceConfig);
816

    
817
    IAMStreamConfig* pStreamConfig = NULL;
818
    HRESULT hr = m_pCaptureGraphBuilder->FindInterface(&PIN_CATEGORY_CAPTURE,
819
                                                       NULL,
820
                                                       pObject,
821
                                                       IID_IAMStreamConfig,
822
                                                       (tVoid**) &pStreamConfig);
823
    if (FAILED(hr))
824
    {
825
        if (phr != NULL)
826
        {
827
            *phr = hr;
828
        }
829
        LOG_ERROR(GetDSError(hr));
830
        LOG_ERROR("FindInterface failed");
831
        RETURN_ERROR(ERR_NOT_SUPPORTED);
832
    }
833

    
834
    VIDEO_STREAM_CONFIG_CAPS sConfigCaps;
835
    memset(&sConfigCaps, 0, sizeof(sConfigCaps));
836

    
837
    int iCount = 0;
838
    int iSize = 0;
839
    hr = pStreamConfig->GetNumberOfCapabilities(&iCount, &iSize);
840
    if (sizeof(sConfigCaps) != iSize)
841
    {
842
        pStreamConfig->Release();
843
        if (phr != NULL)
844
        {
845
            *phr = hr;
846
        }
847
        LOG_ERROR(GetDSError(hr));
848
        LOG_ERROR("The video stream capture config that will be returned has not the right size! "
849
                  "Can not ask for VIDEO_STREAM_CONFIG_CAPS in DirectShow (capabilities)");
850
        RETURN_ERROR(ERR_FAILED);
851
    }
852

    
853
    AM_MEDIA_TYPE*    pMediaType        = NULL;
854
    VIDEOINFOHEADER*  pInfo             = NULL;
855
    VIDEOINFOHEADER2* pInfo2            = NULL;
856
    BITMAPINFOHEADER* pBitmapInfoHeader = NULL;
857

    
858
    LOG_INFO(adtf_util::cString::Format("Iterate capabilities. Count == %d", iCount));
859
    for (tInt nIdx = 0;  nIdx < iCount;  nIdx++)
860
    {
861
        hr = pStreamConfig->GetStreamCaps(nIdx, &pMediaType, reinterpret_cast<BYTE*>(&sConfigCaps));
862
        if (FAILED(hr))
863
        {
864
            LOG_ERROR(GetDSError(hr));
865
            LOG_ERROR("Could not find valid stream type");
866
            pStreamConfig->Release();
867
            if (phr != NULL)
868
            {
869
                *phr = hr;
870
            }
871
            RETURN_ERROR(ERR_NOT_SUPPORTED);
872
        }
873

    
874
        if ((pMediaType->formattype == FORMAT_VideoInfo2 ||
875
             pMediaType->formattype == FORMAT_VideoInfo) &&
876
            (pMediaType->subtype == MEDIASUBTYPE_RGB8    ||
877
             pMediaType->subtype == MEDIASUBTYPE_RGB555  ||
878
             pMediaType->subtype == MEDIASUBTYPE_RGB565  ||
879
             pMediaType->subtype == MEDIASUBTYPE_RGB24   ||
880
             pMediaType->subtype == MEDIASUBTYPE_RGB32   ||
881
             pMediaType->subtype == MEDIASUBTYPE_MJPG    ))
882
        {
883
            LOG_INFO("MediaType found!");
884
            break;
885
        }
886
    }
887

    
888
    if (pMediaType->formattype == FORMAT_VideoInfo2)
889
    {
890
        pInfo2 = (VIDEOINFOHEADER2*) pMediaType->pbFormat;
891
        pInfo2->AvgTimePerFrame = (10000000) / (tInt64) pDeviceConfig->nFrameRate;
892
        pBitmapInfoHeader = &pInfo2->bmiHeader;
893
        LOG_INFO("FORMAT_VideoInfo2");
894
    }
895
    else if (pMediaType->formattype == FORMAT_VideoInfo)
896
    {
897
        pInfo = (VIDEOINFOHEADER*) pMediaType->pbFormat;
898
        pInfo->AvgTimePerFrame = (10000000) / (tInt64) pDeviceConfig->nFrameRate;
899
        pBitmapInfoHeader = &pInfo->bmiHeader;
900
        LOG_INFO("FORMAT_VideoInfo (%dx%d)", pInfo->bmiHeader.biWidth, pInfo->bmiHeader.biHeight);
901
    }
902
    else if (pMediaType->formattype == FORMAT_MPEG2Video)
903
    {
904
        LOG_ERROR("unhandled formattype: FORMAT_MPEG2Video");
905
        RETURN_ERROR(ERR_NOT_SUPPORTED);
906
    }
907
    else if (pMediaType->formattype == FORMAT_None)
908
    {
909
        LOG_ERROR("unhandled formattype: FORMAT_None");
910
        RETURN_ERROR(ERR_NOT_SUPPORTED);
911
    }
912
    else if (pMediaType->formattype == FORMAT_DolbyAC3)
913
    {
914
        LOG_ERROR("unhandled formattype: FORMAT_DolbyAC3");
915
        RETURN_ERROR(ERR_NOT_SUPPORTED);
916
    }
917
    else if (pMediaType->formattype == FORMAT_MPEG2Audio)
918
    {
919
        LOG_ERROR("unhandled formattype: FORMAT_MPEG2Audio");
920
        RETURN_ERROR(ERR_NOT_SUPPORTED);
921
    }
922
    else if (pMediaType->formattype == FORMAT_DVD_LPCMAudio)
923
    {
924
        LOG_ERROR("unhandled formattype: FORMAT_DVD_LPCMAudio");
925
        RETURN_ERROR(ERR_NOT_SUPPORTED);
926
    }
927
    else
928
    {
929
      //  USES_CONVERSION;
930
        OLECHAR* bstrGuid;
931
        StringFromCLSID(pMediaType->formattype, &bstrGuid);
932

    
933
       // LOG_ERROR(adtf_util::cString::Format("unknown formattype: %s", W2A(bstrGuid)).GetPtr());
934
        LOG_ERROR(adtf_util::cString::Format("unknown formattype: %s", (bstrGuid)).GetPtr());
935
        ::CoTaskMemFree(bstrGuid);
936
        RETURN_ERROR(ERR_UNKNOWN_FORMAT);
937
    }
938

    
939
    LOG_INFO(adtf_util::cString::Format("BitmapFormat.Width = %d", pDeviceConfig->sBitmapFormat.m_ui32Width));
940
    if (pDeviceConfig->sBitmapFormat.m_ui32Width != 0)
941
    {
942
        pBitmapInfoHeader->biWidth = pDeviceConfig->sBitmapFormat.m_ui32Width;
943
    }
944

    
945
    LOG_INFO(adtf_util::cString::Format("BitmapFormat.Height = %d", pDeviceConfig->sBitmapFormat.m_ui32Height));
946
    if (pDeviceConfig->sBitmapFormat.m_ui32Height != 0)
947
    {
948
        pBitmapInfoHeader->biHeight = pDeviceConfig->sBitmapFormat.m_ui32Height;
949
    }
950

    
951
    
952
    //pMediaType->subtype = m_RequestedSubtype;
953
    if (pDeviceConfig->sBitmapFormat.m_nBitsPerPixel > 0)
954
    {
955
        pBitmapInfoHeader->biBitCount = (WORD)pDeviceConfig->sBitmapFormat.m_nBitsPerPixel;
956
        if (pBitmapInfoHeader->biBitCount <= 8)
957
        {
958
            pBitmapInfoHeader->biClrUsed = 0;
959
            pBitmapInfoHeader->biClrImportant = 0;
960
        }
961
    }
962

    
963
    hr = pStreamConfig->SetFormat(pMediaType);
964

    
965
    if (FAILED(hr))
966
    {
967
        if (phr != NULL)
968
        {
969
            *phr = hr;
970
        }
971
        LOG_ERROR(GetDSError(hr));
972
        LOG_ERROR("SetFormat failed (%dx%d)", pInfo->bmiHeader.biWidth, pInfo->bmiHeader.biHeight);
973
    }
974

    
975
    DeleteMediaType(pMediaType);
976
    pStreamConfig->Release();
977

    
978
    LOG_INFO("ConfigureCaptureDevice end");
979
    RETURN_NOERROR;
980
}
981

    
982
//*****************************************************************************
983
tResult cDSInput::UpdateFormat(const AM_MEDIA_TYPE* pMediaType)
984
{
985
    RETURN_IF_POINTER_NULL(pMediaType);
986

    
987
    if (pMediaType->majortype != MEDIATYPE_Video)
988
    {
989
        RETURN_ERROR(ERR_INVALID_ARG);
990
    }
991

    
992
    if (pMediaType->subtype != MEDIASUBTYPE_RGB8  &&
993
        pMediaType->subtype != MEDIASUBTYPE_RGB555 &&
994
        pMediaType->subtype != MEDIASUBTYPE_RGB565 &&
995
        pMediaType->subtype != MEDIASUBTYPE_RGB24 &&
996
        pMediaType->subtype != MEDIASUBTYPE_RGB32)
997
    {
998
        RETURN_ERROR(ERR_NOT_SUPPORTED);
999
    }
1000

    
1001
    BITMAPINFOHEADER* pBitmapInfoHeader = NULL;
1002
    RGBQUAD* pPalette                   = NULL;
1003
    long nPaletteSize                   = 0;
1004
    const tChar* strPixelFormat                 = ADTF_IMAGE_FORMAT(BGR_32);
1005

    
1006
    if (pMediaType->subtype == MEDIASUBTYPE_RGB8)
1007
    {
1008
        strPixelFormat = ADTF_IMAGE_FORMAT(RGB_8);
1009
    }
1010
    else if (pMediaType->subtype == MEDIASUBTYPE_RGB555)
1011
    {
1012
        strPixelFormat = ADTF_IMAGE_FORMAT(RGB_555);
1013
    }
1014
    else if (pMediaType->subtype == MEDIASUBTYPE_RGB565)
1015
    {
1016
        strPixelFormat = ADTF_IMAGE_FORMAT(RGB_565);
1017
    }
1018
    else if (pMediaType->subtype == MEDIASUBTYPE_RGB24)
1019
    {
1020
        strPixelFormat = ADTF_IMAGE_FORMAT(BGR_24);
1021
    }
1022
    else if (pMediaType->subtype == MEDIASUBTYPE_RGB32)
1023
    {
1024
        strPixelFormat = ADTF_IMAGE_FORMAT(BGR_32);
1025
    }
1026

    
1027
    if (pMediaType->formattype == FORMAT_VideoInfo2 &&
1028
        pMediaType->cbFormat >= sizeof(VIDEOINFOHEADER2)) 
1029
    {
1030
        VIDEOINFOHEADER2* pInfo = (VIDEOINFOHEADER2*) pMediaType->pbFormat;
1031
        
1032
        m_nAvgTimePerFrame = pInfo->AvgTimePerFrame;
1033

    
1034
        pBitmapInfoHeader = &pInfo->bmiHeader;
1035

    
1036
        if (pBitmapInfoHeader->biBitCount <= 8 && pMediaType->cbFormat > sizeof(VIDEOINFOHEADER2))
1037
        {
1038
            pPalette     = (RGBQUAD*) (((BYTE*) pMediaType->pbFormat) + sizeof(VIDEOINFOHEADER2));
1039
            nPaletteSize = (pMediaType->cbFormat - sizeof(VIDEOINFOHEADER2)) / sizeof(RGBQUAD);
1040
        }
1041

    
1042
        if (pBitmapInfoHeader->biSizeImage == 0)
1043
        {
1044
            pBitmapInfoHeader->biSizeImage = pMediaType->lSampleSize;
1045
        }
1046

    
1047
        RETURN_IF_FAILED(UpdateFormat(pBitmapInfoHeader, pPalette, nPaletteSize, strPixelFormat));
1048
    }
1049
    else if (pMediaType->formattype == FORMAT_VideoInfo &&
1050
             pMediaType->cbFormat >= sizeof(VIDEOINFOHEADER)) 
1051
    {
1052
        VIDEOINFOHEADER* pInfo = (VIDEOINFOHEADER*) pMediaType->pbFormat;
1053

    
1054
        m_nAvgTimePerFrame = pInfo->AvgTimePerFrame;
1055

    
1056
        pBitmapInfoHeader = &pInfo->bmiHeader;
1057

    
1058
        if (pBitmapInfoHeader->biBitCount <= 8 &&
1059
            pMediaType->cbFormat > sizeof(VIDEOINFOHEADER))
1060
        {
1061
            pPalette     = (RGBQUAD*) (((BYTE*) pMediaType->pbFormat) + sizeof(VIDEOINFOHEADER));
1062
            nPaletteSize = (pMediaType->cbFormat - sizeof(VIDEOINFOHEADER)) / sizeof(RGBQUAD);
1063
        }
1064

    
1065
        if (pBitmapInfoHeader->biSizeImage == 0)
1066
        {
1067
            pBitmapInfoHeader->biSizeImage = pMediaType->lSampleSize;
1068
        }
1069

    
1070
        RETURN_IF_FAILED(UpdateFormat(pBitmapInfoHeader, pPalette, nPaletteSize, strPixelFormat));
1071
    }
1072
    else
1073
    {
1074
        m_nAvgTimePerFrame = 25;
1075
        RETURN_IF_FAILED(UpdateFormat(pBitmapInfoHeader, pPalette, nPaletteSize, strPixelFormat));
1076
    }
1077

    
1078
    RETURN_NOERROR;
1079
}
1080

    
1081
//*****************************************************************************
1082
tResult cDSInput::UpdateFormat(BITMAPINFOHEADER* pBitmapInfoHeader,
1083
                               RGBQUAD* pPalette,
1084
                               long nPaletteSize, 
1085
                               const tChar* strPixelFormat)
1086
{
1087
    memset(&m_sBitmapFormat, 0, sizeof(m_sBitmapFormat));
1088

    
1089
    m_sBitmapFormat.m_ui32Width  = pBitmapInfoHeader->biWidth;
1090
    m_sBitmapFormat.m_ui32Height = pBitmapInfoHeader->biHeight;
1091
    if (pBitmapInfoHeader->biHeight < 0)
1092
    {
1093
        m_sBitmapFormat.m_ui32Height = -pBitmapInfoHeader->biHeight;
1094
        m_bFlipVertical = tFalse;
1095
    }
1096
    else
1097
    {
1098
        m_bFlipVertical = tTrue;
1099
    }
1100

    
1101
  //  m_sBitmapFormat.nBitsPerPixel = pBitmapInfoHeader->biBitCount;
1102
    //m_sBitmapFormat.szMaxByteSize = (pBitmapInfoHeader->biWidth * m_sBitmapFormat.nBitsPerPixel) / 8;
1103

    
1104
    m_sBitmapFormat.m_szMaxByteSize = pBitmapInfoHeader->biSizeImage;
1105

    
1106
    m_sBitmapFormat.m_strFormatName = strPixelFormat;
1107
    if (pBitmapInfoHeader->biBitCount <= 8 && nPaletteSize == 0)
1108
    {
1109
        m_sBitmapFormat.m_strFormatName = ADTF_IMAGE_FORMAT(GREYSCALE_8);
1110
    }
1111
    m_sBitmapFormat.m_nBitsPerPixel = pBitmapInfoHeader->biBitCount;
1112

    
1113
 //   RETURN_IF_FAILED(AllocPalette(nPaletteSize, tFalse));
1114

    
1115
  //  if (m_pPalette != NULL)
1116
 //   {
1117
 //       memcpy(m_pPalette, pPalette, nPaletteSize * sizeof(RGBQUAD));
1118
 //       for (tInt nIdx=0; nIdx<nPaletteSize; nIdx++)
1119
  //      {
1120
   //         m_pGreyscalePalette[nIdx] = cImage::Brightness(m_pPalette[nIdx].nRed, m_pPalette[nIdx].nGreen, m_pPalette[nIdx].nBlue);
1121
  //      }
1122
 //   }
1123

    
1124
    RETURN_NOERROR;
1125
}
1126

    
1127

    
1128
//*****************************************************************************
1129
tResult cDSInput::AllocPalette(tInt nPaletteSize, tBool bForce)
1130
{
1131
    if (nPaletteSize == m_sBitmapFormat.m_nPaletteSize &&
1132
        m_pPalette != NULL &&
1133
        !bForce)
1134
    {
1135
        RETURN_NOERROR;
1136
    }
1137

    
1138
    FreePalette();
1139

    
1140
    if (nPaletteSize > 0)
1141
    {
1142
        m_pPalette = new tColor[nPaletteSize];
1143
        if (m_pPalette == NULL)
1144
        {
1145
            RETURN_ERROR(ERR_MEMORY);
1146
        }
1147

    
1148
        m_pGreyscalePalette = new tUInt8[nPaletteSize];
1149
        if (m_pGreyscalePalette == NULL)
1150
        {
1151
            RETURN_ERROR(ERR_MEMORY);
1152
        }
1153

    
1154
        m_sBitmapFormat.m_nPaletteSize = nPaletteSize;
1155
    }
1156

    
1157
    RETURN_NOERROR;
1158
}
1159

    
1160
//*****************************************************************************
1161

    
1162
tResult cDSInput::FreePalette()
1163
{
1164
    if (m_pPalette != NULL)
1165
    {
1166
        delete [] m_pPalette;
1167
        m_pPalette = NULL;
1168
    }
1169

    
1170
    if (m_pGreyscalePalette != NULL)
1171
    {
1172
        delete [] m_pGreyscalePalette;
1173
        m_pGreyscalePalette = NULL;
1174
    }
1175

    
1176
    m_sBitmapFormat.m_nPaletteSize = 0;
1177

    
1178
    RETURN_NOERROR;
1179
}
1180

    
1181
//*****************************************************************************
1182
tInternalFormat* cDSInput::GetBitmapFormat()
1183
{
1184
    return &m_sBitmapFormat;
1185
}
1186

    
1187
//*****************************************************************************
1188
tInt64 cDSInput::GetAvgTimePerFrame()
1189
{
1190
    return m_nAvgTimePerFrame / 10;
1191
}
1192

    
1193
//*****************************************************************************
1194
HRESULT cDSInput::OnNewFrame(::IMediaSample* pMediaSample)
1195
{
1196
    tTimeStamp tmCurrent = adtf_util::cSystem::GetTime();
1197

    
1198
    HRESULT hr = S_OK;
1199

    
1200
    AM_MEDIA_TYPE* pMediaType;
1201
    hr = pMediaSample->GetMediaType(&pMediaType);
1202
    if (hr == S_OK && pMediaType != NULL)
1203
    {
1204
        if (IS_OK(UpdateFormat(pMediaType)))
1205
        {
1206
            m_bFormatChanged = tTrue;
1207
        }
1208

    
1209
        DeleteMediaType(pMediaType);
1210
    }
1211

    
1212
    long nSampleSize = pMediaSample->GetSize();
1213

    
1214
    BYTE* pData = NULL;
1215
    hr = pMediaSample->GetPointer(&pData);
1216

    
1217
    if (m_psStreamEventSink != NULL)
1218
    {
1219
        REFERENCE_TIME  nStartTime, nEndTime;
1220
        hr = pMediaSample->GetTime(&nStartTime, &nEndTime);
1221

    
1222
        tTimeStamp nTime;
1223

    
1224
        if (FAILED(hr))
1225
        {
1226
            if (VFW_S_NO_STOP_TIME == hr)
1227
            {
1228
                nTime = (nStartTime + m_nAvgTimePerFrame / 2) / 10;
1229
            }
1230
            else if (VFW_E_SAMPLE_TIME_NOT_SET == hr)
1231
            {
1232
                nTime = tmCurrent - m_nAvgTimePerFrame / 20;
1233
            }
1234
            else 
1235
            {
1236
                return hr;
1237
            }
1238
        }
1239
        else
1240
        {
1241
            nTime = ((tInt64) nStartTime + (tInt64) nEndTime) / 20;
1242
        }
1243

    
1244
        if (m_bFormatChanged)
1245
        {
1246
            m_psStreamEventSink->OnNewFrame(nTime,
1247
                                            pData,
1248
                                            nSampleSize,
1249
                                            &m_sBitmapFormat,
1250
                                            m_pPalette,
1251
                                            m_bFlipVertical);
1252
            m_bFormatChanged = tFalse;
1253
        }
1254
        else
1255
        {
1256
            m_psStreamEventSink->OnNewFrame(nTime,
1257
                                            pData,
1258
                                            nSampleSize,
1259
                                            NULL,
1260
                                            NULL,
1261
                                            m_bFlipVertical);
1262
        }
1263
    }
1264

    
1265
    return S_OK;
1266
}
(1-1/2)