// This is the main DLL file.

#include "stdafx.h"
#include "XDMDNative.h"
#include "dsfutil.h"
#include "dshowutil.h"






void XDMDNative::SetState(PLAYER_STATE state)
{
	m_State = state;
}

PLAYER_STATE XDMDNative::State()
{
	return m_State;
}
void XDMDNative::_Sleep(int ms)
{
	Sleep(ms);

}

bool XDMDNative::Play()
{
		HRESULT hr = S_OK;

	if (pC->m_pMediaControl != NULL)
	{

	//	if (!IsFFDShowInstalled())
	//	{
	//if (Open(lastfile,true,lastaudio)==true)
	//{
	//	//Sleep(5000);
	//	hr = pC->m_pMediaControl->Run();
	///*	long evCode;
 //   pC->m_pMediaEvent->WaitForCompletion(INFINITE, &evCode);*/


	//if (SUCCEEDED(hr))
	//{
	//	SetState(PLAYER_STATE::PLAYER_STATE_Playing);
	//return true;
	//}
	//}
	//return false;
	//	}

		//pC->m_pSampleGrabber->SetBufferSamples(TRUE);
		//pC->m_pSampleGrabber->SetBufferSamples(TRUE);
		hr = pC->m_pMediaControl->Run();
	/*	long evCode;
    pC->m_pMediaEvent->WaitForCompletion(INFINITE, &evCode);*/


	if (SUCCEEDED(hr))
	{
		SetState(PLAYER_STATE::PLAYER_STATE_Playing);
	//Sleep(4);
		//pC->m_pSampleGrabber->SetBufferSamples(TRUE);
		
					 /*OAFilterState state;
	pC->m_pMediaControl->GetState(20000, &state);*/

		
	//cntgrabs=0;
		}
	}
	
		return true;
//}
}

bool XDMDNative::PlayWait()
{
		HRESULT hr = S_OK;

	if (pC->m_pMediaControl != NULL)
	{
		//pC->m_pSampleGrabber->SetBufferSamples(TRUE);
		hr = pC->m_pMediaControl->Run();
	/*	long evCode;
    pC->m_pMediaEvent->WaitForCompletion(INFINITE, &evCode);*/


	if (SUCCEEDED(hr))
		SetState(PLAYER_STATE::PLAYER_STATE_Playing);
	//Sleep(4);
		//pC->m_pSampleGrabber->SetBufferSamples(TRUE);
		 OAFilterState state;
	pC->m_pMediaControl->GetState(20000, &state);
				
		}
		
		return true;
//}
}

void  XDMDNative::MyDeleteMediaType(AM_MEDIA_TYPE *pmt)
{
	return;
    if (pmt != NULL)
    {
      //  MyFreeMediaType(*pmt); // See FreeMediaType for the implementation.
		
        CoTaskMemFree(pmt);
    }
}

STDMETHODIMP XDMDNative::GrabSample()
{
	if (pC->m_pSampleGrabber == NULL)
		return S_OK;

	HRESULT hr;

	if (W == 0)
	{
		cntgrabs =0;
		AM_MEDIA_TYPE mt;
		hr = pC->m_pSampleGrabber->GetConnectedMediaType(&mt);
		
	/*	VIDEOINFOHEADER *pVih;*/
		if ((mt.formattype == FORMAT_VideoInfo) && 
			(mt.cbFormat >= sizeof(VIDEOINFOHEADER)) &&
			(mt.pbFormat != NULL) ) 
		{
				
			pVih = (VIDEOINFOHEADER*)mt.pbFormat;
			W=pVih->bmiHeader.biWidth;
			H=pVih->bmiHeader.biHeight;
			//pC->m_pSampleGrabber->SetMediaType(&mt);
		//pitch=pVih->bmiHeader.biBitCount ;
		//CoTaskMemFree((PVOID)mt.pbFormat
		}
		else 
		{
			// Wrong format. Free the format block and return an error.
			if (mt.cbFormat != 0)
		{
			CoTaskMemFree((PVOID)mt.pbFormat);
			mt.cbFormat = 0;
			mt.pbFormat = NULL;
		}
		if (mt.pUnk != NULL)
		{
			// Unecessary because pUnk should not be used, but safest.
			mt.pUnk->Release();
			mt.pUnk = NULL;
		}

		//FreeMediaType(&mt);
			return VFW_E_INVALIDMEDIATYPE; 
		}


		if (mt.cbFormat != 0)
		{
			CoTaskMemFree((PVOID)mt.pbFormat);
			mt.cbFormat = 0;
			mt.pbFormat = NULL;
		}
		if (mt.pUnk != NULL)
		{
			// Unecessary because pUnk should not be used, but safest.
			mt.pUnk->Release();
			mt.pUnk = NULL;
		}
//FreeMediaType(&mt);
		//CoTaskMemFree((PVOID)&mt)
		MyDeleteMediaType(&mt);
	}


	
	return S_OK;
}

bool XDMDNative::GrabSampleToDC(int HD,int width,int height)
{
//*R=0;
	//long cbBuffer;
	if (pC->m_pSampleGrabber == NULL)
		return false;


	HRESULT hr;

	AM_MEDIA_TYPE mt;
		hr = pC->m_pSampleGrabber->GetConnectedMediaType(&mt);
		

		if ((mt.formattype == FORMAT_VideoInfo) && 
			(mt.cbFormat >= sizeof(VIDEOINFOHEADER)) &&
			(mt.pbFormat != NULL) ) 
		{
				
			pVih = (VIDEOINFOHEADER*)mt.pbFormat;
		
		}
		else 
		{

			// Wrong format. Free the format block and return an error.
			if (mt.cbFormat != 0)
		{
			CoTaskMemFree((PVOID)mt.pbFormat);
			mt.cbFormat = 0;
			mt.pbFormat = NULL;
		}
		if (mt.pUnk != NULL)
		{
			// Unecessary because pUnk should not be used, but safest.
			/*mt.pUnk->Release();
			mt.pUnk = NULL;*/
		}

		MyDeleteMediaType(&mt);
			return false; 
		}

		if (mt.cbFormat != 0)
		{
			CoTaskMemFree((PVOID)mt.pbFormat);
			mt.cbFormat = 0;
			mt.pbFormat = NULL;
		}
		if (mt.pUnk != NULL)
		{
			// Unecessary because pUnk should not be used, but safest.
			/*mt.pUnk->Release();
			mt.pUnk = NULL;*/
		}

		MyDeleteMediaType(&mt);


		 //pC->m_pSampleGrabber->SetBufferSamples(TRUE);

	
	long Size = 0;
	hr = pC->m_pSampleGrabber->GetCurrentBuffer(&Size, NULL);
//pC->m_pSampleGrabber->SetBufferSamples(FALSE);
//pC->m_pSampleGrabber->SetBufferSamples(TRUE);
	if (FAILED(hr))
                return false;
	if (Size <10000)
return false;


	if (pC->cbBuffer!=Size)

	{
		
		if (pC->cbBuffer!=0)
	{
                    delete[] pBuffer;

	}
		
	pC->cbBuffer=Size;

		pBuffer = new char[pC->cbBuffer];
	}
	if (!pBuffer) 
{
	
	pC->cbBuffer=0;
return false;
	}
	
	
	hr = pC->m_pSampleGrabber->GetCurrentBuffer(&pC->cbBuffer, (long*)pBuffer);
if (FAILED(hr))
                return false;





 StretchDIBits(
  			(HDC)HD, 0, 0, 
			width, height,
			0, 0,
			W, H,
			pBuffer,
			(BITMAPINFO*)&pVih->bmiHeader,
  DIB_RGB_COLORS,
  SRCCOPY
);


		/*SetDIBitsToDevice(
			(HDC)HD, 0, 0, 
			W,
			H,
			0, 0, 
			0,
			H,
			pBuffer,
			(BITMAPINFO*)&pVih->bmiHeader,
			DIB_RGB_COLORS
		);*/
//*R=1;
	return true;
}



bool XDMDNative::GrabSampleToDC(int HD)
{
//*R=0;
	//long cbBuffer;
	if (pC->m_pSampleGrabber == NULL)
		return false;


	HRESULT hr;

	AM_MEDIA_TYPE mt;
		hr = pC->m_pSampleGrabber->GetConnectedMediaType(&mt);
		

		if ((mt.formattype == FORMAT_VideoInfo) && 
			(mt.cbFormat >= sizeof(VIDEOINFOHEADER)) &&
			(mt.pbFormat != NULL) ) 
		{
				
			pVih = (VIDEOINFOHEADER*)mt.pbFormat;
		
		}
		else 
		{

			// Wrong format. Free the format block and return an error.
			if (mt.cbFormat != 0)
		{
			CoTaskMemFree((PVOID)mt.pbFormat);
			mt.cbFormat = 0;
			mt.pbFormat = NULL;
		}
		if (mt.pUnk != NULL)
		{
			// Unecessary because pUnk should not be used, but safest.
			/*mt.pUnk->Release();
			mt.pUnk = NULL;*/
		}

		MyDeleteMediaType(&mt);
			return false; 
		}

		if (mt.cbFormat != 0)
		{
			CoTaskMemFree((PVOID)mt.pbFormat);
			mt.cbFormat = 0;
			mt.pbFormat = NULL;
		}
		if (mt.pUnk != NULL)
		{
			// Unecessary because pUnk should not be used, but safest.
			/*mt.pUnk->Release();
			mt.pUnk = NULL;*/
		}

		MyDeleteMediaType(&mt);


		 //pC->m_pSampleGrabber->SetBufferSamples(TRUE);

	
	long Size = 0;
	hr = pC->m_pSampleGrabber->GetCurrentBuffer(&Size, NULL);
//pC->m_pSampleGrabber->SetBufferSamples(FALSE);
//pC->m_pSampleGrabber->SetBufferSamples(TRUE);
	if (FAILED(hr))
                return false;
	if (Size <10000)
return false;


	if (pC->cbBuffer!=Size)

	{
		
		if (pC->cbBuffer!=0)
	{
                    delete[] pBuffer;

	}
		
	pC->cbBuffer=Size;

		pBuffer = new char[pC->cbBuffer];
	}
	if (!pBuffer) 
{
	
	pC->cbBuffer=0;
return false;
	}
	
	
	hr = pC->m_pSampleGrabber->GetCurrentBuffer(&pC->cbBuffer, (long*)pBuffer);
if (FAILED(hr))
                return false;

		SetDIBitsToDevice(
			(HDC)HD, 0, 0, 
			W,
			H,
			0, 0, 
			0,
			H,
			pBuffer,
			(BITMAPINFO*)&pVih->bmiHeader,
			DIB_RGB_COLORS
		);
//*R=1;
	return true;
}





bool XDMDNative::GrabSampleToMemory(long buf,long l)
{
	return GrabSampleToMemory(buf,l,false);
}


bool XDMDNative::GrabSampleToMemory(long buf,long l,bool wait)
{
//*R=0;
	//long cbBuffer;

	if (pC->m_pSampleGrabber == NULL)
		return false;


	HRESULT hr;
	//if (W == 0)
	//{
	//	cntgrabs =0;
	//AM_MEDIA_TYPE mt;
	//	hr = pC->m_pSampleGrabber->GetConnectedMediaType(&mt);
	//	

	//	if ((mt.formattype == FORMAT_VideoInfo) && 
	//		(mt.cbFormat >= sizeof(VIDEOINFOHEADER)) &&
	//		(mt.pbFormat != NULL) ) 
	//	{
	//			
	//		pVih = (VIDEOINFOHEADER*)mt.pbFormat;
	//	
	//	}
	//	else 
	//	{

	//		// Wrong format. Free the format block and return an error.
	//		if (mt.cbFormat != 0)
	//	{
	//		CoTaskMemFree((PVOID)mt.pbFormat);
	//		mt.cbFormat = 0;
	//		mt.pbFormat = NULL;
	//	}
	//	if (mt.pUnk != NULL)
	//	{
	//		// Unecessary because pUnk should not be used, but safest.
	//		mt.pUnk->Release();
	//		mt.pUnk = NULL;
	//	}

	//	MyDeleteMediaType(&mt);
	//		return false; 
	//	}

	//	if (mt.cbFormat != 0)
	//	{
	//		CoTaskMemFree((PVOID)mt.pbFormat);
	//		mt.cbFormat = 0;
	//		mt.pbFormat = NULL;
	//	}
	//	if (mt.pUnk != NULL)
	//	{
	//		// Unecessary because pUnk should not be used, but safest.
	//		mt.pUnk->Release();
	//		mt.pUnk = NULL;
	//	}

	//	MyDeleteMediaType(&mt);

	//}
	long Size = 0;

		//if (wait==true)
		//{
		//long evCode;
  //  hr = pC->m_pMediaEvent->WaitForCompletion(INFINITE, &evCode);
		//}

try
	{
	if (cntgrabs<3)

{
	cntgrabs++;
	if (cntgrabs==1)
	{
		if (pC->m_pMediaControl != NULL)
	{
	 OAFilterState state;
	pC->m_pMediaControl->GetState(20000, &state);
	}
	}
	//pC->cbBuffer=1;
	//hr = pC->m_pSampleGrabber->GetCurrentBuffer(&pC->cbBuffer, (long*)buf);
	//return true;


	//pC->m_pSampleGrabber->SetBufferSamples (TRUE);
	if (pC->cbBuffer<1000)
	{
	//pC->m_pSampleGrabber->SetBufferSamples(FALSE);
		//pC->m_pSampleGrabber->SetBufferSamples(TRUE);
	hr = pC->m_pSampleGrabber->GetCurrentBuffer(&Size, NULL);

	if (FAILED(hr))
                return false;
	if (Size <10000)
return false;
//	if (Size <(l-4))
//return false;
	if (Size >(l-1))
	{
		Size=(l-1);
//		pC->m_pSampleGrabber->SetBufferSamples(FALSE);
return false;
	}



	if (pC->cbBuffer!=Size)

	{
		
	//	if (pC->cbBuffer!=0)
	//{
 //                   //delete[] pBuffer;

	//}
		
	pC->cbBuffer=Size;

		//pBuffer = new char[pC->cbBuffer];
	}

	if (Size >l)
return false;

	}
//	if (!pBuffer) 
//{
//	
//	pC->cbBuffer=0;
//return false;
	//}
	//}
	if (pC->cbBuffer >(l))
	{
		Size=(l-1);
//		pC->m_pSampleGrabber->SetBufferSamples(FALSE);
return false;
	}
}
	hr = pC->m_pSampleGrabber->GetCurrentBuffer(&pC->cbBuffer, (long*)buf);
if (FAILED(hr))
                return false;
//CopyMemory(buf, pBuffer, Size);
//TCHAR bu[2048] = TEXT("This is the destination");
	}
	catch(HRESULT)
	{
return false;
	}
	
//CopyMemory((void*)buf, pBuffer, Size);

		


//*R=1;
	return true;
}


