Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Direct Show & IStream ?

354
15 октября 2007 года
ШпиЁн
468 / / 19.02.2006
Здравствуйте.

пишу простенький проигрыватель аудио-файлов, возникла такая проблема: необходимо проиграть не определенный файл, а некоторые данные загруженные в память (например ресурс).

Дело в том что AddSourceFilter из IGraphBuilder требует имени файла, а файла-то нет. :о)

Как решить эту проблему? заранее благодарю. :о)
5.9K
24 октября 2007 года
Zushenskiy
161 / / 29.06.2006
Поищи фильтры сторонних разработчиков. либо напиши сам SourceFilter
5.9K
24 октября 2007 года
Zushenskiy
161 / / 29.06.2006
Вот пример сорс фильтра для генерации звука теперь ты можешь сюда подставить чтения из памяти


Код:
class CBlankAudioPin :
    public CSourceStream,
    public CSourceSeeking
{
    friend class CBlankStreams;
    REFERENCE_TIME m_rtStartTime;
    REFERENCE_TIME m_rtEndTime;
    WAVEFORMATEX m_wf;
    DWORD m_dwBufferSize;
    CCritSec  m_SeekLock;
protected:
    HRESULT ChangeStart( );
    HRESULT ChangeStop( );
    HRESULT ChangeRate( );
public:
    STDMETHODIMP QueryInterface(REFIID riid, void **ppv)
    {      
        return CSourceStream::QueryInterface(riid,ppv);            
    };                                                          
    STDMETHODIMP_(ULONG) AddRef()
    {                            
        return CSourceStream::AddRef();                            
    };                                                          
    STDMETHODIMP_(ULONG) Release()
    {                            
        return CSourceStream::Release();                          
    };
   
    CBlankAudioPin(HRESULT* pHr, CSource* pSource);
    ~CBlankAudioPin();
protected:
    HRESULT OnThreadCreate(void);
    HRESULT OnThreadDestroy(void);
    HRESULT OnThreadStartPlay(void);
protected:
    HRESULT DoBufferProcessingLoop(void);
    HRESULT CheckMediaType(const CMediaType *pMediaType);
    HRESULT GetMediaType(int iPosition, CMediaType *pMediaType);
    HRESULT GetMediaType(CMediaType *pMediaType);
    HRESULT FillBuffer(IMediaSample *pSample);
    HRESULT DecideBufferSize(IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *ppropInputRequest);
    STDMETHODIMP ConnectionMediaType(AM_MEDIA_TYPE*);
    STDMETHODIMP NonDelegatingQueryInterface( REFIID riid, void ** ppv );
protected:
    HRESULT UpdateAudioHeader();
};

class CBlankStreams:
    public CSource
{
    CBlankAudioPin* m_pAudioPin;
public:
    CBlankStreams(HRESULT* pHr);
    ~CBlankStreams(void);
public:
    static CUnknown * WINAPI CreateInstance(LPUNKNOWN pUnk, HRESULT *phr);
public:
    CBasePin *GetPin(int n)
    {
        if (n == 0)
            return m_pAudioPin;
        else if (n == 1)
            return m_pVideoPin;
        else
            return NULL;
    }
    int GetPinCount(void)
    {
        return 2;
    }
   
    STDMETHODIMP NonDelegatingQueryInterface(const IID& riid, void** ppv);
public:
    DECLARE_IUNKNOWN;
};

#define DEFAULT_DURATION 10 * UNITS

CBlankAudioPin::CBlankAudioPin(HRESULT* pHr, CSource* pSource):
    CSourceStream(TEXT("Output stream"), pHr, pSource, L"Output audio stream"),
    CSourceSeeking(TEXT("Output stream"), (IPin*)this, pHr, &m_SeekLock),
    m_iCountFrame(0),
    m_rtStartTime(0),
    m_rtEndTime(0),
    m_dwBufferSize(512)
{
    ZeroMemory(&m_wf, sizeof(m_wf));
   
    UpdateAudioHeader();
   
    m_rtDuration = DEFAULT_DURATION;
    m_rtStop = m_rtDuration;

    // no seeking to absolute pos's and no seeking backwards!
    //
    m_dwSeekingCaps = AM_SEEKING_CanSeekForwards | AM_SEEKING_CanGetStopPos   | AM_SEEKING_CanGetDuration  | AM_SEEKING_CanSeekAbsolute;
   
}

