1793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
2793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
3793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
4793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// PARTICULAR PURPOSE.
5793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//
6793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// Copyright (c) Microsoft Corporation. All rights reserved
7793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
8793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
9793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#pragma once
10793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
11793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
12793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//////////////////////////////////////////////////////////////////////////
13793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//  VideoBufferLock
14793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//
15793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//  Description:
16793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//  Locks a video buffer that might or might not support IMF2DBuffer.
17793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//
18793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//////////////////////////////////////////////////////////////////////////
19793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
20793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerclass VideoBufferLock
21793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
22793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerpublic:
23793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    VideoBufferLock(IMFMediaBuffer *pBuffer) : m_p2DBuffer(NULL)
24793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
25793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        m_pBuffer = pBuffer;
26793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        m_pBuffer->AddRef();
27793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
28793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        // Query for the 2-D buffer interface. OK if this fails.
29793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        m_pBuffer->QueryInterface(IID_PPV_ARGS(&m_p2DBuffer));
30793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
31793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
32793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    ~VideoBufferLock()
33793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
34793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        UnlockBuffer();
35793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        SafeRelease(&m_pBuffer);
36793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        SafeRelease(&m_p2DBuffer);
37793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
38793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
39793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    // LockBuffer:
40793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    // Locks the buffer. Returns a pointer to scan line 0 and returns the stride.
41793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
42793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    // The caller must provide the default stride as an input parameter, in case
43793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    // the buffer does not expose IMF2DBuffer. You can calculate the default stride
44793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    // from the media type.
45793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
46793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    HRESULT LockBuffer(
47793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        LONG  lDefaultStride,    // Minimum stride (with no padding).
48793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        DWORD dwHeightInPixels,  // Height of the image, in pixels.
49793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        BYTE  **ppbScanLine0,    // Receives a pointer to the start of scan line 0.
50793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        LONG  *plStride          // Receives the actual stride.
51793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        )
52793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
53793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        HRESULT hr = S_OK;
54793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
55793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        // Use the 2-D version if available.
56793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if (m_p2DBuffer)
57793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
58793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            hr = m_p2DBuffer->Lock2D(ppbScanLine0, plStride);
59793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
60793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        else
61793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
62793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            // Use non-2D version.
63793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            BYTE *pData = NULL;
64793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
65793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            hr = m_pBuffer->Lock(&pData, NULL, NULL);
66793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if (SUCCEEDED(hr))
67793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
68793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                *plStride = lDefaultStride;
69793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                if (lDefaultStride < 0)
70793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                {
71793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    // Bottom-up orientation. Return a pointer to the start of the
72793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    // last row *in memory* which is the top row of the image.
73793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    *ppbScanLine0 = pData + abs(lDefaultStride) * (dwHeightInPixels - 1);
74793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                }
75793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                else
76793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                {
77793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    // Top-down orientation. Return a pointer to the start of the
78793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    // buffer.
79793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    *ppbScanLine0 = pData;
80793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                }
81793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
82793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
83793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        return hr;
84793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
85793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
86793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    HRESULT UnlockBuffer()
87793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
88793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if (m_p2DBuffer)
89793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
90793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            return m_p2DBuffer->Unlock2D();
91793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
92793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        else
93793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
94793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            return m_pBuffer->Unlock();
95793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
96793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
97793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
98793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerprivate:
99793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    IMFMediaBuffer  *m_pBuffer;
100793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    IMF2DBuffer     *m_p2DBuffer;
101793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler};
102