bool XDMDNative::GrabSampleToBuffer(array<Byte> ^buf,long l)
{
//*R=0;
	//long cbBuffer;

	if (pC->m_pSampleGrabber == NULL)
		return false;


	HRESULT hr;
	//if (W == 0)
	//{
	//	cntgrabs =0;
	//AM_MEDIA_TYPE mt;
	//	hr = pC->m_pSampleGrabber->GetConnectedMediaType(&mt);
	//	

	//	if ((mt.formattype == FORMAT_VideoInfo) && 
	//		(mt.cbFormat >= sizeof(VIDEOINFOHEADER)) &&
	//		(mt.pbFormat != NULL) ) 
	//	{
	//			
	//		pVih = (VIDEOINFOHEADER*)mt.pbFormat;
	//	
	//	}
	//	else 
	//	{

	//		// Wrong format. Free the format block and return an error.
	//		if (mt.cbFormat != 0)
	//	{
	//		CoTaskMemFree((PVOID)mt.pbFormat);
	//		mt.cbFormat = 0;
	//		mt.pbFormat = NULL;
	//	}
	//	if (mt.pUnk != NULL)
	//	{
	//		// Unecessary because pUnk should not be used, but safest.
	//		mt.pUnk->Release();
	//		mt.pUnk = NULL;
	//	}

	//	MyDeleteMediaType(&mt);
	//		return false; 
	//	}

	//	if (mt.cbFormat != 0)
	//	{
	//		CoTaskMemFree((PVOID)mt.pbFormat);
	//		mt.cbFormat = 0;
	//		mt.pbFormat = NULL;
	//	}
	//	if (mt.pUnk != NULL)
	//	{
	//		// Unecessary because pUnk should not be used, but safest.
	//		mt.pUnk->Release();
	//		mt.pUnk = NULL;
	//	}

	//	MyDeleteMediaType(&mt);

	//}
	long Size = 0;

		//if (wait==true)
		//{
		//long evCode;
  //  hr = pC->m_pMediaEvent->WaitForCompletion(INFINITE, &evCode);
		//}

try
	{
	if (cntgrabs<3)

{
	cntgrabs++;
	if (cntgrabs==1)
	{
		if (pC->m_pMediaControl != NULL)
	{
	 OAFilterState state;
	pC->m_pMediaControl->GetState(20000, &state);
	}
	}
	//pC->cbBuffer=1;
	//hr = pC->m_pSampleGrabber->GetCurrentBuffer(&pC->cbBuffer, (long*)buf);
	//return true;


	//pC->m_pSampleGrabber->SetBufferSamples (TRUE);
	if (pC->cbBuffer<1000)
	{
	//pC->m_pSampleGrabber->SetBufferSamples(FALSE);
		//pC->m_pSampleGrabber->SetBufferSamples(TRUE);
	hr = pC->m_pSampleGrabber->GetCurrentBuffer(&Size, NULL);

	if (FAILED(hr))
                return false;
	if (Size <10000)
return false;
//	if (Size <(l-4))
//return false;
	if (Size >(l-1))
	{
		Size=(l-1);
//		pC->m_pSampleGrabber->SetBufferSamples(FALSE);
return false;
	}



	if (pC->cbBuffer!=Size)

	{
		
	//	if (pC->cbBuffer!=0)
	//{
 //                   //delete[] pBuffer;

	//}
		
	pC->cbBuffer=Size;

		//pBuffer = new char[pC->cbBuffer];
	}

	if (Size >l)
return false;

	}
//	if (!pBuffer) 
//{
//	
//	pC->cbBuffer=0;
//return false;
	//}
	//}
	if (pC->cbBuffer >(l))
	{
		Size=(l-1);
//		pC->m_pSampleGrabber->SetBufferSamples(FALSE);
return false;
	}
}
	hr = pC->m_pSampleGrabber->GetCurrentBuffer(&pC->cbBuffer, (long*)reinterpret_cast<unsigned char*>(&buf));
	MessageBox(NULL, (LPCTSTR)"a", (LPCTSTR)"", 0);
if (FAILED(hr))
                return false;
//CopyMemory(buf, pBuffer, Size);
//TCHAR bu[2048] = TEXT("This is the destination");
	}
	catch(HRESULT)
	{
return false;
	}
	
//CopyMemory((void*)buf, pBuffer, Size);

		


//*R=1;
	return true;
}




bool XDMDNative::StopWait()
{

	if (m_State==PLAYER_STATE::PLAYER_STATE_Graph_Stopped1  ) 
return true;

	SetState(PLAYER_STATE::PLAYER_STATE_Graph_Stopped1 );
		HRESULT hr;
	/*	if (pC==NULL )
		{
return false;
		}*/
	if (pC->m_pMediaControl != NULL)
	{

//				long Size=1;
//		long s=1;
////pC->m_pSampleGrabber->SetMediaType(NULL);
//		/*pC->m_pSampleGrabber->SetOneShot(FALSE);
//		pC->m_pSampleGrabber->SetBufferSamples(FALSE);*/
//hr = pC->m_pSampleGrabber->GetCurrentBuffer(&Size, NULL);
//long tb;
//while (Size>10)
//{
//	//Sleep(10);
//		hr = pC->m_pSampleGrabber->GetCurrentBuffer(&Size, NULL);
//		hr = pC->m_pSampleGrabber->GetCurrentBuffer(&s,&tb);
//}

//pC->m_pSampleGrabber->SetBufferSamples(FALSE);
		hr = pC->m_pMediaControl->Stop();
		
		if (SUCCEEDED(hr))
		{
			SetState(PLAYER_STATE::PLAYER_STATE_Graph_Stopped1);
		LONGLONG now = 0;
//if (IsFFDShowInstalled())
		hr = pC->m_pMediaSeeking->SetPositions(&now, AM_SEEKING_AbsolutePositioning, NULL, AM_SEEKING_NoPositioning);
		
//						long Size=1;
//		long s=1;
////pC->m_pSampleGrabber->SetMediaType(NULL);
//		/*pC->m_pSampleGrabber->SetOneShot(FALSE);
//		pC->m_pSampleGrabber->SetBufferSamples(FALSE);*/
//hr = pC->m_pSampleGrabber->GetCurrentBuffer(&Size, NULL);
//long tb;
//while (Size>10)
//{
//	//Sleep(10);
//		hr = pC->m_pSampleGrabber->GetCurrentBuffer(&Size, NULL);
//		hr = pC->m_pSampleGrabber->GetCurrentBuffer(&s,&tb);
//}
//
		}
			 OAFilterState state;
	pC->m_pMediaControl->GetState(10000, &state);
	
		}

return true;

}


bool XDMDNative::Stop()
{

	if (m_State==PLAYER_STATE::PLAYER_STATE_Graph_Stopped1  ) 
return true;

	SetState(PLAYER_STATE::PLAYER_STATE_Graph_Stopped1 );
		HRESULT hr;
	/*	if (pC==NULL )
		{
return false;
		}*/
	if (pC->m_pMediaControl != NULL)
	{

//				long Size=1;
//		long s=1;
////pC->m_pSampleGrabber->SetMediaType(NULL);
//		/*pC->m_pSampleGrabber->SetOneShot(FALSE);
//		pC->m_pSampleGrabber->SetBufferSamples(FALSE);*/
//hr = pC->m_pSampleGrabber->GetCurrentBuffer(&Size, NULL);
//long tb;
//while (Size>10)
//{
//	//Sleep(10);
//		hr = pC->m_pSampleGrabber->GetCurrentBuffer(&Size, NULL);
//		hr = pC->m_pSampleGrabber->GetCurrentBuffer(&s,&tb);
//}

//pC->m_pSampleGrabber->SetBufferSamples(FALSE);
		hr = pC->m_pMediaControl->Stop();
		
		if (SUCCEEDED(hr))
		{
			SetState(PLAYER_STATE::PLAYER_STATE_Graph_Stopped1);
		LONGLONG now = 0;
//if (IsFFDShowInstalled())
		hr = pC->m_pMediaSeeking->SetPositions(&now, AM_SEEKING_AbsolutePositioning, NULL, AM_SEEKING_NoPositioning);
		}
//						long Size=1;
//		long s=1;
////pC->m_pSampleGrabber->SetMediaType(NULL);
//		/*pC->m_pSampleGrabber->SetOneShot(FALSE);
//		pC->m_pSampleGrabber->SetBufferSamples(FALSE);*/
//hr = pC->m_pSampleGrabber->GetCurrentBuffer(&Size, NULL);
//long tb;
//while (Size>10)
//{
//	//Sleep(10);
//		hr = pC->m_pSampleGrabber->GetCurrentBuffer(&Size, NULL);
//		hr = pC->m_pSampleGrabber->GetCurrentBuffer(&s,&tb);
//}
//
		/*		 OAFilterState state;
	pC->m_pMediaControl->GetState(20000, &state);*/
	}

return true;

}
void XDMDNative::SetVolume(INT volume)
{
    HRESULT hr = 0;

    if (pC->m_pGraphBuilder2 == NULL || pC->m_pBasicAudio == NULL)
        return;

    hr = pC->m_pBasicAudio->put_Volume(volume);
}

void XDMDNative::ConfigureSampleGrabber()
{

    ZeroMemory(&pC->globalmt, sizeof(AM_MEDIA_TYPE));

    pC->globalmt.majortype = MEDIATYPE_Video;
    pC->globalmt.subtype = MEDIASUBTYPE_RGB32;
    pC->globalmt.formattype = FORMAT_VideoInfo;
//pC->globalmt.bFixedSizeSamples = true;
	/* HDC hdc = GetDC(NULL);
	INT iBitDepth = GetDeviceCaps(hdc, BITSPIXEL);

	ReleaseDC(NULL, hdc);

	switch (iBitDepth)
	{
	case 8:
		mt.subtype = MEDIASUBTYPE_RGB32;
		break;
	case 16:
		mt.subtype = MEDIASUBTYPE_RGB32;
		break;
	case 24:
		mt.subtype = MEDIASUBTYPE_RGB32;
		break;
	case 32:
		mt.subtype = MEDIASUBTYPE_RGB32;
		break;
	default:
		mt.subtype = MEDIASUBTYPE_RGB32;
	} */

    pC->m_pSampleGrabber->SetMediaType(&pC->globalmt);

pC->m_pSampleGrabber->SetBufferSamples (TRUE);
	
	
}


void XDMDNative::ConfigureSampleGrabber24bit()
{

    ZeroMemory(&pC->globalmt, sizeof(AM_MEDIA_TYPE));

    pC->globalmt.majortype = MEDIATYPE_Video;
    pC->globalmt.subtype = MEDIASUBTYPE_RGB24;
    pC->globalmt.formattype = FORMAT_VideoInfo;
//pC->globalmt.bFixedSizeSamples = true;
	/* HDC hdc = GetDC(NULL);
	INT iBitDepth = GetDeviceCaps(hdc, BITSPIXEL);

	ReleaseDC(NULL, hdc);

	switch (iBitDepth)
	{
	case 8:
		mt.subtype = MEDIASUBTYPE_RGB32;
		break;
	case 16:
		mt.subtype = MEDIASUBTYPE_RGB32;
		break;
	case 24:
		mt.subtype = MEDIASUBTYPE_RGB32;
		break;
	case 32:
		mt.subtype = MEDIASUBTYPE_RGB32;
		break;
	default:
		mt.subtype = MEDIASUBTYPE_RGB32;
	} */

    pC->m_pSampleGrabber->SetMediaType(&pC->globalmt);

pC->m_pSampleGrabber->SetBufferSamples (TRUE);
	
	
}



void XDMDNative::ConfigureSampleGrabber16bit()
{

    ZeroMemory(&pC->globalmt, sizeof(AM_MEDIA_TYPE));

    pC->globalmt.majortype = MEDIATYPE_Video;
    pC->globalmt.subtype = MEDIASUBTYPE_RGB555;
    pC->globalmt.formattype = FORMAT_VideoInfo;
//pC->globalmt.bFixedSizeSamples = true;
	/* HDC hdc = GetDC(NULL);
	INT iBitDepth = GetDeviceCaps(hdc, BITSPIXEL);

	ReleaseDC(NULL, hdc);

	switch (iBitDepth)
	{
	case 8:
		mt.subtype = MEDIASUBTYPE_RGB32;
		break;
	case 16:
		mt.subtype = MEDIASUBTYPE_RGB32;
		break;
	case 24:
		mt.subtype = MEDIASUBTYPE_RGB32;
		break;
	case 32:
		mt.subtype = MEDIASUBTYPE_RGB32;
		break;
	default:
		mt.subtype = MEDIASUBTYPE_RGB32;
	} */

    pC->m_pSampleGrabber->SetMediaType(&pC->globalmt);

pC->m_pSampleGrabber->SetBufferSamples (TRUE);
	
	
}





