LoaderSourceFileWindowsMedia::LoaderSourceFileWindowsMedia( SourceFileWindowsMedia * source, Target * target ) : Loader(), mSource( source ), mSampleOffset( 0 ), mSrcSampleRate( 0 ), mSrcChannelCount( 0 ), mSrcBitsPerSample( 0 ) { ::HRESULT hr; //setup readers IWMSyncReader * IWMReaderP = NULL; hr = ::WMCreateSyncReader(0, 0, &IWMReaderP ); if( FAILED( hr ) ) { throw IoExceptionFailedLoad(); } mReader = msw::makeComShared<IWMSyncReader>( IWMReaderP ); IWMHeaderInfo * IWMHeaderInfoP = NULL; hr = mReader->QueryInterface( IID_IWMHeaderInfo, (void**)&IWMHeaderInfoP ); if( FAILED(hr) ) { throw IoExceptionFailedLoad(); } mHeaderInfo = msw::makeComShared<IWMHeaderInfo>( IWMHeaderInfoP ); //turn data into stream ::IStream * iStreamP = NULL; hr = ::CreateStreamOnHGlobal( mSource->mMemHandle.get(), FALSE, &iStreamP ); if(FAILED(hr)) { throw IoExceptionFailedLoad(); } std::shared_ptr<::IStream> pStream = msw::makeComShared<::IStream>( iStreamP ); hr = mReader->OpenStream( pStream.get() ); if( FAILED(hr) ) { throw IoExceptionFailedLoad(); } DWORD nOutputFormatCount; hr = mReader->GetOutputFormatCount(0, &nOutputFormatCount); if( FAILED(hr) ) { throw IoExceptionFailedLoad(); } DWORD nFormatSize = 0; BYTE* pBuf = 0; IWMOutputMediaProps* pProps = 0; for( uint32_t j = 0; j < nOutputFormatCount; j++ ) { hr = mReader->GetOutputFormat( 0, j, &pProps ); if(FAILED(hr)) { continue; } //get required size of the media type structure DWORD nNewSize = 0; hr = pProps->GetMediaType( NULL, & nNewSize ); if( FAILED(hr) ) { continue; } if(nNewSize > nFormatSize) { if( pBuf ) { delete [] pBuf; pBuf = 0; } nFormatSize = nNewSize; pBuf = new BYTE[nFormatSize]; } WM_MEDIA_TYPE* pType = (WM_MEDIA_TYPE*) pBuf; size_t acrunk = sizeof( WM_MEDIA_TYPE ); hr = pProps->GetMediaType( pType, &nFormatSize ); if(FAILED(hr)) continue; if( IsEqualIID( WMFORMAT_WaveFormatEx, pType->formattype ) ) { //casting format buffer as WAVEFORMATEX //when formattype == WMFORMAT_WaveFormatEx, pbFormat will be //WAVEFORMATEX or WAVEFORMATEXTENSIBLE, both of which can be cast //safely as WAVEFORMATEX mOutputFormat = *((WAVEFORMATEX *)pType->pbFormat); if( ( mOutputFormat.wFormatTag == ( ( target->isFloat() ) ? WAVE_FORMAT_IEEE_FLOAT : WAVE_FORMAT_PCM ) ) && ( mOutputFormat.nChannels == target->getChannelCount() ) && ( mOutputFormat.wBitsPerSample == target->getBitsPerSample() ) && ( mOutputFormat.nSamplesPerSec == target->getSampleRate() ) && ( mOutputFormat.nBlockAlign == target->getBlockAlign() ) ) { mSrcSampleRate = mOutputFormat.nSamplesPerSec; mSrcChannelCount = mOutputFormat.nChannels; mSrcBitsPerSample = mOutputFormat.wBitsPerSample; mSrcBlockAlign = mOutputFormat.nBlockAlign; break; } } if( pProps ) { pProps->Release(); pProps = 0; } } if( pBuf ) { delete [] pBuf; pBuf = 0; } hr = mReader->SetOutputProps( 0, pProps ); if( FAILED( hr ) ) { throw IoExceptionFailedLoad(); } if( pProps ) { pProps->Release(); pProps = 0; } WORD wStreamNum = 0; WMT_ATTR_DATATYPE Type; QWORD dwDuration = 0; WORD wLength = 8; hr = mHeaderInfo->GetAttributeByName( &wStreamNum, g_wszWMDuration, &Type, (BYTE*)&dwDuration, &wLength ); if( FAILED( hr ) ) { throw IoExceptionFailedLoad(); } //divide by 10 million to get seconds double fTime = double( dwDuration ) / 10000000.0f; mStreamSize = (uint32_t)( fTime * mOutputFormat.nAvgBytesPerSec * 1.5 ); DWORD tempMaxBufferSize = 0; mMaxBufferSize = 0; hr = mReader->GetMaxOutputSampleSize( 0, &tempMaxBufferSize ); mMaxBufferSize = tempMaxBufferSize; if( FAILED( hr ) ) { throw IoExceptionFailedLoad(); } //set data to not be compressed /*hr = mReader->SetReadStreamSamples( 0, FALSE ); if( FAILED( hr ) ) { throw IoExceptionFailedLoad(); }*/ }
int decoder_load(unsigned long id, const string sname) { HRESULT hres; IWMOutputMediaProps* ppProps; WM_MEDIA_TYPE* wmt = 0; DWORD wmpz = 0; WAVEFORMATEX wfx; DWORD i, outcount = 0; IWMHeaderInfo* wminfo; WORD wmistream = 0; WMT_ATTR_DATATYPE Type; WORD wmilen; CoInitialize(0); hres = WMCreateSyncReader(0, 0, &pstreams[id].wmreader); if(FAILED(hres))return 0; hres = pstreams[id].wmreader->Open(sname); pstreams[id].wmreader->GetOutputCount(&outcount); for(i=0; i<outcount; i++) { hres = pstreams[id].wmreader->GetOutputProps(i, &ppProps); if(FAILED(hres)) { ppProps->Release(); continue; } hres = ppProps->GetMediaType(0, &wmpz); if(FAILED(hres)) { ppProps->Release(); continue; } wmt = (WM_MEDIA_TYPE*) malloc(wmpz); hres = ppProps->GetMediaType(wmt, &wmpz); if(WMMEDIATYPE_Audio != wmt->majortype) { ppProps->Release(); free(wmt); continue; } memcpy(&wfx, wmt->pbFormat, wmt->cbFormat); pstreams[id].channels = wfx.nChannels; pstreams[id].frequency = wfx.nSamplesPerSec; pstreams[id].bitspersample = wfx.wBitsPerSample; pstreams[id].wmaudioout = i; free(wmt); ppProps->Release(); break; } pstreams[id].buffer = 0; pstreams[id].buffersize = 0; /* get information */ hres = pstreams[id].wmreader->QueryInterface(IID_IWMHeaderInfo, (VOID **)&wminfo); if(FAILED(hres))return 0; wmistream = 0; hres = wminfo->GetAttributeByName(&wmistream, g_wszWMDuration, &Type, 0, &wmilen); if(hres == S_OK) { QWORD dur; wminfo->GetAttributeByName(&wmistream, g_wszWMDuration, &Type, (BYTE*)&dur,&wmilen); pstreams[id].duration = (DWORD)(dur / 10000); } wminfo->Release(); return 1; }