summaryrefslogtreecommitdiff
path: root/avstream/samplemft0/SampleHelpers.h
blob: 870e2cd3043d28344054857a900e321e403b73e5 (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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
//// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
//// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
//// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
//// PARTICULAR PURPOSE.
////
//// Copyright (c) Microsoft Corporation. All rights reserved


#pragma once
#include "stdafx.h"

#define WIDEN2(x) L ## x
#define WIDEN(x) WIDEN2(x)
#define __WFILE__ WIDEN(__FILE__)


#define WPP_CONTROL_GUIDS \
    WPP_DEFINE_CONTROL_GUID(WPPCameraExtensionMFt_Sample, \
        (31A88041,BBF0,4D2C,A752,16EB1E51859C), \
        WPP_DEFINE_BIT(AllMessages) \
    )

#define SAFEFREE(x) \
    if(x) { \
        free(x); \
        x = NULL; \
    }
#define SAFERELEASE(x) \
    if(x) { \
        x->Release(); \
        x = NULL; \
    }

#define CHK_LOG_BRK(exp) \
    if(FAILED(hr = (exp)))  { \
        wprintf(L"HR=%08x File: %S Ln:  %d\n", hr, __FILE__, __LINE__); \
        break; \
    }

#define CHK_NULL_BRK(exp) \
    if((exp) == NULL) { \
        hr = E_OUTOFMEMORY; \
        wprintf(L"HR=%08x File: %S Ln:  %d\n", hr, __FILE__, __LINE__); \
        break; \
    }
#define CHK_NULL_PTR_BRK(exp) \
    if((exp) == NULL) { \
        hr = E_INVALIDARG; \
        wprintf(L"HR=%08x File: %S Ln:  %d\n", hr, __FILE__, __LINE__); \
        break; \
    }

#define CHK_BOOL_BRK(exp) \
    if(!exp) { \
        hr = E_FAIL; \
        wprintf(L"HR=%08x File: %S Ln:  %d\n", hr, __FILE__, __LINE__); \
        break; \
    }


class VideoBufferLock
{
public:
    VideoBufferLock(IMFMediaBuffer *pBuffer) : m_p2DBuffer(NULL)
    {
        m_pBuffer = pBuffer;
        m_pBuffer->AddRef();

        // Query for the 2-D buffer interface. OK if this fails.
        m_pBuffer->QueryInterface(IID_IMF2DBuffer, (void**)&m_p2DBuffer);
    }

    ~VideoBufferLock()
    {
        UnlockBuffer();
        SAFERELEASE(m_pBuffer);
        SAFERELEASE(m_p2DBuffer);
    }

    // LockBuffer:
    // Locks the buffer. Returns a pointer to scan line 0 and returns the stride.

    // The caller must provide the default stride as an input parameter, in case
    // the buffer does not expose IMF2DBuffer. You can calculate the default stride
    // from the media type.

    HRESULT LockBuffer(
        LONG  lDefaultStride,    // Minimum stride (with no padding).
        DWORD dwHeightInPixels,  // Height of the image, in pixels.
        BYTE  **ppbScanLine0,    // Receives a pointer to the start of scan line 0.
        LONG  *plStride          // Receives the actual stride.
        )
    {
        HRESULT hr = S_OK;

        // Use the 2-D version if available.
        if (m_p2DBuffer)
        {
            hr = m_p2DBuffer->Lock2D(ppbScanLine0, plStride);
        }
        else
        {
            // Use non-2D version.
            BYTE *pData = NULL;

            hr = m_pBuffer->Lock(&pData, NULL, NULL);
            if (SUCCEEDED(hr))
            {
                *plStride = lDefaultStride;
                if (lDefaultStride < 0)
                {
                    // Bottom-up orientation. Return a pointer to the start of the
                    // last row *in memory* which is the top row of the image.
                    *ppbScanLine0 = pData + abs(lDefaultStride) * (dwHeightInPixels - 1);
                }
                else
                {
                    // Top-down orientation. Return a pointer to the start of the
                    // buffer.
                    *ppbScanLine0 = pData;
                }
            }
        }
        return hr;
    }

    HRESULT UnlockBuffer()
    {
        if (m_p2DBuffer)
        {
            return m_p2DBuffer->Unlock2D();
        }
        else
        {
            return m_pBuffer->Unlock();
        }
    }

private:
    IMFMediaBuffer  *m_pBuffer;
    IMF2DBuffer     *m_p2DBuffer;
};