bool XDMDNative::Open24bit(String^ file, bool WMV, bool m_bAudioOn)
{
	lastaudio=m_bAudioOn;
W=0;
	HRESULT hr;
WMV=true;
	Stop();

	if (pC->m_pMediaControl != NULL)
	{
//
//	/*	pC->m_pSampleGrabber->SetOneShot(FALSE);
//
//
//pC->m_pSampleGrabber->SetBufferSamples(FALSE);
////pC->m_pSampleGrabber->SetMediaType(NULL);
//
//		long Size=1;
//		long s=1;
////pC->m_pSampleGrabber->SetMediaType(NULL);
//		pC->m_pSampleGrabber->SetOneShot(FALSE);
//		pC->m_pSampleGrabber->SetBufferSamples(FALSE);
//hr = pC->m_pSampleGrabber->GetCurrentBuffer(&Size, NULL);
//long tb;
//while (Size>10)
//{
//	//Sleep(10);
//		hr = pC->m_pSampleGrabber->GetCurrentBuffer(&Size, NULL);
//		hr = pC->m_pSampleGrabber->GetCurrentBuffer(&s,&tb);
//}
if(!IsFFDShowInstalled())
	{
				 OAFilterState state;
	pC->m_pMediaControl->GetState(20000, &state);
//}
}
	}
//
//
////long Size;
////hr = pC->m_pSampleGrabber->GetCurrentBuffer(&Size, NULL);
////long tb;
////while (Size>10)
////{
////	Sleep(10);
////		hr = pC->m_pSampleGrabber->GetCurrentBuffer(&Size, NULL);
////		hr = pC->m_pSampleGrabber->GetCurrentBuffer(0,&tb);
////}
//
	//}
	//	if (pC->m_pMediaControl != NULL)
	//{
	//	//pC->m_pSampleGrabber->SetBufferSamples(TRUE);
	//	//hr = pC->m_pMediaControl->Run();
	///*	long evCode;
 //   pC->m_pMediaEvent->WaitForCompletion(INFINITE, &evCode);*/
 //OAFilterState state;

	////if (SUCCEEDED(hr))
	////	SetState(PLAYER_STATE::PLAYER_STATE_Playing);
	//////Sleep(4);
	////	pC->m_pSampleGrabber->SetBufferSamples(TRUE);
	//pC->m_pMediaControl->GetState(20000, &state);
	//			
	//	}
	ReleaseInterfaces();
//m_bFirstPlay = true;
SetState(PLAYER_STATE::PLAYER_STATE_Graph_Stopped1 );
if (pC->m_pGraphBuilder2==NULL)
{
    pC->m_pGraphBuilder2.CoCreateInstance(CLSID_CaptureGraphBuilder2);
}

if (pC->m_pFilterGraph==NULL)
{
    pC->m_pFilterGraph.CoCreateInstance(CLSID_FilterGraph);
}
    pC->m_pGraphBuilder2->SetFiltergraph(pC->m_pFilterGraph);

	IntPtr ptr = Marshal::StringToHGlobalUni(file);
LPCWSTR str = reinterpret_cast<LPCWSTR>(ptr.ToPointer());
//MessageBoxW(NULL,str, str, 0);
//do stuff with string


if (pC->m_pSampleGrabber==NULL)
{
    pC->grabberFilter.CoCreateInstance(CLSID_SampleGrabber);
    pC->grabberFilter->QueryInterface(IID_ISampleGrabber, (PVOID *) &pC->m_pSampleGrabber);
	ConfigureSampleGrabber24bit();

}



pC->m_pSampleGrabber->SetBufferSamples(TRUE);
    hr =  pC->m_pFilterGraph->AddFilter(pC->grabberFilter, L"Sample Grabber");
    if (FAILED(hr))
	{
		//pC->m_pGraphBuilder2->
      // SaveGraphFile(pC->m_pGraphBuilder2, L"C:\\graph.grf");
        return FALSE;
	}
	

//	USHORT realName[512];
//	MultiByteToWideChar(CP_ACP, 0, fileName, -1, realName, 512);


	hr = pC->m_pFilterGraph->AddSourceFilter( str, L"Video Source", &pC->sourceFilter);
	Marshal::FreeHGlobal(ptr);
    if (FAILED(hr))
	{
		//pC->m_pGraphBuilder2->
      // SaveGraphFile(pC->m_pGraphBuilder2, L"C:\\graph.grf");
        return FALSE;
	}
	// -------------------------

if(!IsFFDShowInstalled())
	{
if (pC->pColorConvertDMO==NULL)
{
	hr = pC->pColorConvertDMO.CoCreateInstance(CLSID_DMOWrapperFilter);

	if (SUCCEEDED(hr))
	{
		
		hr = pC->pColorConvertDMO->QueryInterface(IID_IDMOWrapperFilter, reinterpret_cast<void**>(&pC->pDmoWrapper));

		if (SUCCEEDED(hr))
		{
			hr = pC->pDmoWrapper->Init(__uuidof(CColorConvertDMO), DMOCATEGORY_VIDEO_EFFECT);

			if (SUCCEEDED(hr))
			{
				hr = pC->m_pFilterGraph->AddFilter(pC->pColorConvertDMO, L"Color Convert DMO");
			}
		}
	}
}
else
{
	//Sleep(5000);
	hr = pC->m_pFilterGraph->AddFilter(pC->pColorConvertDMO, L"Color Convert DMO");
}
}
	// Enumerate all the pins in the source filter attempting to connect the sample grabber
 //   if (FAILED(hr))
	//{
	//	pC->m_pGraphBuilder2->
 //      SaveGraphFile(pC->m_pGraphBuilder2, L"C:\\graph.grf");
 //       return FALSE;
	//}
	CComPtr<IEnumPins> pEnum = NULL;
	CComPtr<IPin> pPin = NULL;

    hr = pC->sourceFilter->EnumPins(&pEnum);
    
    while (S_OK == pEnum->Next(1, &pPin, NULL))
    {
        hr = ConnectFilters(pC->m_pFilterGraph, pPin, pC->grabberFilter);

        pPin.Release();
pPin = NULL;
        if (SUCCEEDED(hr))
        {
            break;
        }
    }
if (pEnum!=NULL)
	pEnum.Release();
 pEnum = NULL;
	// -------------------------
   if (FAILED(hr))
	{
		//pC->m_pGraphBuilder2->
      // SaveGraphFile(pC->m_pGraphBuilder2, L"C:\\graph.grf");
        return FALSE;
	}
  if (pC->nullRenderer == NULL)  
    pC->nullRenderer.CoCreateInstance(CLSID_NullRenderer);

	hr = pC->m_pFilterGraph->AddFilter(pC->nullRenderer, L"Null Renderer");

    if (FAILED(hr))
	{
		//pC->m_pGraphBuilder2->
      // SaveGraphFile(pC->m_pGraphBuilder2, L"C:\\graph.grf");
        return FALSE;
	}

	/* if(WMV==TRUE)
		hr = pC->m_pGraphBuilder2->RenderStream(NULL, &MEDIATYPE_Video, sourceFilter, grabberFilter, nullRenderer);
	else
		hr = pC->m_pGraphBuilder2->RenderStream(NULL, NULL, sourceFilter, grabberFilter, nullRenderer); */

	// It seems that this is a much more reliable way to connect the pins
	hr = ConnectFilters(pC->m_pFilterGraph, pC->grabberFilter, pC->nullRenderer);

    if (FAILED(hr))
	{
		//pC->m_pGraphBuilder2->
       //SaveGraphFile(pC->m_pGraphBuilder2, L"C:\\graph.grf");
        return FALSE;
	}
//SaveGraphFile(pC->m_pGraphBuilder2, L"C:\\graph.grf");
    hr = pC->m_pGraphBuilder2->RenderStream(NULL, &MEDIATYPE_Audio, pC->sourceFilter, NULL, NULL);
 //   if (FAILED(hr))
	//{
	//	//pC->m_pGraphBuilder2->
 //     // SaveGraphFile(pC->m_pGraphBuilder2, L"C:\\graph.grf");
 //       return FALSE;
	//}
//if (pC->m_pMediaEvent==NULL)
//{

	hr = pC->m_pFilterGraph->QueryInterface(IID_IMediaEvent,(PVOID *) &pC->m_pMediaEvent);
	hr = pC->m_pFilterGraph->QueryInterface(IID_IMediaControl,(PVOID *) &pC->m_pMediaControl);
	hr = pC->m_pFilterGraph->QueryInterface(IID_IMediaSeeking,(PVOID *) &pC->m_pMediaSeeking);
	hr = pC->m_pFilterGraph->QueryInterface(IID_IMediaPosition,(PVOID *) &pC->m_pMediaPosition);
	hr = pC->m_pFilterGraph->QueryInterface(IID_IBasicAudio,(PVOID *) &pC->m_pBasicAudio);
//}

//SaveGraphFile(pC->m_pGraphBuilder2, L"C:\\graph.grf");
if (m_bAudioOn==true)
{
	SetVolume(VOLUME_FULL);
}
else
{
	SetVolume(VOLUME_SILENCE);
}
	//hr = m_pMediaEvent->SetNotifyWindow(hWnd, WM_GRAPHNOTIFY, NULL);


lastfile =file;
    //return hr;
	return true;


}	



bool XDMDNative::Open16bit(String^ file, bool WMV, bool m_bAudioOn)
{
	lastaudio=m_bAudioOn;
W=0;
	HRESULT hr;
WMV=true;
	Stop();

	if (pC->m_pMediaControl != NULL)
	{
//
//	/*	pC->m_pSampleGrabber->SetOneShot(FALSE);
//
//
//pC->m_pSampleGrabber->SetBufferSamples(FALSE);
////pC->m_pSampleGrabber->SetMediaType(NULL);
//
//		long Size=1;
//		long s=1;
////pC->m_pSampleGrabber->SetMediaType(NULL);
//		pC->m_pSampleGrabber->SetOneShot(FALSE);
//		pC->m_pSampleGrabber->SetBufferSamples(FALSE);
//hr = pC->m_pSampleGrabber->GetCurrentBuffer(&Size, NULL);
//long tb;
//while (Size>10)
//{
//	//Sleep(10);
//		hr = pC->m_pSampleGrabber->GetCurrentBuffer(&Size, NULL);
//		hr = pC->m_pSampleGrabber->GetCurrentBuffer(&s,&tb);
//}
if(!IsFFDShowInstalled())
	{
				 OAFilterState state;
	pC->m_pMediaControl->GetState(20000, &state);
//}
}
	}
//
//
////long Size;
////hr = pC->m_pSampleGrabber->GetCurrentBuffer(&Size, NULL);
////long tb;
////while (Size>10)
////{
////	Sleep(10);
////		hr = pC->m_pSampleGrabber->GetCurrentBuffer(&Size, NULL);
////		hr = pC->m_pSampleGrabber->GetCurrentBuffer(0,&tb);
////}
//
	//}
	//	if (pC->m_pMediaControl != NULL)
	//{
	//	//pC->m_pSampleGrabber->SetBufferSamples(TRUE);
	//	//hr = pC->m_pMediaControl->Run();
	///*	long evCode;
 //   pC->m_pMediaEvent->WaitForCompletion(INFINITE, &evCode);*/
 //OAFilterState state;

	////if (SUCCEEDED(hr))
	////	SetState(PLAYER_STATE::PLAYER_STATE_Playing);
	//////Sleep(4);
	////	pC->m_pSampleGrabber->SetBufferSamples(TRUE);
	//pC->m_pMediaControl->GetState(20000, &state);
	//			
	//	}
	ReleaseInterfaces();
//m_bFirstPlay = true;
SetState(PLAYER_STATE::PLAYER_STATE_Graph_Stopped1 );
if (pC->m_pGraphBuilder2==NULL)
{
    pC->m_pGraphBuilder2.CoCreateInstance(CLSID_CaptureGraphBuilder2);
}

if (pC->m_pFilterGraph==NULL)
{
    pC->m_pFilterGraph.CoCreateInstance(CLSID_FilterGraph);
}
    pC->m_pGraphBuilder2->SetFiltergraph(pC->m_pFilterGraph);

	IntPtr ptr = Marshal::StringToHGlobalUni(file);
LPCWSTR str = reinterpret_cast<LPCWSTR>(ptr.ToPointer());
//MessageBoxW(NULL,str, str, 0);
//do stuff with string


if (pC->m_pSampleGrabber==NULL)
{
    pC->grabberFilter.CoCreateInstance(CLSID_SampleGrabber);
    pC->grabberFilter->QueryInterface(IID_ISampleGrabber, (PVOID *) &pC->m_pSampleGrabber);
	ConfigureSampleGrabber16bit();

}



pC->m_pSampleGrabber->SetBufferSamples(TRUE);
    hr =  pC->m_pFilterGraph->AddFilter(pC->grabberFilter, L"Sample Grabber");
    if (FAILED(hr))
	{
		//pC->m_pGraphBuilder2->
      // SaveGraphFile(pC->m_pGraphBuilder2, L"C:\\graph.grf");
        return FALSE;
	}
	

//	USHORT realName[512];
//	MultiByteToWideChar(CP_ACP, 0, fileName, -1, realName, 512);


	hr = pC->m_pFilterGraph->AddSourceFilter( str, L"Video Source", &pC->sourceFilter);
	Marshal::FreeHGlobal(ptr);
    if (FAILED(hr))
	{
		//pC->m_pGraphBuilder2->
      // SaveGraphFile(pC->m_pGraphBuilder2, L"C:\\graph.grf");
        return FALSE;
	}
	// -------------------------

if(!IsFFDShowInstalled())
	{
if (pC->pColorConvertDMO==NULL)
{
	hr = pC->pColorConvertDMO.CoCreateInstance(CLSID_DMOWrapperFilter);

	if (SUCCEEDED(hr))
	{
		
		hr = pC->pColorConvertDMO->QueryInterface(IID_IDMOWrapperFilter, reinterpret_cast<void**>(&pC->pDmoWrapper));

		if (SUCCEEDED(hr))
		{
			hr = pC->pDmoWrapper->Init(__uuidof(CColorConvertDMO), DMOCATEGORY_VIDEO_EFFECT);

			if (SUCCEEDED(hr))
			{
				hr = pC->m_pFilterGraph->AddFilter(pC->pColorConvertDMO, L"Color Convert DMO");
			}
		}
	}
}
else
{
	//Sleep(5000);
	hr = pC->m_pFilterGraph->AddFilter(pC->pColorConvertDMO, L"Color Convert DMO");
}
}
	// Enumerate all the pins in the source filter attempting to connect the sample grabber
 //   if (FAILED(hr))
	//{
	//	pC->m_pGraphBuilder2->
 //      SaveGraphFile(pC->m_pGraphBuilder2, L"C:\\graph.grf");
 //       return FALSE;
	//}
	CComPtr<IEnumPins> pEnum = NULL;
	CComPtr<IPin> pPin = NULL;

    hr = pC->sourceFilter->EnumPins(&pEnum);
    
    while (S_OK == pEnum->Next(1, &pPin, NULL))
    {
        hr = ConnectFilters(pC->m_pFilterGraph, pPin, pC->grabberFilter);

        pPin.Release();
pPin = NULL;
        if (SUCCEEDED(hr))
        {
            break;
        }
    }
if (pEnum!=NULL)
	pEnum.Release();
 pEnum = NULL;
	// -------------------------
   if (FAILED(hr))
	{
		//pC->m_pGraphBuilder2->
      // SaveGraphFile(pC->m_pGraphBuilder2, L"C:\\graph.grf");
        return FALSE;
	}
  if (pC->nullRenderer == NULL)  
    pC->nullRenderer.CoCreateInstance(CLSID_NullRenderer);

	hr = pC->m_pFilterGraph->AddFilter(pC->nullRenderer, L"Null Renderer");

    if (FAILED(hr))
	{
		//pC->m_pGraphBuilder2->
      // SaveGraphFile(pC->m_pGraphBuilder2, L"C:\\graph.grf");
        return FALSE;
	}

	/* if(WMV==TRUE)
		hr = pC->m_pGraphBuilder2->RenderStream(NULL, &MEDIATYPE_Video, sourceFilter, grabberFilter, nullRenderer);
	else
		hr = pC->m_pGraphBuilder2->RenderStream(NULL, NULL, sourceFilter, grabberFilter, nullRenderer); */

	// It seems that this is a much more reliable way to connect the pins
	hr = ConnectFilters(pC->m_pFilterGraph, pC->grabberFilter, pC->nullRenderer);

    if (FAILED(hr))
	{
		//pC->m_pGraphBuilder2->
       //SaveGraphFile(pC->m_pGraphBuilder2, L"C:\\graph.grf");
        return FALSE;
	}
//SaveGraphFile(pC->m_pGraphBuilder2, L"C:\\graph.grf");
    hr = pC->m_pGraphBuilder2->RenderStream(NULL, &MEDIATYPE_Audio, pC->sourceFilter, NULL, NULL);
 //   if (FAILED(hr))
	//{
	//	//pC->m_pGraphBuilder2->
 //     // SaveGraphFile(pC->m_pGraphBuilder2, L"C:\\graph.grf");
 //       return FALSE;
	//}
//if (pC->m_pMediaEvent==NULL)
//{

	hr = pC->m_pFilterGraph->QueryInterface(IID_IMediaEvent,(PVOID *) &pC->m_pMediaEvent);
	hr = pC->m_pFilterGraph->QueryInterface(IID_IMediaControl,(PVOID *) &pC->m_pMediaControl);
	hr = pC->m_pFilterGraph->QueryInterface(IID_IMediaSeeking,(PVOID *) &pC->m_pMediaSeeking);
	hr = pC->m_pFilterGraph->QueryInterface(IID_IMediaPosition,(PVOID *) &pC->m_pMediaPosition);
	hr = pC->m_pFilterGraph->QueryInterface(IID_IBasicAudio,(PVOID *) &pC->m_pBasicAudio);
//}

//SaveGraphFile(pC->m_pGraphBuilder2, L"C:\\graph.grf");
if (m_bAudioOn==true)
{
	SetVolume(VOLUME_FULL);
}
else
{
	SetVolume(VOLUME_SILENCE);
}
	//hr = m_pMediaEvent->SetNotifyWindow(hWnd, WM_GRAPHNOTIFY, NULL);


lastfile =file;
    //return hr;
	return true;


}	





