⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 htrencftr.cpp

📁 freescale i.mx31 BSP CE5.0全部源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	CHtrEncPhysicalAllocator::Mapping* pCur = m_pMappingsList;
	// Check that list exists
	if( NULL == pCur )
	{
	    HTRENC_DEBUG( "CHtrEncPhysicalAllocator::FindMapping FAILED, no mappings created yet\n" );
		return NULL;
	}

	// Find mapping for the specified virtual address
	do
	{
		if( pCur->pVirAddr == pVirAddr )
		{
		    HTRENC_DEBUG_EXTRA( "CHtrEncPhysicalAllocator::FindMapping Ok\n" );
			return pCur;
		}
		pCur = pCur->p_next;
	} while( pCur != NULL );
	
    HTRENC_DEBUG( "CHtrEncPhysicalAllocator::FindMapping FAILED, couldn't find mapping for virtual address\n" );
	return NULL;
}

VOID CHtrEncPhysicalAllocator::ClearMappings()
{
	// Clear the list of mapping
	CHtrEncPhysicalAllocator::Mapping* pNext = NULL;
	CHtrEncPhysicalAllocator::Mapping* pCur = m_pMappingsList;
	do
	{
		if( pCur != NULL )
		{
			pNext = pCur->p_next;
			delete pCur;
			pCur = pNext;
		}
	} while ( pCur != NULL );
    HTRENC_DEBUG_EXTRA( "CHtrEncPhysicalAllocator::ClearMappings Ok\n" );
}

HRESULT CHtrEncPhysicalAllocator::Alloc(void)
{
	// Check that SetProperties has been called and there is no outstanding buffers
	HRESULT hr = CBaseAllocator::Alloc();
	if( FAILED(hr) )
	{
	    HTRENC_DEBUG( "CHtrEncPhysicalAllocator::Alloc FAILED, SetProperties has not been called or there is outstanding buffers\n" );
		return hr;
	}

	// Create CMediaSample objects and add them to the list of free objects
	ALLOCATOR_PROPERTIES props;
	hr = GetProperties(&props);
	if( FAILED(hr) )
	{
	    HTRENC_DEBUG( "CHtrEncPhysicalAllocator::Alloc FAILED, properties have not been set\n" );
		return VFW_E_SIZENOTSET;
	}
	
	// Allocate the physical memory for each sample
	for( int i = 0; i<props.cBuffers; i++ )
	{
		LPBYTE virAddr;
		DWORD physAddr; 
#ifdef UNDER_CE
		virAddr = (LPBYTE)AllocPhysMem(props.cbBuffer+props.cbPrefix, PAGE_READWRITE, 0, 0, &physAddr);
#else
		virAddr = (LPBYTE)malloc(props.cbBuffer+props.cbPrefix);
		physAddr = (DWORD)virAddr; // simple emulation of physical address on PC environment
#endif /* UNDER_CE */
		// Once the memory block is allocated, let's add the mapping to our bookkeeping
		AddMapping(virAddr, physAddr);
		if( NULL == virAddr )
		{
		    HTRENC_DEBUG( "CHtrEncPhysicalAllocator::Alloc FAILED, could not allocate memory on heap\n" );
			return E_OUTOFMEMORY;
		}

		// Create the media sample, hr is not touched by the constructor
		CMediaSample* ps;
		ps = new CMediaSample(NAME("Hantro Encoder Custom Sample"), this, &hr, virAddr, props.cbBuffer);
		if( NULL == ps )
		{
		    HTRENC_DEBUG( "CHtrEncPhysicalAllocator::Alloc FAILED, could not allocate memory on heap\n" );
			return E_OUTOFMEMORY;
		}
		// Add the sample to the list of free samples and increment allocated counter
		m_lFree.Add(ps);
		m_lAllocated++;
	}

    HTRENC_DEBUG_EXTRA( "CHtrEncPhysicalAllocator::Alloc Ok\n" );
	return S_OK;
}

void CHtrEncPhysicalAllocator::Free(void)
{
	/* Should never be deleting this unless all buffers are freed */
    ASSERT(m_lAllocated == m_lFree.GetCount());

	while( m_lFree.GetCount() > 0 )
	{
		LPBYTE pBuf;
		CMediaSample* ps = m_lFree.RemoveHead();
		if( NULL != ps )
		{
			ps->GetPointer(&pBuf); // returns S_OK always
#ifdef UNDER_CE
			FreePhysMem(pBuf); // We cannot do anything if the freeing fails
#else
			free(pBuf);
#endif /* UNDER_CE */
			delete ps;
			m_lAllocated--;
		}
		else
		{
			break;
		}
	}
	// Let's clear our bookkeeping of the mapping between physical and virtual addresses
	ClearMappings();

    HTRENC_DEBUG_EXTRA( "CHtrEncPhysicalAllocator::Free Ok\n" );
}

