#include "Stdafx.h"
#include "Cサンプルプール.h"
#include "共通\AutoLock.h"

//=========================================================
// !! Win32 と連携するので、例外を発生させてはならない。!!
//=========================================================

namespace FDK
{
// public:

	Cサンプルプール::Cサンプルプール()
	{
		this->m_bInitialized = FALSE;
		this->m_n現在のサンプル数 = 0;
	}
	Cサンプルプール::~Cサンプルプール()
	{
	}

	HRESULT	Cサンプルプール::t初期化する( CVideoSampleList& samples )
	{
		AutoLock lock( m_lock );

		if( this->m_bInitialized )
			return MF_E_INVALIDREQUEST;

		HRESULT hr = S_OK;
		IMFSample *pSample = NULL;

		// samples に含まれるサンプルを、全部 m_VideoSampleQuere に格納する。
		try
		{
			CVideoSampleList::POSITION pos = samples.FrontPosition();
			while( pos != samples.EndPosition() )
			{
				tFAILEDなら帰還( hr = samples.GetItemPos( pos, &pSample ) );			// サンプル取得
				tFAILEDなら帰還( hr = m_VideoSampleQueue.InsertBack( pSample ) );		// 格納
				pos = samples.Next( pos );
				SAFE_COM_RELEASE( pSample );											// サンプル解放
			}
			m_bInitialized = TRUE;
		}
		finally
		{
			samples.Clear();
			SAFE_COM_RELEASE( pSample );
		}

		return S_OK;
	}
	HRESULT Cサンプルプール::Clear()
	{
		AutoLock lock( m_lock );

		this->m_VideoSampleQueue.Clear();
		this->m_bInitialized = FALSE;
		this->m_n現在のサンプル数 = 0;

		return S_OK;
	}

	HRESULT	Cサンプルプール::tプールからサンプルを取り出す( IMFSample **ppSample )
	{
		AutoLock lock( m_lock );

		if( !this->m_bInitialized )
			return MF_E_NOT_INITIALIZED;

		if( this->m_VideoSampleQueue.IsEmpty() )
			return MF_E_SAMPLEALLOCATOR_EMPTY;	// キューが空である


		// キューからサンプルを取得する。

		HRESULT hr = S_OK;
		IMFSample *pSample = NULL;

		try
		{
			// リストの先頭または末尾のどちらから取り出すかについては気にする必要はないが、
			// それを戻す場合には、それを反対側の端に挿入したい。

			tFAILEDなら帰還( hr = this->m_VideoSampleQueue.RemoveFront( &pSample ) );
			this->m_n現在のサンプル数++;

			// 呼び出し元にサンプルを返す。
			*ppSample = pSample;
			( *ppSample )->AddRef();
		}
		finally
		{
			SAFE_COM_RELEASE( pSample );
		}

		return S_OK;
	}
	HRESULT	Cサンプルプール::tサンプルをプールに戻す( IMFSample *pSample )
	{
		AutoLock lock( m_lock );

		if( !this->m_bInitialized )
			return MF_E_NOT_INITIALIZED;

		HRESULT hr = S_OK;

		tFAILEDなら帰還( hr = m_VideoSampleQueue.InsertBack( pSample ) );
		this->m_n現在のサンプル数--;

		return S_OK;
	}
	BOOL	Cサンプルプール::bサンプルが存在している()
	{
		AutoLock lock( m_lock );

		if( !this->m_bInitialized )
			return FALSE;

		return ( this->m_n現在のサンプル数 > 0 );
	}
}