bool XDMDNative::Open(String^ file, bool WMV, bool m_bAudioOn)
{
	lastaudio=m_bAudioOn;
W=0;
	HRESULT hr;
WMV=true;
	Stop();

	if (pC->m_pMediaControl != NULL)
	{
//
//	/*	pC->m_pSampleGrabber->SetOneShot(FALSE);
//
//
//pC->m_pSampleGrabber->SetBufferSamples(FALSE);
////pC->m_pSampleGrabber->SetMediaType(NULL);
//
//		long Size=1;
//		long s=1;
////pC->m_pSampleGrabber->SetMediaType(NULL);
//		pC->m_pSampleGrabber->SetOneShot(FALSE);
//		pC->m_pSampleGrabber->SetBufferSamples(FALSE);
//hr = pC->m_pSampleGrabber->GetCurrentBuffer(&Size, NULL);
//long tb;
//while (Size>10)
//{
//	//Sleep(10);
//		hr = pC->m_pSampleGrabber->GetCurrentBuffer(&Size, NULL);
//		hr = pC->m_pSampleGrabber->GetCurrentBuffer(&s,&tb);
//}
if(!IsFFDShowInstalled())
	{
				 OAFilterState state;
	pC->m_pMediaControl->GetState(20000, &state);

	//ReleaseAllInterfacesFinal();
}
}
	//}
//
//
////long Size;
////hr = pC->m_pSampleGrabber->GetCurrentBuffer(&Size, NULL);
////long tb;
////while (Size>10)
////{
////	Sleep(10);
////		hr = pC->m_pSampleGrabber->GetCurrentBuffer(&Size, NULL);
////		hr = pC->m_pSampleGrabber->GetCurrentBuffer(0,&tb);
////}
//
	//}
	//	if (pC->m_pMediaControl != NULL)
	//{
	//	//pC->m_pSampleGrabber->SetBufferSamples(TRUE);
	//	//hr = pC->m_pMediaControl->Run();
	///*	long evCode;
 //   pC->m_pMediaEvent->WaitForCompletion(INFINITE, &evCode);*/
 //OAFilterState state;

	////if (SUCCEEDED(hr))
	////	SetState(PLAYER_STATE::PLAYER_STATE_Playing);
	//////Sleep(4);
	////	pC->m_pSampleGrabber->SetBufferSamples(TRUE);
	//pC->m_pMediaControl->GetState(20000, &state);
	//			
	//	}
	ReleaseInterfaces();
//m_bFirstPlay = true;
SetState(PLAYER_STATE::PLAYER_STATE_Graph_Stopped1 );
if (pC->m_pGraphBuilder2==NULL)
{
    pC->m_pGraphBuilder2.CoCreateInstance(CLSID_CaptureGraphBuilder2);
}

if (pC->m_pFilterGraph==NULL)
{
    pC->m_pFilterGraph.CoCreateInstance(CLSID_FilterGraph);
}
    pC->m_pGraphBuilder2->SetFiltergraph(pC->m_pFilterGraph);

	IntPtr ptr = Marshal::StringToHGlobalUni(file);
LPCWSTR str = reinterpret_cast<LPCWSTR>(ptr.ToPointer());
//MessageBoxW(NULL,str, str, 0);
//do stuff with string


if (pC->m_pSampleGrabber==NULL)
{
    pC->grabberFilter.CoCreateInstance(CLSID_SampleGrabber);
    pC->grabberFilter->QueryInterface(IID_ISampleGrabber, (PVOID *) &pC->m_pSampleGrabber);
	ConfigureSampleGrabber();

}


pC->m_pSampleGrabber->SetBufferSamples(TRUE);
    hr =  pC->m_pFilterGraph->AddFilter(pC->grabberFilter, L"Sample Grabber");
    if (FAILED(hr))
	{
		//pC->m_pGraphBuilder2->
      // SaveGraphFile(pC->m_pGraphBuilder2, L"C:\\graph.grf");
        return FALSE;
	}
	

//	USHORT realName[512];
//	MultiByteToWideChar(CP_ACP, 0, fileName, -1, realName, 512);


	hr = pC->m_pFilterGraph->AddSourceFilter( str, L"Video Source", &pC->sourceFilter);
	Marshal::FreeHGlobal(ptr);
    if (FAILED(hr))
	{
		//pC->m_pGraphBuilder2->
      // SaveGraphFile(pC->m_pGraphBuilder2, L"C:\\graph.grf");
        return FALSE;
	}
	// -------------------------

if(!IsFFDShowInstalled())
	{
if (pC->pColorConvertDMO==NULL)
{
	hr = pC->pColorConvertDMO.CoCreateInstance(CLSID_DMOWrapperFilter);

	if (SUCCEEDED(hr))
	{
		
		hr = pC->pColorConvertDMO->QueryInterface(IID_IDMOWrapperFilter, reinterpret_cast<void**>(&pC->pDmoWrapper));

		if (SUCCEEDED(hr))
		{
			hr = pC->pDmoWrapper->Init(__uuidof(CColorConvertDMO), DMOCATEGORY_VIDEO_EFFECT);

			if (SUCCEEDED(hr))
			{
				hr = pC->m_pFilterGraph->AddFilter(pC->pColorConvertDMO, L"Color Convert DMO");
			}
		}
	}
}
else
{
	//Sleep(5000);
	hr = pC->m_pFilterGraph->AddFilter(pC->pColorConvertDMO, L"Color Convert DMO");
}
}
	// Enumerate all the pins in the source filter attempting to connect the sample grabber
 //   if (FAILED(hr))
	//{
	//	pC->m_pGraphBuilder2->
 //      SaveGraphFile(pC->m_pGraphBuilder2, L"C:\\graph.grf");
 //       return FALSE;
	//}
	CComPtr<IEnumPins> pEnum = NULL;
	CComPtr<IPin> pPin = NULL;

    hr = pC->sourceFilter->EnumPins(&pEnum);
    
    while (S_OK == pEnum->Next(1, &pPin, NULL))
    {
        hr = ConnectFilters(pC->m_pFilterGraph, pPin, pC->grabberFilter);

        pPin.Release();
pPin = NULL;
        if (SUCCEEDED(hr))
        {
            break;
        }
    }
if (pEnum!=NULL)
	pEnum.Release();
 pEnum = NULL;
	// -------------------------
   if (FAILED(hr))
	{
		//pC->m_pGraphBuilder2->
      // SaveGraphFile(pC->m_pGraphBuilder2, L"C:\\graph.grf");
        return FALSE;
	}
  if (pC->nullRenderer == NULL)  
    pC->nullRenderer.CoCreateInstance(CLSID_NullRenderer);

	hr = pC->m_pFilterGraph->AddFilter(pC->nullRenderer, L"Null Renderer");

    if (FAILED(hr))
	{
		//pC->m_pGraphBuilder2->
      // SaveGraphFile(pC->m_pGraphBuilder2, L"C:\\graph.grf");
        return FALSE;
	}

	/* if(WMV==TRUE)
		hr = pC->m_pGraphBuilder2->RenderStream(NULL, &MEDIATYPE_Video, sourceFilter, grabberFilter, nullRenderer);
	else
		hr = pC->m_pGraphBuilder2->RenderStream(NULL, NULL, sourceFilter, grabberFilter, nullRenderer); */

	// It seems that this is a much more reliable way to connect the pins
	hr = ConnectFilters(pC->m_pFilterGraph, pC->grabberFilter, pC->nullRenderer);

    if (FAILED(hr))
	{
		//pC->m_pGraphBuilder2->
       //SaveGraphFile(pC->m_pGraphBuilder2, L"C:\\graph.grf");
        return FALSE;
	}
//SaveGraphFile(pC->m_pGraphBuilder2, L"C:\\graph.grf");
    hr = pC->m_pGraphBuilder2->RenderStream(NULL, &MEDIATYPE_Audio, pC->sourceFilter, NULL, NULL);
 //   if (FAILED(hr))
	//{
	//	//pC->m_pGraphBuilder2->
 //     // SaveGraphFile(pC->m_pGraphBuilder2, L"C:\\graph.grf");
 //       return FALSE;
	//}
//if (pC->m_pMediaEvent==NULL)
//{

	hr = pC->m_pFilterGraph->QueryInterface(IID_IMediaEvent,(PVOID *) &pC->m_pMediaEvent);
	hr = pC->m_pFilterGraph->QueryInterface(IID_IMediaControl,(PVOID *) &pC->m_pMediaControl);
	hr = pC->m_pFilterGraph->QueryInterface(IID_IMediaSeeking,(PVOID *) &pC->m_pMediaSeeking);
	hr = pC->m_pFilterGraph->QueryInterface(IID_IMediaPosition,(PVOID *) &pC->m_pMediaPosition);
	hr = pC->m_pFilterGraph->QueryInterface(IID_IBasicAudio,(PVOID *) &pC->m_pBasicAudio);
//}

//SaveGraphFile(pC->m_pGraphBuilder2, L"C:\\graph.grf");
if (m_bAudioOn==true)
{
	SetVolume(VOLUME_FULL);
}
else
{
	SetVolume(VOLUME_SILENCE);
}
	//hr = m_pMediaEvent->SetNotifyWindow(hWnd, WM_GRAPHNOTIFY, NULL);


lastfile =file;
    //return hr;
	return true;


}	




HRESULT XDMDNative::DisconnectAllPins(IGraphBuilder* pGraph)
{
	HRESULT hr = S_OK;

	if (pGraph)
	{
		CComPtr<IEnumFilters> pIEnumFilters = NULL;
		hr = pGraph->EnumFilters(&pIEnumFilters);
		if (SUCCEEDED(hr))
		{
			IBaseFilter* pFilter = NULL;
			while (S_OK == pIEnumFilters->Next(1, &pFilter, NULL))
			{
				CComPtr<IEnumPins> pIEnumPins = NULL;
				hr = pFilter->EnumPins(&pIEnumPins);
				if (SUCCEEDED(hr))
				{
					IPin* pIPin = NULL;
					while (S_OK == pIEnumPins->Next(1, &pIPin, NULL))
					{
						IPin* pIPinConnection = NULL;
						if (S_OK == pIPin->ConnectedTo(&pIPinConnection))
						{
							// pins are connected, to disconnect filters, both pins must be disconnected
							hr = pGraph->Disconnect(pIPin);
							hr = pGraph->Disconnect(pIPinConnection);

							if (pIPinConnection!=NULL)
							{
							pIPinConnection->Release();
							pIPinConnection=NULL;
							}
						}

						if (pIPin!=NULL)
							{
							pIPin->Release();
							pIPin=NULL;
							}
						//SAFE_RELEASE(pIPin);
					}
				}

				if (pFilter!=NULL)
							{
							pFilter->Release();
							pFilter=NULL;
							}
				//SAFE_RELEASE(pFilter);
			}
		}
	}
	else
	{
		hr = E_INVALIDARG;
	}

	return hr;
}

BOOL XDMDNative::IsFFDShowInstalled()
{
	CComPtr<IBaseFilter> pFFDShowVideo;
	HRESULT hr = CoCreateInstance(CLSID_FFDSHOW, NULL, CLSCTX_ALL, IID_IBaseFilter, reinterpret_cast<void**>(&pFFDShowVideo));
if (pFFDShowVideo!=NULL)
{
pFFDShowVideo.Release ();
pFFDShowVideo=NULL;
}
	return SUCCEEDED(hr);
}




void XDMDNative::RemoveAllFilters(IFilterGraph2 *pFilterGraph)
{
	IEnumFilters *pEnum;
	IBaseFilter *pFilter;
	HRESULT hr;

	if (pFilterGraph == NULL)
		return;

	hr = pFilterGraph->EnumFilters(&pEnum);

	if (SUCCEEDED(hr))
	{
		pEnum->Reset();

		while (pEnum->Next(1, &pFilter, NULL) == S_OK)
		{
			pFilterGraph->RemoveFilter(pFilter);
			pEnum->Reset();

			pFilter->Release();
		}

		pEnum->Release();
	}
}

