1 // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 2 // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO 3 // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 4 // PARTICULAR PURPOSE. 5 // 6 // Copyright (c) Microsoft Corporation. All rights reserved 7 8 9 #pragma once 10 11 12 ////////////////////////////////////////////////////////////////////////// 13 // VideoBufferLock 14 // 15 // Description: 16 // Locks a video buffer that might or might not support IMF2DBuffer. 17 // 18 ////////////////////////////////////////////////////////////////////////// 19 20 class VideoBufferLock 21 { 22 public: VideoBufferLock(IMFMediaBuffer * pBuffer)23 VideoBufferLock(IMFMediaBuffer *pBuffer) : m_p2DBuffer(NULL) 24 { 25 m_pBuffer = pBuffer; 26 m_pBuffer->AddRef(); 27 28 // Query for the 2-D buffer interface. OK if this fails. 29 m_pBuffer->QueryInterface(IID_PPV_ARGS(&m_p2DBuffer)); 30 } 31 ~VideoBufferLock()32 ~VideoBufferLock() 33 { 34 UnlockBuffer(); 35 SafeRelease(&m_pBuffer); 36 SafeRelease(&m_p2DBuffer); 37 } 38 39 // LockBuffer: 40 // Locks the buffer. Returns a pointer to scan line 0 and returns the stride. 41 42 // The caller must provide the default stride as an input parameter, in case 43 // the buffer does not expose IMF2DBuffer. You can calculate the default stride 44 // from the media type. 45 LockBuffer(LONG lDefaultStride,DWORD dwHeightInPixels,BYTE ** ppbScanLine0,LONG * plStride)46 HRESULT LockBuffer( 47 LONG lDefaultStride, // Minimum stride (with no padding). 48 DWORD dwHeightInPixels, // Height of the image, in pixels. 49 BYTE **ppbScanLine0, // Receives a pointer to the start of scan line 0. 50 LONG *plStride // Receives the actual stride. 51 ) 52 { 53 HRESULT hr = S_OK; 54 55 // Use the 2-D version if available. 56 if (m_p2DBuffer) 57 { 58 hr = m_p2DBuffer->Lock2D(ppbScanLine0, plStride); 59 } 60 else 61 { 62 // Use non-2D version. 63 BYTE *pData = NULL; 64 65 hr = m_pBuffer->Lock(&pData, NULL, NULL); 66 if (SUCCEEDED(hr)) 67 { 68 *plStride = lDefaultStride; 69 if (lDefaultStride < 0) 70 { 71 // Bottom-up orientation. Return a pointer to the start of the 72 // last row *in memory* which is the top row of the image. 73 *ppbScanLine0 = pData + abs(lDefaultStride) * (dwHeightInPixels - 1); 74 } 75 else 76 { 77 // Top-down orientation. Return a pointer to the start of the 78 // buffer. 79 *ppbScanLine0 = pData; 80 } 81 } 82 } 83 return hr; 84 } 85 UnlockBuffer()86 HRESULT UnlockBuffer() 87 { 88 if (m_p2DBuffer) 89 { 90 return m_p2DBuffer->Unlock2D(); 91 } 92 else 93 { 94 return m_pBuffer->Unlock(); 95 } 96 } 97 98 private: 99 IMFMediaBuffer *m_pBuffer; 100 IMF2DBuffer *m_p2DBuffer; 101 }; 102