/*------------------------------------------------------------------------------
    6. CHtrEncInputPin class
------------------------------------------------------------------------------*/

CHtrEncInputPin::CHtrEncInputPin( TCHAR* pObjectName, CTransformFilter* pTransformFilter, HRESULT* phr, LPCWSTR pName )
: CTransformInputPin( pObjectName, pTransformFilter, phr, pName ), m_pHtrAlloc(NULL)
{
}

HRESULT CHtrEncInputPin::GetAllocator(IMemAllocator **ppAllocator)
{
    CheckPointer(ppAllocator, E_POINTER);
	if (m_pAllocator)  
    {
        // We already have an allocator, so return that one.
        *ppAllocator = m_pAllocator;
        (*ppAllocator)->AddRef();
	    HTRENC_DEBUG_EXTRA( "CHtrEncInputPin::GetAllocator Ok!\n" );
        return S_OK;
    }
    // No allocator yet, so propose our custom allocator. 
    HRESULT hr = S_OK;
    CHtrEncPhysicalAllocator *pAlloc = new CHtrEncPhysicalAllocator(&hr);
    if (!pAlloc)
    {
	    HTRENC_DEBUG( "CHtrEncInputPin::GetAllocator FAILED, out of memory\n" );
        return E_OUTOFMEMORY;
    }
    if (FAILED(hr))
    {
	    HTRENC_DEBUG( "CHtrEncInputPin::GetAllocator FAILED, constructing physical allocator failed\n" );
        delete pAlloc;
        return hr;
    }
    // Return the IMemAllocator interface to the caller.
    HTRENC_DEBUG_EXTRA( "CHtrEncInputPin::GetAllocator Ok!\n" );
    return pAlloc->QueryInterface(IID_IMemAllocator, (void**)ppAllocator);
}

HRESULT CHtrEncInputPin::NotifyAllocator(IMemAllocator *pAllocator, BOOL bReadOnly)
{
	IHtrAllocator* pHtrAlloc = NULL;

	// Is the chosen allocator is the one we proposed, let's check out by asking for our custom interface
	HRESULT hr = pAllocator->QueryInterface(IID_IHtrAllocator, (void**)&pHtrAlloc);
	if( FAILED(hr) )
	{
		HTRENC_DEBUG( "CHtrEncInputPin::NotifyAllocator FAILED, upstream pin did not accept our allocator!\n" );
		return E_FAIL;
	}
	m_pHtrAlloc = pHtrAlloc;
	// We already have one lock for this COM object through m_pAllocator member and we use it as long
	// as the base class uses. Let's leave the cleanup for the base class.
	m_pHtrAlloc->Release();

	HTRENC_DEBUG_EXTRA( "CHtrEncInputPin::NotifyAllocator Ok!\n" );
	return S_OK;
}

/*------------------------------------------------------------------------------
    7. CHtrEncOutputPin class
------------------------------------------------------------------------------*/

CHtrEncOutputPin::CHtrEncOutputPin( TCHAR* pObjectName, CTransformFilter* pTransformFilter, HRESULT* phr, LPCWSTR pName )
: CTransformOutputPin( pObjectName, pTransformFilter, phr, pName ), m_pHtrAlloc(NULL)
{
}

STDMETHODIMP CHtrEncOutputPin::NonDelegatingQueryInterface(REFIID iid, void **ppv)
{
    if (iid == IID_IAMStreamConfig ) {
        return GetInterface(static_cast<IAMStreamConfig*>(this), ppv);
    }
	else if( iid == IID_IAMVideoCompression ) {
        return GetInterface(static_cast<IAMVideoCompression*>(this), ppv);
	}
    return CTransformOutputPin::NonDelegatingQueryInterface(iid,ppv);
}