void XDMDNative::ReleaseInterfaces()
{
if (pC==NULL )
		{
return;
		}
HRESULT hr;

//if (pC->cbBuffer!=0)
//	{
		
                    //delete[] pBuffer;
					 pC->cbBuffer=0;
		
//}

OAFilterState state;
	if (pC->m_pMediaControl != NULL)
	{
////				pC->m_pSampleGrabber->SetOneShot(TRUE);
////pC->m_pSampleGrabber->SetBufferSamples(FALSE);
////		if (m_State!=PLAYER_STATE::PLAYER_STATE_Graph_Stopped1  )
////		pC->m_pSampleGrabber->SetOneShot(TRUE);
////		pC->m_pSampleGrabber->SetBufferSamples(FALSE);
////		//pC->m_pSampleGrabber->SetMediaType(NULL);
////				long Size=1;
////		long s=1;
////pC->m_pSampleGrabber->SetMediaType(NULL);
////		pC->m_pSampleGrabber->SetOneShot(FALSE);
////		pC->m_pSampleGrabber->SetBufferSamples(FALSE);
////hr = pC->m_pSampleGrabber->GetCurrentBuffer(&Size, NULL);
////long tb;
////while (Size>10)
////{
////	Sleep(10);
////		hr = pC->m_pSampleGrabber->GetCurrentBuffer(&Size, NULL);
////		hr = pC->m_pSampleGrabber->GetCurrentBuffer(&s,&tb);
////}

		if(!IsFFDShowInstalled())
	{

		pC->m_pMediaControl->Stop();





				 
	pC->m_pMediaControl->GetState(20000, &state);

		}
	//pC->m_pSampleGrabber->SetBufferSamples(FALSE);
//pC->m_pSampleGrabber->SetMediaType(NULL);
//long Size;
//hr = pC->m_pSampleGrabber->GetCurrentBuffer(&Size, NULL);
//long tb;
////while (Size>10)
////{
//	//Sleep(10);
//		hr = pC->m_pSampleGrabber->GetCurrentBuffer(&Size, NULL);
//		hr = pC->m_pSampleGrabber->GetCurrentBuffer(0,&tb);
//}
	/*	OAFilterState st;
pC->m_pMediaControl->GetState(20000,&st);*/
	
	}
//if (pC->m_pSampleGrabber != NULL)
//	{
//pC->grabberFilter->Stop();
//pC->m_pSampleGrabber->SetBufferSamples(FALSE);
//pC->m_pSampleGrabber->SetMediaType(NULL);
//
//}


//		if (pC->m_pSampleGrabber != NULL)
//	{
//if (pC->grabberFilter != NULL)
//	{
//		pC->grabberFilter.Release();
//		pC->grabberFilter = NULL;
//	}
////pC->m_pSampleGrabber->SetBufferSamples(FALSE)
//		pC->m_pSampleGrabber.Release ();
//		pC->m_pSampleGrabber = NULL;
//	}




	if (pC->m_pBasicAudio != NULL)
	{

		//pC->m_pBasicAudio->GetState(20000, &state);
		pC->m_pBasicAudio.Release();
		pC->m_pBasicAudio = NULL;
	}
	if (pC->m_pMediaPosition != NULL)
	{
		//pC->m_pMediaPosition->GetState(20000, &state);
		pC->m_pMediaPosition.Release();
		pC->m_pMediaPosition = NULL;
	}


	
	if (pC->m_pMediaSeeking != NULL)
	{
		//pC->m_pMediaSeeking->GetState(20000, &state);
		pC->m_pMediaSeeking.Release();
		pC->m_pMediaSeeking = NULL;
	}


		if (pC->m_pMediaControl != NULL)
	{
		//if (m_State!=PLAYER_STATE::PLAYER_STATE_Graph_Stopped1  )

	
	/*	OAFilterState st;
pC->m_pMediaControl->GetState(20000,&st);*/
		pC->m_pMediaControl.Release();
		pC->m_pMediaControl = NULL;
	}



	if (pC->m_pMediaEvent != NULL)
	{
		pC->m_pMediaEvent->SetNotifyWindow(NULL, 0, NULL);
		pC->m_pMediaEvent.Release();
		pC->m_pMediaEvent = NULL;
	}


if (pC->sourceFilter != NULL)
	{
		/*pC->sourceFilter->Stop();
		FILTER_STATE s;
		pC->sourceFilter->GetState(20000, &s);*/
	/*	pC->sourceFilter.Release();
		pC->sourceFilter = NULL;*/
	}
























//if (pC->pDmoWrapper != NULL)
//	{
//		//pC->pDmoWrapper->
//		pC->pDmoWrapper.Release();
//		pC->pDmoWrapper = NULL;
//	}
//if (pC->pColorConvertDMO != NULL)
//	{
//		pC->pColorConvertDMO.Release();
//		pC->pColorConvertDMO = NULL;
//	}



//if (pC->nullRenderer != NULL)
//	{
//		pC->nullRenderer.Release();
//		pC->nullRenderer = NULL;
//	}
	//	if (pC->m_pSampleGrabber != NULL)
	//{
	//	pC->m_pSampleGrabber->SetBufferSamples(FALSE);
	//	pC->m_pSampleGrabber.Release ();
	//	pC->m_pSampleGrabber = NULL;
	//}

//






	//		if (pC->grabberFilter != NULL)
	//{
	//	pC->grabberFilter.Release();
	//	pC->grabberFilter = NULL;
	//}




//
	if (pC->m_pFilterGraph != NULL)
	{
DisconnectAllPins(pC->m_pFilterGraph);
	RemoveAllFilters(pC->m_pFilterGraph);
	}
//		//pC->m_pFilterGraph->GetState(20000, &state);
//		CComPtr<IEnumFilters> pEnum = NULL;
//		hr = pC->m_pFilterGraph->EnumFilters(&pEnum);
//
//		if (SUCCEEDED(hr))
//		{
//			CComPtr<IBaseFilter> pFilter = NULL;
//
//			while (pEnum->Next(1, &pFilter, NULL) == S_OK)
//			 {
//				/* 	try
//				{*/
////pFilter->Stop();
//				//}
//				
//			/*		catch(HRESULT)
//						{
//							
//				}*/
//
//	CComPtr<IEnumPins> pEnum2 = NULL;
//	CComPtr<IPin> pPin = NULL;
//
//    hr = pFilter->EnumPins(&pEnum2);
//    if (SUCCEEDED(hr))
//		{
//    while (S_OK == pEnum2->Next(1, &pPin, NULL))
//    {
//        pC->m_pFilterGraph->Disconnect(pPin);
//
//      pPin.Release();
//pPin = NULL;
////pFilter->
////pEnum2->Reset();
//	}
//	//}
// //     //  if (SUCCEEDED(hr))
// //       {
// //           break;
// //       }
//	pEnum2 = NULL;
//	pEnum2.Release();
//    }
////if (pEnum2!=NULL)
////	
//
// 
//
//
//
//				pC-> m_pFilterGraph->RemoveFilter(pFilter);
//			
//
//				pFilter.Release();
//				
//				pFilter=NULL;
//				 pEnum->Reset();
//
//				 
//			}
//pEnum.Release();
//			pEnum = NULL;
//		}
//	}
////
//
////	if (pC->m_pFilterGraph != NULL)
////	{
////		CComPtr<IEnumFilters> pEnum = NULL;
////		hr = pC->m_pFilterGraph->EnumFilters(&pEnum);
////
////		if (SUCCEEDED(hr))
////		{
////			CComPtr<IBaseFilter> pFilter = NULL;
////
////			while (pEnum->Next(1, &pFilter, NULL) == S_OK)
////			 {
////				/* 	try
////				{*/
//////pFilter->Stop();
////				//}
////				
////			/*		catch(HRESULT)
////						{
////							
////				}*/
////				 //Sleep(60000);
////				pC-> m_pFilterGraph->RemoveFilter(pFilter);
////			
////
////				pFilter.Release();
////				
////				pFilter=NULL;
////				 pEnum->Reset();
////
////				 
////			}
////
////			pEnum = NULL;
////		}
////	}
//
//
////	if (pC->m_pFilterGraph != NULL)
////	{
////
////		//pC->m_pFilterGraph->GetState(20000, &state);
////		CComPtr<IEnumFilters> pEnum = NULL;
////		hr = pC->m_pFilterGraph->EnumFilters(&pEnum);
////
////		if (SUCCEEDED(hr))
////		{
////			CComPtr<IBaseFilter> pFilter = NULL;
////
////			while (pEnum->Next(1, &pFilter, NULL) == S_OK)
////			 {
////				/* 	try
////				{*/
//////pFilter->Stop();
////				//}
////				
////			/*		catch(HRESULT)
////						{
////							CComPtr<IEnumPins> pEnum = NULL;
////	CComPtr<IPin> pPin = NULL;
////
////    hr = pC->sourceFilter->EnumPins(&pEnum);
////    
////    while (S_OK == pEnum->Next(1, &pPin, NULL))
////    {
////        hr = ConnectFilters(pC->m_pFilterGraph, pPin, pC->grabberFilter);
////
////        pPin.Release();
////pPin = NULL;
////        if (SUCCEEDED(hr))
////        {
////            break;
////        }
////    }	
////				}*/
////				 /*pFilter->*/
////				pC-> m_pFilterGraph->RemoveFilter(pFilter);
////			
////
////				pFilter.Release();
////				
////				pFilter=NULL;
////				 pEnum->Reset();
////
////				 
////			}
////
////			pEnum = NULL;
////		}
////	}
if (pC->sourceFilter != NULL)
	{
		/*FILTER_STATE s;
		pC->sourceFilter->GetState(20000, &s);
		pC->sourceFilter->*/
		pC->sourceFilter.Release();
		pC->sourceFilter = NULL;
	}

	if (pC->m_pFilterGraph != NULL)
	{
		//pC->m_pFilterGraph->
		pC->m_pFilterGraph.Release();
		pC->m_pFilterGraph = NULL;
	}




		if (pC->m_pGraphBuilder2 != NULL)
	{
		//pC->m_pGraphBuilder2->
		pC->m_pGraphBuilder2.Release();
		pC->m_pGraphBuilder2 = NULL;
	}



}


void XDMDNative::ReleaseAllInterfacesFinal()
{
if (pC==NULL )
		{
return;
		}
HRESULT hr;

//if (pC->cbBuffer!=0)
//	{
		
                    //delete[] pBuffer;
					 pC->cbBuffer=0;
		
//}

OAFilterState state;
	if (pC->m_pMediaControl != NULL)
	{
////				pC->m_pSampleGrabber->SetOneShot(TRUE);
////pC->m_pSampleGrabber->SetBufferSamples(FALSE);
////		if (m_State!=PLAYER_STATE::PLAYER_STATE_Graph_Stopped1  )
////		pC->m_pSampleGrabber->SetOneShot(TRUE);
////		pC->m_pSampleGrabber->SetBufferSamples(FALSE);
////		//pC->m_pSampleGrabber->SetMediaType(NULL);
////				long Size=1;
////		long s=1;
////pC->m_pSampleGrabber->SetMediaType(NULL);
////		pC->m_pSampleGrabber->SetOneShot(FALSE);
////		pC->m_pSampleGrabber->SetBufferSamples(FALSE);
////hr = pC->m_pSampleGrabber->GetCurrentBuffer(&Size, NULL);
////long tb;
////while (Size>10)
////{
////	Sleep(10);
////		hr = pC->m_pSampleGrabber->GetCurrentBuffer(&Size, NULL);
////		hr = pC->m_pSampleGrabber->GetCurrentBuffer(&s,&tb);
////}

	//	if(!IsFFDShowInstalled())
	//{

		pC->m_pMediaControl->Stop();





				 
	pC->m_pMediaControl->GetState(20000, &state);

		//}
	}
	//pC->m_pSampleGrabber->SetBufferSamples(FALSE);
//pC->m_pSampleGrabber->SetMediaType(NULL);
//long Size;
//hr = pC->m_pSampleGrabber->GetCurrentBuffer(&Size, NULL);
//long tb;
////while (Size>10)
////{
//	//Sleep(10);
//		hr = pC->m_pSampleGrabber->GetCurrentBuffer(&Size, NULL);
//		hr = pC->m_pSampleGrabber->GetCurrentBuffer(0,&tb);
//}
	/*	OAFilterState st;
pC->m_pMediaControl->GetState(20000,&st);*/
	
	//}
//if (pC->m_pSampleGrabber != NULL)
//	{
//pC->grabberFilter->Stop();
//pC->m_pSampleGrabber->SetBufferSamples(FALSE);
//pC->m_pSampleGrabber->SetMediaType(NULL);
//
//}








	if (pC->m_pBasicAudio != NULL)
	{

		//pC->m_pBasicAudio->GetState(20000, &state);
		pC->m_pBasicAudio.Release();
		pC->m_pBasicAudio = NULL;
	}
	if (pC->m_pMediaPosition != NULL)
	{
		//pC->m_pMediaPosition->GetState(20000, &state);
		pC->m_pMediaPosition.Release();
		pC->m_pMediaPosition = NULL;
	}


	
	if (pC->m_pMediaSeeking != NULL)
	{
		//pC->m_pMediaSeeking->GetState(20000, &state);
		pC->m_pMediaSeeking.Release();
		pC->m_pMediaSeeking = NULL;
	}


		if (pC->m_pMediaControl != NULL)
	{
		//if (m_State!=PLAYER_STATE::PLAYER_STATE_Graph_Stopped1  )

	
	/*	OAFilterState st;
pC->m_pMediaControl->GetState(20000,&st);*/
		pC->m_pMediaControl.Release();
		pC->m_pMediaControl = NULL;
	}



	if (pC->m_pMediaEvent != NULL)
	{
		pC->m_pMediaEvent->SetNotifyWindow(NULL, 0, NULL);
		pC->m_pMediaEvent.Release();
		pC->m_pMediaEvent = NULL;
	}


//if (pC->sourceFilter != NULL)
//	{
//		/*pC->sourceFilter->Stop();
//		FILTER_STATE s;
//		pC->sourceFilter->GetState(20000, &s);*/
//	/*	pC->sourceFilter.Release();
//		pC->sourceFilter = NULL;*/
//	}
























if (pC->pDmoWrapper != NULL)
	{
		//pC->pDmoWrapper->
		pC->pDmoWrapper.Release();
		pC->pDmoWrapper = NULL;
	}
if (pC->pColorConvertDMO != NULL)
	{
		pC->pColorConvertDMO.Release();
		pC->pColorConvertDMO = NULL;
	}



if (pC->nullRenderer != NULL)
	{
		pC->nullRenderer.Release();
		pC->nullRenderer = NULL;
	}
		if (pC->m_pSampleGrabber != NULL)
	{
		pC->m_pSampleGrabber->SetBufferSamples(FALSE);
		pC->m_pSampleGrabber.Release ();
		pC->m_pSampleGrabber = NULL;
	}

//






			if (pC->grabberFilter != NULL)
	{
		pC->grabberFilter.Release();
		pC->grabberFilter = NULL;
	}




//
	if (pC->m_pFilterGraph != NULL)
	{
DisconnectAllPins(pC->m_pFilterGraph);
	RemoveAllFilters(pC->m_pFilterGraph);
	}
//		//pC->m_pFilterGraph->GetState(20000, &state);
//		CComPtr<IEnumFilters> pEnum = NULL;
//		hr = pC->m_pFilterGraph->EnumFilters(&pEnum);
//
//		if (SUCCEEDED(hr))
//		{
//			CComPtr<IBaseFilter> pFilter = NULL;
//
//			while (pEnum->Next(1, &pFilter, NULL) == S_OK)
//			 {
//				/* 	try
//				{*/
////pFilter->Stop();
//				//}
//				
//			/*		catch(HRESULT)
//						{
//							
//				}*/
//
//	CComPtr<IEnumPins> pEnum2 = NULL;
//	CComPtr<IPin> pPin = NULL;
//
//    hr = pFilter->EnumPins(&pEnum2);
//    if (SUCCEEDED(hr))
//		{
//    while (S_OK == pEnum2->Next(1, &pPin, NULL))
//    {
//        pC->m_pFilterGraph->Disconnect(pPin);
//
//      pPin.Release();
//pPin = NULL;
////pFilter->
////pEnum2->Reset();
//	}
//	//}
// //     //  if (SUCCEEDED(hr))
// //       {
// //           break;
// //       }
//	pEnum2 = NULL;
//	pEnum2.Release();
//    }
////if (pEnum2!=NULL)
////	
//
// 
//
//
//
//				pC-> m_pFilterGraph->RemoveFilter(pFilter);
//			
//
//				pFilter.Release();
//				
//				pFilter=NULL;
//				 pEnum->Reset();
//
//				 
//			}
//pEnum.Release();
//			pEnum = NULL;
//		}
//	}
////
//
////	if (pC->m_pFilterGraph != NULL)
////	{
////		CComPtr<IEnumFilters> pEnum = NULL;
////		hr = pC->m_pFilterGraph->EnumFilters(&pEnum);
////
////		if (SUCCEEDED(hr))
////		{
////			CComPtr<IBaseFilter> pFilter = NULL;
////
////			while (pEnum->Next(1, &pFilter, NULL) == S_OK)
////			 {
////				/* 	try
////				{*/
//////pFilter->Stop();
////				//}
////				
////			/*		catch(HRESULT)
////						{
////							
////				}*/
////				 //Sleep(60000);
////				pC-> m_pFilterGraph->RemoveFilter(pFilter);
////			
////
////				pFilter.Release();
////				
////				pFilter=NULL;
////				 pEnum->Reset();
////
////				 
////			}
////
////			pEnum = NULL;
////		}
////	}
//
//
////	if (pC->m_pFilterGraph != NULL)
////	{
////
////		//pC->m_pFilterGraph->GetState(20000, &state);
////		CComPtr<IEnumFilters> pEnum = NULL;
////		hr = pC->m_pFilterGraph->EnumFilters(&pEnum);
////
////		if (SUCCEEDED(hr))
////		{
////			CComPtr<IBaseFilter> pFilter = NULL;
////
////			while (pEnum->Next(1, &pFilter, NULL) == S_OK)
////			 {
////				/* 	try
////				{*/
//////pFilter->Stop();
////				//}
////				
////			/*		catch(HRESULT)
////						{
////							CComPtr<IEnumPins> pEnum = NULL;
////	CComPtr<IPin> pPin = NULL;
////
////    hr = pC->sourceFilter->EnumPins(&pEnum);
////    
////    while (S_OK == pEnum->Next(1, &pPin, NULL))
////    {
////        hr = ConnectFilters(pC->m_pFilterGraph, pPin, pC->grabberFilter);
////
////        pPin.Release();
////pPin = NULL;
////        if (SUCCEEDED(hr))
////        {
////            break;
////        }
////    }	
////				}*/
////				 /*pFilter->*/
////				pC-> m_pFilterGraph->RemoveFilter(pFilter);
////			
////
////				pFilter.Release();
////				
////				pFilter=NULL;
////				 pEnum->Reset();
////
////				 
////			}
////
////			pEnum = NULL;
////		}
////	}
if (pC->sourceFilter != NULL)
	{
		/*FILTER_STATE s;
		pC->sourceFilter->GetState(20000, &s);
		pC->sourceFilter->*/
		pC->sourceFilter.Release();
		pC->sourceFilter = NULL;
	}

	if (pC->m_pFilterGraph != NULL)
	{
		//pC->m_pFilterGraph->
		pC->m_pFilterGraph.Release();
		pC->m_pFilterGraph = NULL;
	}




		if (pC->m_pGraphBuilder2 != NULL)
	{
		//pC->m_pGraphBuilder2->
		pC->m_pGraphBuilder2.Release();
		pC->m_pGraphBuilder2 = NULL;
	}



}


int XDMDNative::VideoWidth()
{
	return W;
}

int XDMDNative::VideoPitch()
{
	return pitch;
}

int XDMDNative::VideoHeight()
{
	return H;
}


LONGLONG XDMDNative::GetDuration()
{
	HRESULT hr = S_OK;
LONGLONG duration;
	if (pC->m_pMediaControl != NULL)
	{
		hr = pC->m_pMediaSeeking->GetDuration(&duration);
		return duration;
	}

	
}
LONGLONG XDMDNative::GetCurrentPosition()
{
	LONGLONG current;
	HRESULT hr = S_OK;

	if (pC->m_pMediaControl != NULL)
	{
		hr = pC->m_pMediaSeeking->GetCurrentPosition(&current);
		return current;
	}

	
}
void XDMDNative::InternalCleanup()
{
	Stop();
	ReleaseInterfaces();
	//delete pC;

}

STDMETHODIMP XDMDNative::Pause(void)
{
	HRESULT hr;

	if (pC->m_pMediaControl != NULL)
	{
		hr = pC->m_pMediaControl->Pause();
		if (SUCCEEDED(hr))
			SetState(PLAYER_STATE::PLAYER_STATE_Graph_Paused);
	}

	return S_OK;
}


HRESULT XDMDNative::SaveGraphFile(CComPtr<ICaptureGraphBuilder2> pGraph, WCHAR *wszPath) 
{
    const WCHAR wszStreamName[] = L"ActiveMovieGraph"; 
    HRESULT hr;
    
    IStorage *pStorage = NULL;
    hr = StgCreateDocfile(
        wszPath,
        STGM_CREATE | STGM_TRANSACTED | STGM_READWRITE | STGM_SHARE_EXCLUSIVE,
        0, &pStorage);
    if(FAILED(hr)) 
    {
        return hr;
    }

    IStream *pStream;
    hr = pStorage->CreateStream(
        wszStreamName,
        STGM_WRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE,
        0, 0, &pStream);
    if (FAILED(hr)) 
    {
        pStorage->Release();    
        return hr;
    }

    IPersistStream *pPersist = NULL;
    pGraph->QueryInterface(IID_IPersistStream, (void**)&pPersist);
    hr = pPersist->Save(pStream, TRUE);
    pStream->Release();
    pPersist->Release();
    if (SUCCEEDED(hr)) 
    {
        hr = pStorage->Commit(STGC_DEFAULT);
    }
    pStorage->Release();
    return hr;
}


STDMETHODIMP XDMDNative::SetRate(double rate)
{
	HRESULT hr = S_OK;

	if (pC->m_pMediaControl != NULL)
	{
		
		
		hr = pC->m_pMediaSeeking->SetRate (rate);
		

	}

	return S_OK;
}

STDMETHODIMP XDMDNative::Seek(LONGLONG position)
{
	HRESULT hr = S_OK;

	if (pC->m_pMediaControl != NULL)
	{
		LONGLONG now = position;
			if (SUCCEEDED(hr))
			SetState(PLAYER_STATE::PLAYER_STATE_Playing);
		hr = pC->m_pMediaSeeking->SetPositions(&now, AM_SEEKING_AbsolutePositioning, NULL, AM_SEEKING_NoPositioning);
		//hr = pC->m_pMediaSeeking->SetRate (.1);

	}

	return S_OK;
}

void XDMDNative::Converto8bitGray(int w, int h, int depth, array<Byte> ^argbvalues, array<Byte> ^arr)
{
		int b3 = 0;
		int l = 0;
		switch (depth)
		{
			case 4:
				for (int y = 0; y < h; y++)
				{
					for (int x = 0; x < w; x++)
					{
						l = (((w * 4) * y) + (x * 4));
						if (argbvalues[l] > 0)
						{
							b3 = (int)(((int)(argbvalues[l + 1]) + +(int)(argbvalues[l + 2]) + (int)(argbvalues[l + 3])) / 3.0);
						}
						else
						{
							b3 = 0;
						}
						arr[x + (y * w)] = (char)(b3);
					}
				}
				break;
			case 3:
				for (int y = 0; y < h; y++)
				{
					for (int x = 0; x < w; x++)
					{
						l = (((w * 3) * y) + (x * 3));
						b3 = (int)(((int)(argbvalues[l]) + +(int)(argbvalues[l + 1]) + (int)(argbvalues[l + 2])) / 3.0);
						arr[x + (y * w)] = (char)(b3);
					}
				}
				break;
		}
	}


void XDMDNative::Render(System::Drawing::Bitmap ^Source, array<Byte> ^Buffer)
{
		 
BitmapData ^data = Source->LockBits(System::Drawing::Rectangle(System::Drawing::Point::Empty, Source->Size), ImageLockMode::ReadWrite, System::Drawing::Imaging::PixelFormat::Format8bppIndexed);
	   unsigned char* Buf = reinterpret_cast<unsigned char*>((data->Scan0).ToPointer());	


	  int w=Source->Size.Width;
		  int h=Source->Size.Height;
		  //color=color * 16;
		  int color=0;
		
		  int xb=0;
		  int yb=0;
		  
	   for (int y = 0; y < (h); y += 6)
			   {
				   
				   xb=0;
				   for (int x = 0; x < (w);  x += 6 )
				   {
					   color=Buffer[xb + (yb * 128)];
								if (color < 16 )
								{
									color=color * 17;
									for (int y2 = (y); y2 < (y+5); y2++)
									{
										for (int x2 = (x); x2 < (x+5); x2++)
										{
											Buf[x2 + (y2 * w)]=color;
										}
									}
								}
						xb++;
					}
					yb++;
				}
	   Source->UnlockBits (data);
}

				   

void XDMDNative::Render(long Source,int w, int h, array<Byte> ^Buffer)
{


		 

	   unsigned char* Buf = reinterpret_cast<unsigned char*>(Source);	

	 /* int m=(Source->Size.Width -1) * (Source->Size.Height -1);
	  int w=Source->Size.Width;
		  int h=Source->Size.Height;*/
		  //color=color * 16;
		  int color=0;
		
		  int xb=0;
		  int yb=0;
		  
	   for (int y = 0; y < (h); y += 6)
			   {
				   
				   xb=0;
				   for (int x = 0; x < (w);  x += 6 )
				   {
					   for (int y2 = (y); y2 < (y+5); y2++)
						{
						for (int x2 = (x); x2 < (x+5); x2++)
							{
								color=Buffer[xb + (yb * 128)];
								if (color < 16 )
								{
									color=color * 16;
								if (color>255)
			  color=255;

							Buf[x2 + (y2 * w)]=color;
								}

							}
					   }
					   xb++;
					}
				   yb++;
				}
	   //Source->UnlockBits (data);
}




void XDMDNative::Clear(System::Drawing::Bitmap ^Source, int color)
{
		 
BitmapData ^data = Source->LockBits(System::Drawing::Rectangle(System::Drawing::Point::Empty, Source->Size), ImageLockMode::ReadWrite, System::Drawing::Imaging::PixelFormat::Format8bppIndexed);
	   unsigned char* Buf = reinterpret_cast<unsigned char*>((data->Scan0).ToPointer());	

	  int m=(Source->Size.Width -1) * (Source->Size.Height -1);
	  int w=Source->Size.Width;
		  int h=Source->Size.Height;
		  color=color * 16;
		  if (color>255)
			  color=255;
		  if (color<0)
			  color=0;

	   for (int y = 0; y < (h); y += 6)
			   {
				   for (int x = 0; x < (w);  x += 6 )
				   {
					   for (int y2 = (y); y2 < (y+5); y2++)
						{
						for (int x2 = (x); x2 < (x+5); x2++)
							{
							Buf[x2 + (y2 * w)]=color;
						}
					   }
					}
				}
	   Source->UnlockBits (data);
}

				   






void XDMDNative::Clear(array<Byte> ^Source, long Size,int color)
{
		 
	/* color=color * 16;
		  if (color>255)
			  color=255;
		  if (color<0)
			  color=0;*/
	pin_ptr<System::Byte> p = &Source[0];
	memset(p,color,Size);

//		return;
//for (int x = 0; x <= Size; x++)
//					{
//						Source[x]=color;
//}

}




void XDMDNative::Clear(long Source, long Size,int color)
{
	 color=color * 16;
		  if (color>255)
			  color=255;
		  if (color<0)
			  color=0;	 
	
unsigned char* buf = reinterpret_cast<unsigned char*>(Source);

for (int x = 0; x <= Size; x++)
					{
						buf[x]=color;
}

}


void XDMDNative::Converto8bitGrayFlipY(int w, int h, int depth, long Source, array<Byte> ^arr)
{
		int b3 = 0;
		int l = 0;
unsigned char* argbvalues = reinterpret_cast<unsigned char*>(Source);

		switch (depth)
		{
			case 4:
				for (int y = (w-1); y > -1; y--)
				{
					for (int x = 0; x < w; x++)
					{
						l = (((w * 4) * y) + (x * 4));
						if (argbvalues[l] > 0)
						{
							b3 = (int)(((int)(argbvalues[l + 1]) + +(int)(argbvalues[l + 2]) + (int)(argbvalues[l + 3])) / 3.0);
						}
						else
						{
							b3 = 0;
						}
						arr[x + (((h-1)-y) * w)] = (char)(b3);
					}
				}
				break;
			case 3:
				for (int y = 0; y < w; y++)
				{
					for (int x = 0; x < w; x++)
					{
						l = (((w * 3) * y) + (x * 3));
						b3 = (int)(((int)(argbvalues[l]) + +(int)(argbvalues[l + 1]) + (int)(argbvalues[l + 2])) / 3.0);
						arr[x + (((h-1)-y) * w)] = (char)(b3);
					}
				}
				break;
		}
	}


