//////////////////////////////////////////////////////////////////////////1//2// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF3// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO4// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A5// PARTICULAR PURPOSE.6//7// Copyright (c) Microsoft Corporation. All rights reserved.8//9//////////////////////////////////////////////////////////////////////////10111213#pragma once1415#include "CaptureDevice.h"16#include <wrl/client.h>171819//-------------------------------------------------------------------20// VideoBufferLock class21//22// Locks a video buffer that might or might not support IMF2DBuffer.23//24//-------------------------------------------------------------------2526class VideoBufferLock27{28public:29VideoBufferLock(IMFMediaBuffer *pBuffer) : m_p2DBuffer(NULL), m_bLocked(FALSE)30{31m_pBuffer = pBuffer;3233// Query for the 2-D buffer interface. OK if this fails.34(void)m_pBuffer->QueryInterface(IID_PPV_ARGS(&m_p2DBuffer));35}3637~VideoBufferLock()38{39UnlockBuffer();40}4142//-------------------------------------------------------------------43// LockBuffer44//45// Locks the buffer. Returns a pointer to scan line 0 and returns the stride.46//47// The caller must provide the default stride as an input parameter, in case48// the buffer does not expose IMF2DBuffer. You can calculate the default stride49// from the media type.50//-------------------------------------------------------------------5152HRESULT LockBuffer(53LONG lDefaultStride, // Minimum stride (with no padding).54DWORD dwHeightInPixels, // Height of the image, in pixels.55BYTE **ppbScanLine0, // Receives a pointer to the start of scan line 0.56LONG *plStride // Receives the actual stride.57)58{59HRESULT hr = S_OK;6061// Use the 2-D version if available.62if (m_p2DBuffer)63{64hr = m_p2DBuffer->Lock2D(ppbScanLine0, plStride);65}66else67{68// Use non-2D version.69BYTE *pData = NULL;7071hr = m_pBuffer->Lock(&pData, NULL, NULL);72if (SUCCEEDED(hr))73{74*plStride = lDefaultStride;75if (lDefaultStride < 0)76{77// Bottom-up orientation. Return a pointer to the start of the78// last row *in memory* which is the top row of the image.79*ppbScanLine0 = pData + abs(lDefaultStride) * (dwHeightInPixels - 1);80}81else82{83// Top-down orientation. Return a pointer to the start of the84// buffer.85*ppbScanLine0 = pData;86}87}88}8990m_bLocked = (SUCCEEDED(hr));9192return hr;93}9495//-------------------------------------------------------------------96// UnlockBuffer97//98// Unlocks the buffer. Called automatically by the destructor.99//-------------------------------------------------------------------100101void UnlockBuffer()102{103if (m_bLocked)104{105if (m_p2DBuffer)106{107(void)m_p2DBuffer->Unlock2D();108}109else110{111(void)m_pBuffer->Unlock();112}113m_bLocked = FALSE;114}115}116117private:118Microsoft::WRL::ComPtr<IMFMediaBuffer> m_pBuffer;119Microsoft::WRL::ComPtr<IMF2DBuffer> m_p2DBuffer;120121BOOL m_bLocked;122};123124125