HRESULT CHtrEncOutputPin::DecideAllocator(IMemInputPin *pPin, IMemAllocator **pAlloc)
{
    CheckPointer(pAlloc, E_POINTER);

	// Let's forget about the downstream pins requirements, we need our on allocator, period.
	HRESULT hr;
	ALLOCATOR_PROPERTIES ownProps;
	IMemAllocator* pOwnAlloc = new CHtrEncPhysicalAllocator(&hr);
	if( NULL == pOwnAlloc )
	{
		HTRENC_DEBUG( "CHtrEncInputPin::DecideAllocator FAILED, not enough memory for allocator!\n" );
		return E_OUTOFMEMORY;	
	}

	// Query our custom interface from the allocator
	IHtrAllocator* pHtrAlloc;
	hr = pOwnAlloc->QueryInterface(IID_IHtrAllocator, (void**)&pHtrAlloc);
	if( FAILED(hr) )
	{
		HTRENC_DEBUG( "CHtrEncInputPin::DecideAllocator FAILED, upstream pin did not accept our allocator!\n" );
		return E_FAIL;
	}
	m_pHtrAlloc = pHtrAlloc;

	// Call DecideBufferSize to set the properties for our allocator
	hr = DecideBufferSize(pOwnAlloc, &ownProps);
	if( FAILED(hr) )
	{
		// If we cannot decide the allocator properties for some reason, cascade the error
        HTRENC_DEBUG( "CHtrEncOutputPin::DecideAllocator FAILED, failed to decide the allocator properties\n" );
		return hr;
	}

	// Call IMemInputPin::NotifyAllocator to tell the downstream pin that we are using our own allocator.
	hr = pPin->NotifyAllocator(pOwnAlloc, TRUE);
	if( FAILED(hr) )
	{
		// If the downstream pin cannot live with our requirements, let's forget it and cascade the error
        HTRENC_DEBUG( "CHtrEncOutputPin::DecideAllocator FAILED, downstream pin rejected our allocator\n" );
		return hr;
	}
	
	// Set the pointer to the allocator correctly
	*pAlloc = pOwnAlloc;

    HTRENC_DEBUG_EXTRA( "CHtrEncOutputPin::DecideAllocator Ok!\n" );
	return S_OK;
}

// Methods from IAMStreamConfig
HRESULT CHtrEncOutputPin::GetFormat(AM_MEDIA_TYPE** ppmt)
{
    if( !m_pFilter->GetPin(0)->IsConnected() )
    {
        HTRENC_DEBUG( "CHtrEncOutputPin::GetFormat FAILED, input pin must be connected\n" );
        return VFW_E_NOT_CONNECTED;
    }

	CMediaType mt;
	HRESULT hr = ((CHtrEncFltr*)m_pFilter)->GetMediaType( 0, &mt );
    if( FAILED(hr) )
    {
        HTRENC_DEBUG( "CHtrEncOutputPin::GetFormat: filter->GetMediaType FAILED\n" );
        return hr;
    }
	
    *ppmt = CreateMediaType( &mt );
    if( *ppmt == NULL )
    {
        HTRENC_DEBUG( "CHtrEncOutputPin::GetFormat FAILED creating media type\n" );
        return E_OUTOFMEMORY;
    }

    HTRENC_DEBUG_EXTRA( "CHtrEncOutputPin::GetFormat Ok!\n" );
    return S_OK;
}

HRESULT CHtrEncOutputPin::SetFormat(AM_MEDIA_TYPE* pmt)
{
    if( !m_pFilter->GetPin(0)->IsConnected()) return VFW_E_NOT_CONNECTED;
	CMediaType mt( *pmt );

    // Check new format using CTransformOutputPin, which calls our
    // implementation in CHtrEncFltr
    HRESULT hr = CheckMediaType( &mt );
    if( FAILED(hr) )
    {
        HTRENC_DEBUG( "CHtrEncOutputPin::SetFormat: CheckMediaType FAILED, invalid format?\n" );
    	return hr;
    }

    // Set new format, also using CTransformOutputPin
	hr = SetMediaType( &mt );
    if( FAILED(hr) )
    {
        HTRENC_DEBUG( "CHtrEncOutputPin::SetFormat: SetMediaType FAILED, invalid format?\n" );
    	return hr;
    }

    HTRENC_DEBUG_EXTRA( "CHtrEncOutputPin::SetFormat Ok!\n" );
	return S_OK;
}

HRESULT CHtrEncOutputPin::GetNumberOfCapabilities(int* piCount, int* piSize)
{
    HTRENC_DEBUG_EXTRA( "CHtrEncOutputPin::GetNumberOfCapabilities WARNING: not implemented!\n" );
	return E_NOTIMPL;
}

