summaryrefslogtreecommitdiff
path: root/avstream/sampledevicemft/custompin.cpp
blob: 00edb32986fa6762767437f1d567e760f3bbb1d0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#include "stdafx.h"
#include "multipinmft.h"
#include "basepin.h"
#include "custompin.h"
#ifdef MF_WPP
#include "custompin.tmh"    //--REF_ANALYZER_DONT_REMOVE--
#endif


//
// Implementation notes
// Implement this file only if you have custom media pins streaming 
// This implementation just streams from the driver and sends it back
// to the pipeline. This method can be used to stream 3A/Statistic Pins. 
// 

CCustomPin::CCustomPin(
    _In_ IMFAttributes *pAttributes,
    _In_ ULONG PinId,
    _In_ CMultipinMft *pParent
    )
    :CInPin( pAttributes, PinId, pParent )
{

}
//
// Process input calls the pin here.. In this code sample we
// don't send it anywhere. It is simply shortcircuited back to the pipeline
//
STDMETHODIMP CCustomPin::SendSample(
    _In_ IMFSample *pSample
    )
{
    //
    // Log sample and exit.. The pipeline will just keep on churning more samples till 
    // We go into the stop state
    //
    DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! Custom Pin %d recieved Sample %p", streamId(), pSample);

    return S_OK;
}

//
// State change transitions on the custom pins are different than the other pins
// The other known pins i.e. preview, record, image etc are exposed out to the pipeline
// and the pipeline will set state on it, reset state, For the other pins we tell the 
// pipeline that we have samples and the pipeline picks it up. 
//
// The CUSTOM pin differs in that it's state has to be managed to by the device MFT. 
// This code snippet just varies state transitions on the custom pin when the Device MFT
// changes state to STREAMING/END_STREAMING on it's exposed pins. 
//
// The below function tells the pipeline to change the state on the custom pin by sending
// METransformInputStreamStateChanged event with the streamid attribute. The pipeline will
// call back in the custom pin at getprefferedmediatype and finally setinputstreamstate
// which will signal back here singnalling sucessful state transition.
//

STDMETHODIMP_(DeviceStreamState) CCustomPin::SetState(
    _In_ DeviceStreamState State
    )
{
    HRESULT hr = S_OK;
    
    DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! Id:%d Transition into state: %d ", streamId(), State);

    DeviceStreamState oldState = setPreferredStreamState( State );

    if ( oldState != State )
    {
        ComPtr<IMFMediaType> preferredMediaType = nullptr;

        if (State == DeviceStreamState_Run)
        {
            GetMediaTypeAt(0, preferredMediaType.ReleaseAndGetAddressOf());
        }

        setPreferredMediaType(preferredMediaType.Get());
        setPreferredStreamState( State );
        
        {
            //
            // Notify the device transform manager that we have changed state
            //
            ComPtr<IMFMediaEvent> pEvent = nullptr;
            DMFTCHECKHR_GOTO( MFCreateMediaEvent(METransformInputStreamStateChanged, GUID_NULL, S_OK, NULL, pEvent.ReleaseAndGetAddressOf()), done );
            DMFTCHECKHR_GOTO( pEvent->SetUINT32(MF_EVENT_MFT_INPUT_STREAM_ID, streamId()), done );
            DMFTCHECKHR_GOTO( Parent()->QueueEvent(pEvent.Get()), done );
        }
        //
        // Wait to be notified back from the pipeline. 
        //
        DMFTCHECKHR_GOTO( WaitForSetInputPinMediaChange(),done );
    }
done:
    DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr);
    return oldState;
}