void XDMDNative::Converto4bitGrayFlipY(int w, int h, int depth, long Source, array<Byte> ^arr)
{
		int b3 = 0;
		int l = 0;
unsigned char* argbvalues = reinterpret_cast<unsigned char*>(Source);

		switch (depth)
		{
			case 4:
				for (int y = (w-1); y > -1; y--)
				{
					for (int x = 0; x < w; x++)
					{
						l = (((w * 4) * y) + (x * 4));
						if (argbvalues[l] > 0)
						{
							b3 = (int)(((int)(argbvalues[l + 1]) + +(int)(argbvalues[l + 2]) + (int)(argbvalues[l + 3])) / (3 *16));
						}
						else
						{
							b3 = 0;
						}
						arr[x + (((h-1)-y) * w)] = (char)(b3);
					}
				}
				break;
			case 3:
				for (int y = 0; y < h; y++)
				{
					for (int x = 0; x < w; x++)
					{
						l = (((w * 3) * y) + (x * 3));
						b3 = (int)(((int)(argbvalues[l]) + +(int)(argbvalues[l + 1]) + (int)(argbvalues[l + 2])) / (3 *16));
						arr[x + (((h-1)-y) * w)] = (char)(b3);
					}
				}
				break;
		}
	}




void XDMDNative::Converto4bitGray(int w, int h, int depth, array<Byte> ^argbvalues, array<Byte> ^arr)
{
	int b3 = 0;
	int l = 0;
	switch (depth)
	{
		case 4:
			for (int y = 0; y < h; y++)
			{
				for (int x = 0; x < w; x++)
				{
					l = (((w * 4) * y) + (x * 4));
					if (argbvalues[l] > 0)
					{
						b3 = (int)((((int)(argbvalues[l + 1]) + +(int)(argbvalues[l + 2]) + (int)(argbvalues[l + 3])) / 3.0) / 16);
					}
					else
					{
						b3 = 0;
					}
					arr[x + (y * w)] = (char)(b3);
				}
			}
			break;
		case 3:
			for (int y = 0; y < h; y++)
			{
				for (int x = 0; x < w; x++)
				{
					l = (((w * 3) * y) + (x * 3));
					b3 = (int)((((int)(argbvalues[l]) + +(int)(argbvalues[l + 1]) + (int)(argbvalues[l + 2])) / 3.0) / 16);
					arr[x + (y * w)] = (char)(b3);
				}
			}
			break;
	}
//.h file code:
}



void XDMDNative::Converto4bitGrayFlipY(int w, int h, int depth, array<Byte> ^argbvalues, array<Byte> ^arr)
{
	int b3 = 0;
	int l = 0;
	switch (depth)
	{
		case 4:
			for (int y = 0; y < h; y++)
			{
				for (int x = 0; x < w; x++)
				{
					l = (((w * 4) * y) + (x * 4));
					/*if (argbvalues[l] > 0)
					{*/
						//b3 = (int)(((int)(argbvalues[l + 1]) + (int)(argbvalues[l + 2]) + (int)(argbvalues[l + 3])) / 48) ;
						/*if (b3>15)
							b3=15;*/
					/*}
					else
					{
						b3 = 0;
					}*/
					arr[x + (((h-1)-y) * w)] = (int)(((int)(argbvalues[l + 1]) + (int)(argbvalues[l + 2]) + (int)(argbvalues[l + 3])) / 48) ;
				}
			}
			break;
		case 3:
			for (int y = 0; y < h; y++)
			{
				for (int x = 0; x < w; x++)
				{
					l = (((w * 3) * y) + (x * 3));
					//b3 = (int)((((int)(argbvalues[l]) + (int)(argbvalues[l + 1]) + (int)(argbvalues[l + 2])) / 3.0) / 16);
					arr[x + (((h-1)-y) * w)] = (int)(((int)(argbvalues[l]) + (int)(argbvalues[l + 1]) + (int)(argbvalues[l + 2])) / 48);
				}
			}
			break;

		case 2:
			for (int y = 0; y < h; y++)
			{
				for (int x = 0; x < w; x++)
				{
					l = (((w * 2) * y) + (x * 2));
					//b3 = (int)((((int)(argbvalues[l]) + (int)(argbvalues[l + 1]) + (int)(argbvalues[l + 2])) / 3.0) / 16);
					arr[x + (((h-1)-y) * w)] = (char)(((int)(argbvalues[l]) + (int)(argbvalues[l + 1]) ) /32) ;
				}
			}
			break;
	}

	}
//.h file code:
//}

void XDMDNative::Converto4bitGrayFont(int w, int h, int depth, System::Drawing::Bitmap^ Source, array<Byte> ^arr)
{
	   int b3 = 0;
	   int l = 0;
	   BitmapData ^data = Source->LockBits(System::Drawing::Rectangle(System::Drawing::Point::Empty, Source->Size), ImageLockMode::ReadWrite, System::Drawing::Imaging::PixelFormat::Format32bppPArgb);
	   unsigned char* argbvalues = reinterpret_cast<unsigned char*>((data->Scan0).ToPointer());
	   switch (depth)
	   {
		   case 4:
			   for (int y = 0; y < h; y++)
			   {
				   for (int x = 0; x < w; x++)
				   {
					   l = (((w * 4) * y) + (x * 4));
					  if (argbvalues[l] > 0)
					{
						b3 = (int)((((int)(argbvalues[l + 1]) + (int)(argbvalues[l + 2]) + (int)(argbvalues[l + 3])) / 3.0) / 16);

						b3=15;
						/*if ((int)(argbvalues[l ])==255 && (int)(argbvalues[l + 1])==255 && (int)(argbvalues[l + 2])==255 && (int)(argbvalues[l + 3])==255)
							b3=16;*/
					}
					else
					{
						b3 = 16;
					}
					  //b3 = 13;
					   arr[x + (y * w)] = (char)(b3);
				   }
			   }
			   break;
		   case 3:
			   for (int y = 0; y < h; y++)
			   {
				   for (int x = 0; x < w; x++)
				   {
					   l = (((w * 3) * y) + (x * 3));
					   b3 = (int)((((int)(argbvalues[l]) + +(int)(argbvalues[l + 1]) + (int)(argbvalues[l + 2])) / 3.0) / 16);
					   arr[x + (y * w)] = (char)(b3);
				   }
			   }
			   break;
	   }
Source->UnlockBits (data);
   }

void XDMDNative::Converto4bitGray(int w, int h, int depth, System::Drawing::Bitmap^ Source, array<Byte> ^arr)
{
	   int b3 = 0;
	   int l = 0;
	   BitmapData ^data ;
		    unsigned char* argbvalues ;
	   
	   switch (depth)
	   {
		   case 4:
			   data= Source->LockBits(System::Drawing::Rectangle(System::Drawing::Point::Empty, Source->Size), ImageLockMode::ReadWrite, System::Drawing::Imaging::PixelFormat::Format32bppArgb);
			  argbvalues= reinterpret_cast<unsigned char*>((data->Scan0).ToPointer());
			   for (int y = 0; y < h; y++)
			   {
				   for (int x = 0; x < w; x++)
				   {
					   l = (((w * 4) * y) + (x * 4));
					  if (argbvalues[l] > 10)
					{
						b3 = (int)(((double)((double)((int)argbvalues[l + 1]) + (int)(argbvalues[l + 2]) + (int)(argbvalues[l + 3])) / 48) );
						if (b3>15)
							b3=15;
					}
					else
					{
						b3 = 16;
					}
					   arr[x + (y * w)] = b3;
				   }
			   }
			   Source->UnlockBits (data);
			   break;
		   case 3:
			    data= Source->LockBits(System::Drawing::Rectangle(System::Drawing::Point::Empty, Source->Size), ImageLockMode::ReadWrite, System::Drawing::Imaging::PixelFormat::Format32bppArgb);
			  argbvalues= reinterpret_cast<unsigned char*>((data->Scan0).ToPointer());
			   for (int y = 0; y < h; y++)
			   {
				   for (int x = 0; x < w; x++)
				   {
					   l = (((w * 4) * y) + (x * 4));
					  if (argbvalues[l] > 10)
					{
						b3 = (int)(((double)((double)((int)argbvalues[l + 1]) + (int)(argbvalues[l + 2]) + (int)(argbvalues[l + 3])) / 48) );
						if (b3>15)
							b3=15;
					}
					else
					{
						b3 = 0;
					}
					   arr[x + (y * w)] = b3;
				   }
			   }
			   Source->UnlockBits (data);
	   }

   }


void XDMDNative::Converto4bitGray(int w, int h, int depth, long Source, array<Byte> ^arr)
{
	   int b3 = 0;
	   int l = 0;
	   //BitmapData ^data = Source->LockBits(System::Drawing::Rectangle(System::Drawing::Point::Empty, Source->Size), ImageLockMode::ReadWrite, System::Drawing::Imaging::PixelFormat::Format32bppPArgb);
	   unsigned char* argbvalues = reinterpret_cast<unsigned char*>(Source);
	   switch (depth)
	   {
		   case 4:
			   for (int y = 0; y < h; y++)
			   {
				   for (int x = 0; x < w; x++)
				   {
					   l = (((w * 4) * y) + (x * 4));
					  if (argbvalues[l] > 10)
					{
						b3 = (int)((((double)(int)(argbvalues[l + 1])  +(int)(argbvalues[l + 2]) + (int)(argbvalues[l + 3])) / 3.0) / 16);
						arr[x + (y * w)] =b3;
					}
					else
					{
						//b3 = 0;
					}
					   
				   }
			   }
			   break;
		   case 3:
			   for (int y = 0; y < h; y++)
			   {
				   for (int x = 0; x < w; x++)
				   {
					   l = (((w * 3) * y) + (x * 3));
					   b3 = (int)((((int)(argbvalues[l]) + +(int)(argbvalues[l + 1]) + (int)(argbvalues[l + 2])) / 3.0) / 16);
					   arr[x + (y * w)] = (char)(b3);
				   }
			   }
			   break;
	   }

   }



void XDMDNative::Converto8bitGray(int w, int h, int depth, System::Drawing::Bitmap ^Source, array<Byte> ^arr)
{
	   int b3 = 0;
	   int l = 0;
	   BitmapData ^data = Source->LockBits(System::Drawing::Rectangle(System::Drawing::Point::Empty, Source->Size), ImageLockMode::ReadWrite, System::Drawing::Imaging::PixelFormat::Format32bppPArgb);
	   unsigned char* argbvalues = reinterpret_cast<unsigned char*>((data->Scan0).ToPointer());
	   switch (depth)
	   {
		   case 4:
			   for (int y = 0; y < h; y++)
			   {
				   for (int x = 0; x < w; x++)
				   {
					   l = (((w * 4) * y) + (x * 4));
					  if (argbvalues[l] > 0)
					{
						b3 = (int)((((int)(argbvalues[l + 1]) + +(int)(argbvalues[l + 2]) + (int)(argbvalues[l + 3])) / 3.0) );
					}
					else
					{
						b3 = 0;
					}
					   arr[x + (y * w)] = (char)(b3);
				   }
			   }
			   break;
		   case 3:
			   for (int y = 0; y < h; y++)
			   {
				   for (int x = 0; x < w; x++)
				   {
					   l = (((w * 3) * y) + (x * 3));
					   b3 = (int)((((int)(argbvalues[l]) + +(int)(argbvalues[l + 1]) + (int)(argbvalues[l + 2])) / 3.0) );
					   arr[x + (y * w)] = (char)(b3);
				   }
			   }
			   break;
	   }
	   Source->UnlockBits (data);
   }

void XDMDNative::Converto8bitGray(int w, int h, int depth,long Source, array<Byte> ^arr)
{
	   int b3 = 0;
	   int l = 0;
	   //BitmapData ^data = Source->LockBits(System::Drawing::Rectangle(System::Drawing::Point::Empty, Source->Size), ImageLockMode::ReadWrite, System::Drawing::Imaging::PixelFormat::Format32bppPArgb);
	   unsigned char* argbvalues = reinterpret_cast<unsigned char*>(&Source);
	   switch (depth)
	   {
		   case 4:
			   for (int y = 0; y < h; y++)
			   {
				   for (int x = 0; x < w; x++)
				   {
					   l = (((w * 4) * y) + (x * 4));
					  if (argbvalues[l] > 0)
					{
						b3 = (int)((((int)(argbvalues[l + 1]) + +(int)(argbvalues[l + 2]) + (int)(argbvalues[l + 3])) / 3.0) );
					}
					else
					{
						b3 = 0;
					}
					   arr[x + (y * w)] = (char)(b3);
				   }
			   }
			   break;
		   case 3:
			   for (int y = 0; y < h; y++)
			   {
				   for (int x = 0; x < w; x++)
				   {
					   l = (((w * 3) * y) + (x * 3));
					   b3 = (int)((((int)(argbvalues[l]) + +(int)(argbvalues[l + 1]) + (int)(argbvalues[l + 2])) / 3.0) );
					   arr[x + (y * w)] = (char)(b3);
				   }
			   }
			   break;
	   }
}



void XDMDNative::Draw(array<Byte> ^SrcBuffer, array<Byte> ^DisplayBuf, int SrcWidth, int SrcHeight, System::Drawing::Rectangle ^SrcRect, System::Drawing::Rectangle ^DesRect, int Brightness, bool FlipX, bool FlipY,double SrcRectScale,double DesRectScale)
{
	Draw(SrcBuffer,DisplayBuf,SrcWidth,SrcHeight,128,32,SrcRect,DesRect,Brightness,FlipX,FlipY,SrcRectScale,DesRectScale);

}

void XDMDNative::Draw(array<Byte> ^SrcBuffer, array<Byte> ^DisplayBuf, int SrcWidth, int SrcHeight,int DesWidth, int DesHeight, System::Drawing::Rectangle ^SrcRect, System::Drawing::Rectangle ^DesRect, int Brightness, bool FlipX, bool FlipY,double SrcRectScale,double DesRectScale)
{

	


	if (SrcRectScale !=1)
		SrcRect=ScaleRectangle(SrcRect,SrcRectScale);
	if (DesRectScale !=1)
		DesRect=ScaleRectangle(DesRect,DesRectScale);

	int newcol=0;
	double x = DesRect->X;
	double y = DesRect->Y;





			if (SrcRect->X<0)
	{
		double ScaleW2 = DesRect->Width / safe_cast<double>(SrcRect->Width );
		x+=Math::Abs(SrcRect->X)*(ScaleW2);
		
		SrcRect->X=0;
		
	}

	double ScaleW = DesRect->Width / safe_cast<double>(SrcRect->Width);
	double ScaleW2 = DesRect->Width / safe_cast<double>(SrcRect->Width);
	double ScaleWF = SrcRect->Width / safe_cast<double>(DesRect->Width);
	double ScaleSW = SrcRect->Width / safe_cast<double>(DesRect->Width);
	if (ScaleSW<1)
	{
		ScaleWF=ScaleSW;
		ScaleSW=1;
		
	}
	else
	{
		ScaleWF=ScaleSW;
		ScaleW=1;
	}

	
		if (SrcRect->Y<0)
	{
		double ScaleH2 = DesRect->Height / safe_cast<double>(SrcRect->Height);
		
		y+=(Math::Abs(SrcRect->Y)*(ScaleH2));
		
		SrcRect->Y=0;
		
		
	}


	double ScaleH = DesRect->Height / safe_cast<double>(SrcRect->Height);
	double ScaleH2 = DesRect->Height / safe_cast<double>(SrcRect->Height);
	double ScaleHF = SrcRect->Height / safe_cast<double>(DesRect->Height);

	double ScaleSH = SrcRect->Height / safe_cast<double>(DesRect->Height);
	
	if (ScaleSH<1)
	{
		
		ScaleHF=ScaleSH;
		ScaleSH=1;
	}
	else
	{
		ScaleHF=ScaleSH;
		ScaleH=1;
		
	}

	
	int YI = 0;
	int XI = 0;
	int FinalX = 0;
	int FinalY = 0;
	int maxw =SrcRect->X + (SrcRect->Width - 1);


	if (maxw >= (((SrcRect->X) )+ (((DesWidth ) - x) *ScaleWF))-1)

		maxw= (((SrcRect->X) )+ (((DesWidth )-x) *ScaleWF)-1);
	//}

	int maxh =SrcRect->Y + (SrcRect->Height  - 1);



		if (maxh >= (((SrcRect->Y) )+ (((DesHeight-( (y)) ) *ScaleHF)))-1)
		{
			maxh= (((SrcRect->Y) )+ (((DesHeight-( (y)) ) *ScaleHF))-1);
			/*	IntPtr ptr = Marshal::StringToHGlobalUni(System::Convert::ToString (maxh/ScaleSH));
LPCWSTR str = reinterpret_cast<LPCWSTR>(ptr.ToPointer());*/
			//MessageBox(NULL,str, (LPCTSTR)"", 0);
			
		}

				if (maxh >= ((SrcHeight )))
		{
			maxh= ((SrcHeight )-1);

			
		}



		if (maxw >= ((SrcWidth )))
		{
			maxw= ((SrcWidth )-1);

//			
		}
		double origx=x;
//		

	for (double srcy = SrcRect->Y; srcy <=maxh ; srcy+=ScaleSH )
	{
		
		
			
			YI = (int)Math::Round(y + ScaleH, 0) -1;
		//if (YI<y)
			//YI=y;
			for (int iy = (int)y; iy <= YI; iy++)
			{
				
				if (iy>=0)
			{
				FinalY = (int)iy;
							if (FlipY)
							{
								FinalY = (DesHeight-1 )- FinalY;
							}
				x = origx;

				
		
				for (double srcx = SrcRect->X; srcx <= maxw ; srcx+=ScaleSW )
				{
		
				if (SrcBuffer[(int)srcx + ((int)srcy * SrcWidth)] < 16)
							{
		
					XI = (int)Math::Round(x + ScaleW, 0) -1;
					
					
						
					for (int ix =(int)x; ix <= XI; ix++)
					{
		
							if (ix >= 0)
						{
						

		
										DisplayBuf[ix + (FinalY * DesWidth)] = (int)(((double)((SrcBuffer[(int)srcx + ((int)srcy * SrcWidth)] )/ 15.0) * Brightness)  );
										
								}
								
								
					
							
						}

						
						
						
					}
						
					
					
				x += ScaleW;
				}
					
			
				

			}
			
			
			

		}
		y += ScaleH;
		

	}
}



void XDMDNative::DrawVideo(array<Byte> ^SrcBuffer, array<Byte> ^DisplayBuf, int SrcWidth, int SrcHeight,int DesWidth, int DesHeight, System::Drawing::Rectangle ^SrcRect, System::Drawing::Rectangle ^DesRect, int Brightness, bool FlipX, bool FlipY,double SrcRectScale,double DesRectScale)
{

	


	if (SrcRectScale !=1)
		SrcRect=ScaleRectangle(SrcRect,SrcRectScale);
	if (DesRectScale !=1)
		DesRect=ScaleRectangle(DesRect,DesRectScale);

	int newcol=0;
	double x = DesRect->X;
	double y = DesRect->Y;





			if (SrcRect->X<0)
	{
		double ScaleW2 = DesRect->Width / safe_cast<double>(SrcRect->Width );
		x+=Math::Abs(SrcRect->X)*(ScaleW2);
		
		SrcRect->X=0;
		
	}

	double ScaleW = DesRect->Width / safe_cast<double>(SrcRect->Width);
	double ScaleW2 = DesRect->Width / safe_cast<double>(SrcRect->Width);
	double ScaleWF = SrcRect->Width / safe_cast<double>(DesRect->Width);
	double ScaleSW = SrcRect->Width / safe_cast<double>(DesRect->Width);
	if (ScaleSW<1)
	{
		ScaleWF=ScaleSW;
		ScaleSW=1;
		
	}
	else
	{
		ScaleWF=ScaleSW;
		ScaleW=1;
	}

	
		if (SrcRect->Y<0)
	{
		double ScaleH2 = DesRect->Height / safe_cast<double>(SrcRect->Height);
		
		y+=(Math::Abs(SrcRect->Y)*(ScaleH2));
		
		SrcRect->Y=0;
		
		
	}


	double ScaleH = DesRect->Height / safe_cast<double>(SrcRect->Height);
	double ScaleH2 = DesRect->Height / safe_cast<double>(SrcRect->Height);
	double ScaleHF = SrcRect->Height / safe_cast<double>(DesRect->Height);

	double ScaleSH = SrcRect->Height / safe_cast<double>(DesRect->Height);
	
	if (ScaleSH<1)
	{
		
		ScaleHF=ScaleSH;
		ScaleSH=1;
	}
	else
	{
		ScaleHF=ScaleSH;
		ScaleH=1;
		
	}

	
	int YI = 0;
	int XI = 0;
	int FinalX = 0;
	int FinalY = 0;
	int maxw =SrcRect->X + (SrcRect->Width - 1);


	if (maxw >= (((SrcRect->X) )+ (((DesWidth ) - x) *ScaleWF))-1)

		maxw= (((SrcRect->X) )+ (((DesWidth )-x) *ScaleWF)-1);
	//}

	int maxh =SrcRect->Y + (SrcRect->Height  - 1);



		if (maxh >= (((SrcRect->Y) )+ (((DesHeight-( (y)) ) *ScaleHF)))-1)
		{
			maxh= (((SrcRect->Y) )+ (((DesHeight-( (y)) ) *ScaleHF))-1);

			
		}

				if (maxh >= ((SrcHeight )))
		{
			maxh= ((SrcHeight )-1);

			
		}



		if (maxw >= ((SrcWidth )))
		{
			maxw= ((SrcWidth )-1);

//			
		}
		double origx=x;
//		
		int b=0;

		int l=0;
//		int d=DesRect->Height_

		//for (double srcy = SrcRect->Y; srcy <= DesRect->Height ; srcy+=1 )
y+=ScaleH*(DesRect->Height)-1;
		maxh=((DesRect->Height-1)*ScaleHF)+maxh;
		/*if (DesRect->Y<0)
			maxh+=Math::Abs (DesRect->Y)*ScaleSH;*/
		 //if ((int)maxh>SrcHeight-1)
			// //maxh=SrcHeight-1;
		double srcstart=0;
		for (srcstart = SrcRect->Y; srcstart <= maxh; srcstart+=ScaleSH )
	{
					if (y<=DesHeight-ScaleH )
					break;
					y-=ScaleH;
		}
		 /*if ((int)maxh>SrcHeight-1)
			 maxh=SrcHeight-1;*/
	for (double srcy = (int)srcstart; srcstart <= maxh; srcy+=ScaleSH )
	{
	
		/*if ((int)srcy>SrcHeight-1)
			break;*/
		/*{*/
		//{
		if (y<0)
			break;
			YI = (int)Math::Round(y + ScaleH, 0) -1;
		
			for (int iy = YI; iy >= (int)y; iy--)
			{
				
			
				//FinalY =  (int)iy;
							/*if (FlipY)
							{*/
								//FinalY = ;
							//}
				
				
				/*if (iy>DesHeight-1 )
					break;*/
		x = origx;
				for (double srcx = SrcRect->X; srcx <= maxw ; srcx+=ScaleSW )
				{
		
				/*if (SrcBuffer[(int)srcx + ((int)srcy * SrcWidth)] < 16)
							{*/
		
					XI = (int)Math::Round(x + ScaleW, 0) -1;
					
					
						
					for (int ix =(int)x; ix <= XI; ix++)
					{
		
							if (ix >= 0)
						{
						l = ((((int)SrcWidth  * 3) * (int)srcy) + ((int)srcx * 3));
					b= (int)((((int)(SrcBuffer[l]) + (int)(SrcBuffer[l + 1]) + (int)(SrcBuffer[l + 2])) / 3.0) / 16);
					//arr[x + (((h-1)-y) * w)] = (int)(((int)(SrcBuffer[l]) + (int)(SrcBuffer[l + 1]) + (int)(SrcBuffer[l + 2])) / 48);

										DisplayBuf[ix + (iy * DesWidth)] =(int)((((double)((int)(SrcBuffer[l]) + (int)(SrcBuffer[l + 1]) + (int)(SrcBuffer[l + 2])) / 48) /15)*Brightness ) ;
										
						}
								
								
					
							
					}

						
						
						
			
						
					
					
				x += ScaleW;
			
					
			
				

			}
			
			
			

		//}
		}
		y -= ScaleH;
		

	}
}


	System::Drawing::Rectangle^ XDMDNative::ScaleRectangle(System::Drawing::Rectangle ^R, double Scale)
{
	System::Drawing::Rectangle ^origr =  System::Drawing::Rectangle(R->X, R->Y, R->Width, R->Height);


	R->Width = (int)(R->Width * Scale);
	R->Height = (int)(R->Height * Scale);
	R->X -= (int)((R->Width / 2.0) - (origr->Width / 2.0));
	R->Y -= (int)((R->Height / 2.0) - (origr->Height / 2.0));
	
	return R;

}



	void XDMDNative::renderDMDFrame(int width, int height, array<Byte> ^currbuffer)
	{


			int byteIdx=4;
	int bd0,bd1,bd2,bd3;
	int pixel;
	int i,j,v;
	int ret = 0;
	unsigned char frame_buf[2052];

	memset(frame_buf,0,2052);
   frame_buf[0] = 0x81;	// frame sync bytes
	frame_buf[1] = 0xC3;
	frame_buf[2] = 0xE7;
	frame_buf[3] = 0x0;		// command byte (not used)

	// dmd height
	for(j = 0; j < height; j++) {
		// dmd width
		for(i = 0; i < width; i+=8) {
			bd0 = 0;
			bd1 = 0;
			bd2 = 0;
			bd3 = 0;
			for (v = 7; v >= 0; v--) {
				// pixel colour
				pixel = currbuffer[(j*128) + (i+v)];
				// 16 color mode hue remapping for proper gradient
				bd0 <<= 1;
				bd1 <<= 1;
				bd2 <<= 1;
				bd3 <<= 1;
				//bd4 <<= 1;
				if(pixel & 1)
					bd0 |= 1;
				if(pixel & 2)
					bd1 |= 1;
				if(pixel & 4)
					bd2 |= 1;
				if(pixel & 8)
					bd3 |= 1;
			}
			frame_buf[byteIdx]      = bd0;
			frame_buf[byteIdx+512]  = bd1;
			frame_buf[byteIdx+1024] = bd2;
			frame_buf[byteIdx+1536] = bd3;
			byteIdx++;
		}
	}

  //writeBuffer[0]=0;
  //usb_bulk_write(device, EP_OUT, writeBuffer, 1, 5000);
  //usb_bulk_read(device, EP_IN, readBuffer, 1, 5000);
  memcpy(pC->writeBuffer ,frame_buf,2052);
  usb_bulk_write(device, EP_OUT, pC->writeBuffer , 2052, 5000);
  //printf("frame sent: %s\n",usb_strerror());


  /*memcpy(writeBuffer,frame_buf,2048);
	ret = usb_submit_async( asyncWriteContext, writeBuffer, sizeof( writeBuffer ) );
	if( ret < 0 )
    printf("error usb_submit_async:\n%s\n", usb_strerror());

   //wait for read and write transfers to complete or 5 seconds
   usb_reap_async( asyncWriteContext, 5000 );*/



	}

	bool XDMDNative::InitPinDMD2()
	{
		int ret = 0;

    //init usb library
    usb_init();
    //find busses
    usb_find_busses();
    //find devices
    usb_find_devices();

    //try to open our device
    if( !( device = open_dev() ) ){
        //if not successfull, print error message
        //printf("error opening pinDMD2 device: \n");
        //and exit
        return false;
    }
    //else notify that device was opened
    else
        //printf("pinDMD2 device opened\n");

    //set configuration
    if( usb_set_configuration( device, MY_CONFIG ) < 0 ){
        //if not succesfull, notify
        //printf("error setting configuration\n");
        //close device
        usb_close( device );
        //and exit
        return false;
    }
    //if successfull, notify
    else
        //printf("configuration set\n");

    //try to claim interface for use
    if( usb_claim_interface( device, MY_INTF ) < 0 ){
        //if failed, print error message
        //printf("error claiming interface\n");
        //close device and exit
        usb_close( device );
        return false;
    }
    //if successfull, notify
 return true;
	}



	bool XDMDNative::DisposePinDMD2()
	{

		    //clean up.
    //kitten dies every time you don't clean up after yourself.
    //free context handlers
    usb_free_async( &pC->asyncWriteContext );
    //relese interface
    usb_release_interface( device, MY_INTF );
    //close device and exit
    usb_close( device );
	return true;
	}



usb_dev_handle* XDMDNative::open_dev( void )
{
  //contains usb busses present on computer
  struct usb_bus *bus;
  //contains devices present on computer
  struct usb_device *dev;
  //used to skip first device
  //bool first = true;
  //loop through busses and devices
  for (bus = usb_get_busses(); bus; bus = bus->next){
    for (dev = bus->devices; dev; dev = dev->next){
      //if device vendor id and product id are match
      if (dev->descriptor.idVendor == VID && dev->descriptor.idProduct == PID)
        return usb_open(dev);
    }
  }
  //return null if no devices were found
  return NULL;
}




   




	


