// Format negotiation HRESULT CTimeStretchFilter::NegotiateFormat(const WAVEFORMATEXTENSIBLE* pwfx, int nApplyChangesDepth, ChannelOrder* pChOrder) { if (!pwfx) return VFW_E_TYPE_NOT_ACCEPTED; #ifdef INTEGER_SAMPLES // only accept 16bit int if (pwfx->Format.wBitsPerSample != 16 || pwfx->SubFormat != KSDATAFORMAT_SUBTYPE_PCM) return VFW_E_TYPE_NOT_ACCEPTED; #else // only accept 32bit float if (pwfx->Format.wBitsPerSample != 32 || pwfx->SubFormat != KSDATAFORMAT_SUBTYPE_IEEE_FLOAT) return VFW_E_TYPE_NOT_ACCEPTED; #endif if (FormatsEqual(pwfx, m_pInputFormat)) { *pChOrder = m_chOrder; return S_OK; } bool bApplyChanges = (nApplyChangesDepth != 0); if (nApplyChangesDepth != INFINITE && nApplyChangesDepth > 0) nApplyChangesDepth--; HRESULT hr = m_pNextSink->NegotiateFormat(pwfx, nApplyChangesDepth, pChOrder); if (FAILED(hr)) return hr; hr = VFW_E_CANNOT_CONNECT; if (!pwfx) return SetFormat(NULL); if (bApplyChanges) { LogWaveFormat(pwfx, "TS - applying "); m_pNextSink->NegotiateBuffer(pwfx, &m_nOutBufferSize, &m_nOutBufferCount, true); AM_MEDIA_TYPE tmp; HRESULT result = CreateAudioMediaType((WAVEFORMATEX*)pwfx, &tmp, true); if (SUCCEEDED(result)) { if (m_pMediaType) DeleteMediaType(m_pMediaType); m_pMediaType = CreateMediaType(&tmp); } SetInputFormat(pwfx); SetOutputFormat(pwfx); SetFormat(pwfx); } else LogWaveFormat(pwfx, "TS - "); m_bNextFormatPassthru = !m_pSettings->m_bUseTimeStretching; m_chOrder = *pChOrder; return S_OK; }
// // GetMediaType // HRESULT CSynthStream::GetMediaType(CMediaType *pmt) { CheckPointer(pmt,E_POINTER); // The caller must hold the state lock because this function // calls get_OutputFormat() and GetPCMFormatStructure(). // The function assumes that the state of the m_Synth // object does not change between the two calls. The // m_Synth object's state will not change if the // state lock is held. ASSERT(CritCheckIn(m_pParent->pStateLock())); WAVEFORMATEX *pwfex; SYNTH_OUTPUT_FORMAT ofCurrent; HRESULT hr = m_Synth->get_OutputFormat( &ofCurrent ); if(FAILED(hr)) { return hr; } if(SYNTH_OF_PCM == ofCurrent) { pwfex = (WAVEFORMATEX *) pmt->AllocFormatBuffer(sizeof(WAVEFORMATEX)); if(NULL == pwfex) { return E_OUTOFMEMORY; } m_Synth->GetPCMFormatStructure(pwfex); } else if(SYNTH_OF_MS_ADPCM == ofCurrent) { DWORD dwMaxWAVEFORMATEXSize; MMRESULT mmr = acmMetrics(NULL, ACM_METRIC_MAX_SIZE_FORMAT, (void*)&dwMaxWAVEFORMATEXSize); // acmMetrics() returns 0 if no errors occur. if(0 != mmr) { return E_FAIL; } pwfex = (WAVEFORMATEX *) pmt->AllocFormatBuffer(dwMaxWAVEFORMATEXSize); if(NULL == pwfex) { return E_OUTOFMEMORY; } WAVEFORMATEX wfexSourceFormat; m_Synth->GetPCMFormatStructure(&wfexSourceFormat); ZeroMemory(pwfex, dwMaxWAVEFORMATEXSize); pwfex->wFormatTag = WAVE_FORMAT_ADPCM; pwfex->cbSize = (USHORT)(dwMaxWAVEFORMATEXSize - sizeof(WAVEFORMATEX)); pwfex->nChannels = wfexSourceFormat.nChannels; pwfex->nSamplesPerSec = wfexSourceFormat.nSamplesPerSec; mmr = acmFormatSuggest(NULL, &wfexSourceFormat, pwfex, dwMaxWAVEFORMATEXSize, ACM_FORMATSUGGESTF_WFORMATTAG | ACM_FORMATSUGGESTF_NSAMPLESPERSEC | ACM_FORMATSUGGESTF_NCHANNELS); // acmFormatSuggest() returns 0 if no errors occur. if(0 != mmr) { return E_FAIL; } } else { return E_UNEXPECTED; } return CreateAudioMediaType(pwfex, pmt, FALSE); }