/** Asyncronous callback */
STDMETHODIMP FImfByteStream::Invoke( IMFAsyncResult* pResult )
{
	HRESULT HResult = S_OK;

	IUnknown* State = NULL;
	IUnknown* Unknown = NULL;
	IMFAsyncResult* CallerResult = NULL;

	AsyncReadState* Op = NULL;

	HResult = pResult->GetState( &State );
	check( SUCCEEDED( HResult ) );

	HResult = State->QueryInterface( IID_PPV_ARGS( &CallerResult ) );
	check( SUCCEEDED( HResult ) );

	HResult = CallerResult->GetObject( &Unknown );
	check( SUCCEEDED( HResult ) );

	Op = static_cast<AsyncReadState*>( Unknown );

	/* Do actual read */
	ULONG cbRead;
	Read( Op->GetBuffer( ), Op->GetCount( ) - Op->GetBytesRead( ), &cbRead );
	Op->SetBytesRead( cbRead + Op->GetBytesRead( ) );

	if( CallerResult )
	{
		CallerResult->SetStatus( HResult );
		MFInvokeCallback( CallerResult );
	}

	if( State != NULL ) { State->Release( ); }
	if( Unknown != NULL ) { Unknown->Release( ); }
	if( CallerResult != NULL ){ CallerResult->Release( ); }

	return S_OK;
}
/** Ends an asyncronous read */
STDMETHODIMP FImfByteStream::EndRead( IMFAsyncResult* pResult, ULONG* pcbRead )
{
	if( !pcbRead )
		return E_INVALIDARG;

	IUnknown* Unknown;
	pResult->GetObject( &Unknown );

	AsyncReadState* State = static_cast<AsyncReadState*>( Unknown );
	*pcbRead = State->GetBytesRead( );
	Unknown->Release( );

	IsCurrentlyReading = false;

	return S_OK;
}