CBlankAudioPin::~CBlankAudioPin()
{
}

   
STDMETHODIMP CBlankAudioPin::Notify(IBaseFilter* pFilter, Quality q)
{
    return S_OK;
}
HRESULT CBlankAudioPin::ChangeRate()
{
   
    return NOERROR;
}
HRESULT CBlankAudioPin::ChangeStop()
{
    return NOERROR;
}
HRESULT CBlankAudioPin::ChangeStart()
{
    m_iCountFrame = 0;

    if (ThreadExists())
    {
        // next time round the loop the worker thread will
        // pick up the position change.
        // We need to flush all the existing data - we must do that here
        // as our thread will probably be blocked in GetBuffer otherwise
        DeliverBeginFlush();

        // make sure we have stopped pushing
        Stop();

        // complete the flush
        DeliverEndFlush();

        // restart
        Run();
    }

    return NOERROR;
}

HRESULT CBlankAudioPin::UpdateAudioHeader()
{
    m_wf.cbSize = 0;//sizeof(WAVEFORMATEX);
    m_wf.nChannels = 2;
    m_wf.wBitsPerSample = 16;
    m_wf.nBlockAlign = (m_wf.nChannels*m_wf.wBitsPerSample)/8;
    m_wf.wFormatTag = WAVE_FORMAT_PCM;
    m_wf.nSamplesPerSec = 44100;
    m_wf.nAvgBytesPerSec = (m_wf.nChannels*m_wf.nSamplesPerSec*m_wf.wBitsPerSample)/8;
    return S_OK;
}

HRESULT CBlankAudioPin::OnThreadCreate(void)
{
    return CSourceStream::OnThreadCreate();
}
HRESULT CBlankAudioPin::OnThreadDestroy(void)
{

    return CSourceStream::OnThreadDestroy();
}
HRESULT CBlankAudioPin::OnThreadStartPlay(void)
{
    DeliverNewSegment( m_rtStartTime, m_rtEndTime, 1.0 );
    return CSourceStream::OnThreadStartPlay();
}
HRESULT CBlankAudioPin::DoBufferProcessingLoop(void)
{
    m_iCountFrame = 0;
    m_rtEndTime = 0;
    return CSourceStream::DoBufferProcessingLoop();
}

STDMETHODIMP CBlankAudioPin::ConnectionMediaType(AM_MEDIA_TYPE*)
{
    return S_OK;
}


HRESULT CBlankAudioPin::CheckMediaType(const CMediaType *pMediaType)
{
    CheckPointer(pMediaType,E_POINTER);
     
    if( *(pMediaType->FormatType())!= FORMAT_WaveFormatEx )
    {
        return VFW_E_TYPE_NOT_ACCEPTED;
    }
    // we only want fixed size Audio
    //
    if( *(pMediaType->Type()) != MEDIATYPE_Audio )
    {
        return VFW_E_TYPE_NOT_ACCEPTED;
    }
    if( *(pMediaType->Subtype()) != MEDIASUBTYPE_PCM)
    {
        return VFW_E_TYPE_NOT_ACCEPTED;    
    }
    WAVEFORMATEX *pwfx = (WAVEFORMATEX *) pMediaType->pbFormat;
    if (!pwfx)
    {
        return VFW_E_TYPE_NOT_ACCEPTED;
    }
    if (pwfx->wFormatTag != WAVE_FORMAT_PCM)
    {
        return VFW_E_TYPE_NOT_ACCEPTED;
    }
    if (pwfx->wBitsPerSample != m_wf.wBitsPerSample)
    {
        return VFW_E_TYPE_NOT_ACCEPTED;
    }
    if (pwfx->nAvgBytesPerSec != m_wf.nAvgBytesPerSec)
    {
        return VFW_E_TYPE_NOT_ACCEPTED;
    }
    if (pwfx->nChannels != m_wf.nChannels)
    {
        return VFW_E_TYPE_NOT_ACCEPTED;
    }
    if (pwfx->nSamplesPerSec != m_wf.nSamplesPerSec)
    {
        return VFW_E_TYPE_NOT_ACCEPTED;
    }
    return S_OK;
   
}

HRESULT CBlankAudioPin::GetMediaType(int iPosition, CMediaType *pMediaType)
{
    CheckPointer(pMediaType,E_POINTER);

    if (iPosition < 0)
    {
        return E_INVALIDARG;
    }

    // Have we run off the end of types

    if( iPosition > 0 )
    {
        return VFW_S_NO_MORE_ITEMS;
    }
    return GetMediaType(pMediaType);
}