HRESULT CHtrEncOutputPin::GetStreamCaps(int iIndex, AM_MEDIA_TYPE** pmt, BYTE* pSCC)
{
    HTRENC_DEBUG_EXTRA( "CHtrEncOutputPin::GetStreamCaps WARNING: not implemented!\n" );
	return E_NOTIMPL;
}

// Methods from IAMVideoCompression
HRESULT CHtrEncOutputPin::put_KeyFrameRate(long KeyFrameRate)
{
    if( !m_pFilter->GetPin(0)->IsConnected()) return VFW_E_NOT_CONNECTED;
    
    // Set intra refresh directly in CHtrEncFltr
    CHtrEncFltr* pHtrEncFltr = (CHtrEncFltr*)m_pFilter;
    if( pHtrEncFltr==NULL )
    {
        HTRENC_DEBUG( "CHtrEncOutputPin::put_KeyFrameRate: not connected to CHtrEncFltr object\n" );
    	return E_FAIL;
    }

    if( KeyFrameRate < 0 )
    {
        HTRENC_DEBUG( "CHtrEncOutputPin::put_KeyFrameRate FAILED, invalid KeyFrameRate input\n" );
        return VFW_E_TYPE_NOT_ACCEPTED;
    }

    pHtrEncFltr->m_settings.intraRefreshRate = KeyFrameRate;

    HTRENC_DEBUG_EXTRA( "CHtrEncOutputPin::put_KeyFrameRate Ok!\n" );
	return S_OK;
}

HRESULT CHtrEncOutputPin::get_KeyFrameRate(long *pKeyFrameRate)
{
    if( !m_pFilter->GetPin(0)->IsConnected()) return VFW_E_NOT_CONNECTED;
    
    if( pKeyFrameRate==NULL )
    {
        HTRENC_DEBUG( "CHtrEncOutputPin::get_KeyFrameRate FAILED, null pKeyFrameRate input\n" );
        return E_INVALIDARG;
    }

    // Get intra refresh directly from CHtrEncFltr
    CHtrEncFltr* pHtrEncFltr = (CHtrEncFltr*)m_pFilter;
    if( pHtrEncFltr==NULL )
    {
        HTRENC_DEBUG( "CHtrEncOutputPin::get_KeyFrameRate: not connected to CHtrEncFltr object\n" );
    	return E_FAIL;
    }

    *pKeyFrameRate = pHtrEncFltr->m_settings.intraRefreshRate;

    HTRENC_DEBUG_EXTRA( "CHtrEncOutputPin::get_KeyFrameRate Ok!\n" );
	return S_OK;
}

HRESULT CHtrEncOutputPin::GetInfo( WCHAR* pszVersion, int* pcbVersion, 
                                   LPWSTR pszDescription, int* pcbDescription,
	                               long* pDefaultKeyFrameRate, long* /*pDefaultPFramesPerKey*/,
	                               double* /*pDefaultQuality*/, long* pCapabilities )
{
    (void)pszVersion; (void)pcbVersion;
    (void)pszDescription; (void)pcbDescription;

    // Zero means only first frame is key frame
    if( pDefaultKeyFrameRate != NULL )
        *pDefaultKeyFrameRate = 0;

    // Only key frame rate is supported
    if( pCapabilities != NULL )
        *pCapabilities = CompressionCaps_CanKeyFrame;

    HTRENC_DEBUG_EXTRA( "CHtrEncOutputPin::GetInfo Ok!\n" );
	return S_OK;
}


HRESULT CHtrEncOutputPin::put_PFramesPerKeyFrame(long PFramesPerKeyFrame)
{
	return E_NOTIMPL;
}

HRESULT CHtrEncOutputPin::get_PFramesPerKeyFrame(long *pPFramesPerKeyFrame)
{
	return E_NOTIMPL;
}

HRESULT CHtrEncOutputPin::put_Quality(double Quality)
{
    return E_NOTIMPL;
}

HRESULT CHtrEncOutputPin::get_Quality(double *pQuality)
{
	return E_NOTIMPL;
}

HRESULT CHtrEncOutputPin::put_WindowSize(DWORDLONG WindowSize)
{
	return E_NOTIMPL;
}

HRESULT CHtrEncOutputPin::get_WindowSize(DWORDLONG *pWindowSize)
{
	return E_NOTIMPL;
}

HRESULT CHtrEncOutputPin::OverrideKeyFrame(long FrameNumber)
{
	return E_NOTIMPL;
}

HRESULT CHtrEncOutputPin::OverrideFrameSize(long FrameNumber, long Size)
{
	return E_NOTIMPL;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -