summaryrefslogtreecommitdiff
path: root/general/SimpleMediaSource/MediaSource/SimpleMediaSource.h
blob: 019926c829fe9318a7047dc7b1211771725c3a27 (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
#pragma once

// Represents a simple media source that only has one stream and outputs a static image

#include "stdafx.h"

class SimpleMediaStream;

class __declspec(uuid("{9812588D-5CE9-4E4C-ABC1-049138D10DCE}"))
SimpleMediaSource : public RuntimeClass<
    RuntimeClassFlags<WinRtClassicComMix>,
    IMFMediaEventGenerator,
    IMFMediaSource,
    IMFMediaSourceEx,
    IMFGetService,
    IKsControl>
{

    enum class SourceState
    {
        Invalid, Stopped, Started, Shutdown
    };

public:
    // IMFMediaEventGenerator
    IFACEMETHOD(BeginGetEvent)(_In_ IMFAsyncCallback *pCallback, _In_ IUnknown *punkState);
    IFACEMETHOD(EndGetEvent)(_In_ IMFAsyncResult *pResult, _Out_ IMFMediaEvent **ppEvent);
    IFACEMETHOD(GetEvent)(DWORD dwFlags, _Out_ IMFMediaEvent **ppEvent);
    IFACEMETHOD(QueueEvent)(MediaEventType met, REFGUID guidExtendedType, HRESULT hrStatus, _In_ const PROPVARIANT *pvValue);

    // IMFMediaSource
    IFACEMETHOD(CreatePresentationDescriptor)(_Out_ IMFPresentationDescriptor **ppPresentationDescriptor);
    IFACEMETHOD(GetCharacteristics)(_Out_ DWORD *pdwCharacteristics);
    IFACEMETHOD(Pause)();
    IFACEMETHOD(Shutdown)();
    IFACEMETHOD(Start)(_In_ IMFPresentationDescriptor *pPresentationDescriptor, _In_ const GUID *pguidTimeFormat, _In_ const PROPVARIANT *pvarStartPosition);
    IFACEMETHOD(Stop)();

    // IMFMediaSourceEx
    IFACEMETHOD(GetSourceAttributes)(_COM_Outptr_ IMFAttributes **ppAttributes);
    IFACEMETHOD(GetStreamAttributes)(DWORD dwStreamIdentifier, _COM_Outptr_ IMFAttributes **ppAttributes);
    IFACEMETHOD(SetD3DManager)(_In_opt_ IUnknown *pManager);

    // IMFGetService
    IFACEMETHOD(GetService)(_In_ REFGUID guidService, _In_ REFIID riid, _Out_ LPVOID *ppvObject);

    // IKsControl
    IFACEMETHOD(KsProperty)(_In_reads_bytes_(ulPropertyLength) PKSPROPERTY pProperty,
                            _In_ ULONG ulPropertyLength,
                            _Inout_updates_to_(ulDataLength, *pBytesReturned) LPVOID pPropertyData,
                            _In_ ULONG ulDataLength,
                            _Out_ ULONG* pBytesReturned);
    IFACEMETHOD(KsMethod)(_In_reads_bytes_(ulMethodLength) PKSMETHOD pMethod,
                          _In_ ULONG ulMethodLength,
                          _Inout_updates_to_(ulDataLength, *pBytesReturned) LPVOID pMethodData,
                          _In_ ULONG ulDataLength,
                          _Out_ ULONG* pBytesReturned);
    IFACEMETHOD(KsEvent)(_In_reads_bytes_opt_(ulEventLength) PKSEVENT pEvent,
                         _In_ ULONG ulEventLength,
                         _Inout_updates_to_(ulDataLength, *pBytesReturned) LPVOID pEventData,
                         _In_ ULONG ulDataLength,
                         _Out_opt_ ULONG* pBytesReturned);
public:
    HRESULT RuntimeClassInitialize();

private:
    HRESULT _CheckShutdownRequiresLock();
    HRESULT _ValidatePresentationDescriptor(_In_ IMFPresentationDescriptor *pPresentationDescriptor);

    CriticalSection _critSec;
    SourceState _sourceState{ SourceState::Invalid };
    ComPtr<IMFMediaEventQueue> _spEventQueue;
    ComPtr<IMFPresentationDescriptor> _spPresentationDescriptor;
    ComPtr<IMFAttributes> _spAttributes;

    bool _wasStreamPreviouslySelected; // maybe makes more sense as a property of the stream
    const DWORD NUM_STREAMS = 1;
    ComPtr<SimpleMediaStream> _stream;
};

CoCreatableClass(SimpleMediaSource);