HRESULT CBlankAudioPin::GetMediaType(CMediaType *pMediaType)
{
    pMediaType ->InitMediaType();
    pMediaType->SetType(&MEDIATYPE_Audio);
    pMediaType->SetFormatType(&FORMAT_WaveFormatEx);
    pMediaType->SetFormat( (BYTE*) &m_wf, sizeof( m_wf ) );
    pMediaType->SetSubtype(&MEDIASUBTYPE_PCM);
    pMediaType->SetSampleSize(m_dwBufferSize);
   
    return NOERROR;
}

HRESULT CBlankAudioPin::FillBuffer(IMediaSample *pSample)
{
    CAutoLock Lock( &m_SeekLock );
    double dSampleByte = (double)m_wf.nAvgBytesPerSec / (double)(m_dwBufferSize);
    if (!dSampleByte) dSampleByte = 0.00000001;
    m_rtStartTime = m_rtEndTime;//Frame2Time( m_iCountFrame, gScale, dSampleByte);
    m_rtEndTime += (LONGLONG)((UNITS / dSampleByte));

    // return S_FALSE if we've hit EOS. Parent class will send EOS for us
    //
    if( m_rtStartTime > m_rtStop )
    {
        return S_FALSE;
    }
   
    SHORT* pBuffer = NULL;
    pSample -> GetPointer((BYTE**)&pBuffer);
    int iSize = pSample -> GetSize() / 2;
    static int iLastLevel = 0;
    //creating low level wave
    for (int i = 0; i < iSize; i++)
    {
        *(pBuffer + i) = (short)(5.0 * sin(0.2 * (double)(i + iLastLevel) * 2.0 * 3.14 / (180.0)));
    }
    iLastLevel += (iSize);
    if (iLastLevel < 0)
    {
        iLastLevel = 0;
    }
     // set the timestamp
    //
    pSample->SetTime( &m_rtStartTime, &m_rtEndTime);

    // set the sync point
    //
    pSample -> SetActualDataLength(m_dwBufferSize);
    pSample -> SetSyncPoint(TRUE);
    m_iCountFrame++;
    return S_OK;
}
HRESULT CBlankAudioPin::DecideBufferSize(IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *pProperties)
{
   HRESULT hr = NOERROR;

    CheckPointer(pAlloc,E_POINTER);
    CheckPointer(pProperties,E_POINTER);

    pProperties->cBuffers = 1;
    if (pProperties->cbAlign == 0)
        pProperties->cbAlign  = 1;

    // Get input pin's allocator size and use that
    pProperties->cbBuffer = m_dwBufferSize;

    // Ask the allocator to reserve us some sample memory, NOTE the function
    // can succeed (that is return NOERROR) but still not have allocated the
    // memory that we requested, so we must check we got whatever we wanted

    ALLOCATOR_PROPERTIES Actual;
    hr = pAlloc->SetProperties(pProperties,&Actual);
    if(FAILED(hr))
    {
        return hr;
    }

    if(pProperties->cBuffers > Actual.cBuffers ||
        pProperties->cbBuffer > Actual.cbBuffer)
    {
        return E_FAIL;
    }

    return NOERROR;
}

STDMETHODIMP CBlankAudioPin::NonDelegatingQueryInterface( REFIID riid, void ** ppv )
{
    if( riid == IID_IMediaSeeking )
    {
        return CSourceSeeking::NonDelegatingQueryInterface( riid, ppv );
    }
    return CSourceStream::NonDelegatingQueryInterface(riid, ppv);
}



CBlankStreams::CBlankStreams(HRESULT* pHr):
    CSource(g_wszNameFilter, NULL, CLSID_CoBlankStreams)
{
    m_pAudioPin = new CBlankAudioPin(pHr, this);
}

CBlankStreams::~CBlankStreams(void)
{
    if (m_paStreams)
    {
        if (m_paStreams[0]) delete m_paStreams[0];
        delete [] m_paStreams;
    }
}

CUnknown * WINAPI CBlankStreams::CreateInstance(LPUNKNOWN pUnk, HRESULT *pHr)
{
    CUnknown* pNewObject = new CBlankStreams(pHr);
    if (!pNewObject) *pHr = E_OUTOFMEMORY;
    return pNewObject;
}

STDMETHODIMP CBlankStreams::NonDelegatingQueryInterface(const IID& riid, void** ppv)
{
    return CSource::NonDelegatingQueryInterface(riid, ppv);
}
354
26 октября 2007 года
ШпиЁн
468 / / 19.02.2006
спасибо. :о) я уже нашел ответ. фильтр почти готов. :о)
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог