Code/Resource
Windows Develop
Linux-Unix program
Internet-Socket-Network
Web Server
Browser Client
Ftp Server
Ftp Client
Browser Plugins
Proxy Server
Email Server
Email Client
WEB Mail
Firewall-Security
Telnet Server
Telnet Client
ICQ-IM-Chat
Search Engine
Sniffer Package capture
Remote Control
xml-soap-webservice
P2P
WEB(ASP,PHP,...)
TCP/IP Stack
SNMP
Grid Computing
SilverLight
DNS
Cluster Service
Network Security
Communication-Mobile
Game Program
Editor
Multimedia program
Graph program
Compiler program
Compress-Decompress algrithms
Crypt_Decrypt algrithms
Mathimatics-Numerical algorithms
MultiLanguage
Disk/Storage
Java Develop
assembly language
Applications
Other systems
Database system
Embeded-SCM Develop
FlashMX/Flex
source in ebook
Delphi VCL
OS Develop
MiddleWare
MPI
MacOS develop
LabView
ELanguage
Software/Tools
E-Books
Artical/Document
HSPlayer.cpp
Package: MF.zip [view]
Upload User: geng8029
Upload Date: 2021-01-30
Package Size: 187k
Code Size: 14k
Category:
Audio program
Development Platform:
Visual C++
- #include "StdAfx.h"
- #include "HSPlayer.h"
- //#include "common.h"
- #include <mfidl.h>
- #include "WavSink.h"
- #include <MMsystem.h>
- #include <aviriff.h>
- //#ifndef SAFE_RELEASE
- //template <class T>
- //inline void SAFE_RELEASE(T*& p)
- //{
- // if (p)
- // {
- // p->Release();
- // p = NULL;
- // }
- //}
- //#endif
- #ifndef IF_FAILED_BREAK
- #define IF_FAILED_BREAK(hr) if (FAILED(hr)) { break; }
- #endif
- #ifndef CHECK_HR
- #define CHECK_HR(hr) IF_FAILED_BREAK(hr)
- #endif
- #ifndef CheckPointer
- #define CheckPointer(x, hr) if (x == NULL) { return hr; }
- #endif
- struct WAV_FILE_HEADER
- {
- RIFFCHUNK FileHeader;
- DWORD fccWaveType; // must be 'WAVE'
- RIFFCHUNK WaveHeader;
- WAVEFORMATEX WaveFormat;
- RIFFCHUNK DataHeader;
- };
- extern HRESULT CreateWavSink(IMFByteStream *pStream, IMFMediaSink **ppSink, CALLBACK_FOR_CAPTUREDATA cb);
- CHSPlayer::CHSPlayer(void):
- //m_pBuffer(NULL),
- m_pByteStream(NULL),
- m_pSource(NULL)
- {
- }
- CHSPlayer::~CHSPlayer(void)
- {
- if (m_pSource)
- {
- m_pSource->Shutdown();
- }
- if (m_pSource)
- {
- m_pSession->Shutdown();
- }
- SAFE_RELEASE(m_pSink);
- SAFE_RELEASE(m_pSource);
- SAFE_RELEASE(m_pTopology);
- SAFE_RELEASE(m_pSession);
- }
- HRESULT CHSPlayer::Initialize(CALLBACK_FOR_CAPTUREDATA cb)
- {
- HRESULT hr = S_OK;
- //m_cb = cb;
- do
- {
- CHECK_HR(hr = MFStartup(MF_VERSION));
- if (SUCCEEDED(hr))
- {
- hr = CreateWavFile(cb);
- }
- } while (false);
- return hr;
- }
- HRESULT CHSPlayer::UnInitialize()
- {
- HRESULT hr = S_OK;
- if (m_pSession)
- {
- m_pSession->Close();
- }
- return hr;
- }
- HRESULT CHSPlayer::CreateMediaSourceForDevice(IMFMediaSource **ppSource)//const WCHAR *sURL,
- {
- HRESULT hr = S_OK;
- UINT32 count = 0;
- IMFAttributes *pConfig = NULL;
- IMFActivate **ppDevices = NULL;
- IMFMediaSource *pSource = NULL;
- // Create an attribute store to hold the search criteria.
- do
- {
- CHECK_HR(hr = MFCreateAttributes(&pConfig, 1));
- // Request video capture devices.
- CHECK_HR(hr = pConfig->SetGUID(
- MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE,
- MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_GUID//MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID
- ));
- // Enumerate the devices,
- CHECK_HR(hr = MFEnumDeviceSources(pConfig, &ppDevices, &count));
- // Create a media source for the first device in the list.
- if (count > 0)
- {
- CHECK_HR(hr = ppDevices[0]->ActivateObject(
- __uuidof(IMFMediaSource),
- (void**)&pSource
- ));
- // Return the pointer to the caller.
- *ppSource = pSource;
- (*ppSource)->AddRef();
- }
- else
- {
- hr = MF_E_NOT_FOUND;
- }
- }while(false);
- for (DWORD i = 0; i < count; i++)
- {
- ppDevices[i]->Release();
- }
- CoTaskMemFree(ppDevices);
- SAFE_RELEASE(pSource);
- return hr;
- }
- ///////////////////////////////////////////////////////////////////////
- // Name: CreateWavFile
- // Description: Creates a .wav file from an input file.
- ///////////////////////////////////////////////////////////////////////
- HRESULT CHSPlayer::CreateWavFile(CALLBACK_FOR_CAPTUREDATA cb)//const WCHAR *sURL, const WCHAR *sOutputFile
- {
- IMFByteStream *pStream = NULL;
- //IMFMediaSink *pSink = NULL;
- //IMFMediaSource *pSource = NULL;
- //IMFTopology *pTopology = NULL;
- //HRESULT hr = S_OK;
- WCHAR *sOutputFile = L"sound2.wav";//C:\Users\EN\Desktop\MediaFoundation1\TextPlayer\Debug
- HRESULT hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_DELETE_IF_EXIST, MF_FILEFLAGS_NONE, sOutputFile, &pStream);
- //if (FAILED(hr))
- //{
- //wprintf(L"MFCreateFile failed!n");
- //}
- // Create the WavSink object.
- if (SUCCEEDED(hr))
- {
- hr = CreateWavSink(pStream, &m_pSink, cb);
- }
- // Create the media source from the end point device.
- if (SUCCEEDED(hr))
- {
- hr = CreateMediaSourceForDevice(&m_pSource);
- }
- // Create the topology.
- if (SUCCEEDED(hr))
- {
- hr = CreateTopology(m_pSource, m_pSink, &m_pTopology);
- }
- // Run the media session.
- if (SUCCEEDED(hr))
- {
- hr = RunMediaSession(m_pTopology);
- if (FAILED(hr))
- {
- //wprintf(L"RunMediaSession failed!n");
- }
- }
- return hr;
- }
- void CHSPlayer::OnClearSessionEvent(IMFAsyncResult* pResult)
- {
- PROPVARIANT varStartPosition;
- PropVariantInit(&varStartPosition);
- HRESULT hrStatus = S_OK;
- IMFMediaEvent *pEvent = NULL;
- MediaEventType meType = MEUnknown;
- MF_TOPOSTATUS TopoStatus = MF_TOPOSTATUS_INVALID; // Used with MESessionTopologyStatus event.
- //hr = m_pSession->GetEvent(0, &pEvent);
- HRESULT hr = S_OK;
- //CComPtr<IMFMediaEvent> spEvent;
- hr = m_pSession->EndGetEvent(pResult, &pEvent);
- if (SUCCEEDED(hr))
- {
- hr = pEvent->GetStatus(&hrStatus);
- }
- if (SUCCEEDED(hr))
- {
- hr = pEvent->GetType(&meType);
- }
- if (SUCCEEDED(hr) && SUCCEEDED(hrStatus))
- {
- switch (meType)
- {
- case MESessionTopologySet:
- //wprintf(L"MESessionTopologySetn");
- break;
- case MESessionTopologyStatus:
- // Get the status code.
- hr = pEvent->GetUINT32(MF_EVENT_TOPOLOGY_STATUS, (UINT32*)&TopoStatus);
- if (SUCCEEDED(hr))
- {
- switch (TopoStatus)
- {
- case MF_TOPOSTATUS_READY:
- //wprintf(L"MESessionTopologyStatus: MF_TOPOSTATUS_READYn");
- hr = m_pSession->Start(&GUID_NULL, &varStartPosition);
- break;
- case MF_TOPOSTATUS_ENDED:
- //wprintf(L"MESessionTopologyStatus: MF_TOPOSTATUS_ENDEDn");
- break;
- }
- }
- break;
- case MESessionStarted:
- //wprintf(L"MESessionStartedn");
- break;
- case MESessionEnded:
- //wprintf(L"MESessionEndedn");
- hr = m_pSession->Stop();
- break;
- case MESessionStopped:
- //wprintf(L"MESessionStopped.n");
- hr = m_pSession->Close();
- break;
- case MESessionClosed:
- //wprintf(L"MESessionClosedn");
- //bGetAnotherEvent = FALSE;
- break;
- default:
- //wprintf(L"Media session event: %dn", meType);
- break;
- }
- }
- SAFE_RELEASE(pEvent);
- //if (FAILED(hr) || FAILED(hrStatus))
- //{
- // bGetAnotherEvent = FALSE;
- //}
- PropVariantClear(&varStartPosition);
- SAFE_RELEASE(pEvent);
- m_pSession->BeginGetEvent(&m_xOnClearSessionEvent, NULL);
- }
- ///////////////////////////////////////////////////////////////////////
- // Name: RunMediaSession
- // Description:
- // Queues the specified topology on the media session and runs the
- // media session until the MESessionEnded event is received.
- ///////////////////////////////////////////////////////////////////////
- HRESULT CHSPlayer::RunMediaSession(IMFTopology *pTopology)
- {
- //IMFMediaSession *pSession = NULL;
- HRESULT hr = S_OK;
- BOOL bGetAnotherEvent = TRUE;
- hr = MFCreateMediaSession(NULL, &m_pSession);
- if (SUCCEEDED(hr))
- {
- hr = m_pSession->SetTopology(0, pTopology);
- }
- if (SUCCEEDED(hr))
- {
- hr = m_pSession->BeginGetEvent(&m_xOnClearSessionEvent, NULL);
- }
- //wprintf(L"Shutting down the media session.n");
- //m_pSession->Shutdown();
- //SAFE_RELEASE(m_pSession);
- return hr;
- }
- ///////////////////////////////////////////////////////////////////////
- // Name: CreateTopology
- // Description: Creates the topology.
- //
- // Note: The first audio stream is conntected to the media sink.
- // Other streams are deselected.
- ///////////////////////////////////////////////////////////////////////
- HRESULT CHSPlayer::CreateTopology(IMFMediaSource *pSource, IMFMediaSink *pSink, IMFTopology **ppTopology)
- {
- IMFTopology *pTopology = NULL;
- IMFPresentationDescriptor *pPD = NULL;
- IMFStreamDescriptor *pSD = NULL;
- HRESULT hr = S_OK;
- DWORD cStreams = 0;
- hr = MFCreateTopology(&pTopology);
- if (SUCCEEDED(hr))
- {
- hr = pSource->CreatePresentationDescriptor(&pPD);
- }
- if (SUCCEEDED(hr))
- {
- hr = pPD->GetStreamDescriptorCount(&cStreams);
- }
- BOOL fConnected = FALSE;
- if (SUCCEEDED(hr))
- {
- GUID majorType = GUID_NULL;
- BOOL fSelected = FALSE;
- for (DWORD iStream = 0; iStream < cStreams; iStream++)
- {
- hr = pPD->GetStreamDescriptorByIndex(iStream, &fSelected, &pSD);
- if (FAILED(hr))
- {
- break;
- }
- // If the stream is not selected by default, ignore it.
- if (!fSelected)
- {
- continue;
- }
- // Get the major media type.
- hr = GetStreamMajorType(pSD, &majorType);
- if (FAILED(hr))
- {
- break;
- }
- // If it's not audio, deselect it and continue.
- if (majorType != MFMediaType_Audio)
- {
- // Deselect this stream
- hr = pPD->DeselectStream(iStream);
- if (FAILED(hr))
- {
- break;
- }
- else
- {
- continue;
- }
- }
- // It's an audio stream, so try to create the topology branch.
- hr = CreateTopologyBranch(pTopology, pSource, pPD, pSD, pSink);
- // Set our status flag.
- if (SUCCEEDED(hr))
- {
- fConnected = TRUE;
- }
- // At this point we have reached the first audio stream in the
- // source, so we can stop looking (whether we succeeded or failed).
- break;
- }
- }
- if (SUCCEEDED(hr))
- {
- // Even if we succeeded, if we didn't connect any streams, it's a failure.
- // (For example, it might be a video-only source.
- if (!fConnected)
- {
- hr = E_FAIL;
- }
- }
- if (SUCCEEDED(hr))
- {
- *ppTopology = pTopology;
- (*ppTopology)->AddRef();
- }
- SAFE_RELEASE(pTopology);
- SAFE_RELEASE(pPD);
- SAFE_RELEASE(pSD);
- return hr;
- }
- ///////////////////////////////////////////////////////////////////////
- // Name: CreateTopologyBranch
- // Description: Adds a source and sink to the topology and
- // connects them.
- //
- // pTopology: The topology.
- // pSource: The media source.
- // pPD: The source's presentation descriptor.
- // pSD: The stream descriptor for the stream.
- // pSink: The media sink.
- //
- ///////////////////////////////////////////////////////////////////////
- HRESULT CHSPlayer::CreateTopologyBranch(
- IMFTopology *pTopology,
- IMFMediaSource *pSource, // Media source.
- IMFPresentationDescriptor *pPD, // Presentation descriptor.
- IMFStreamDescriptor *pSD, // Stream descriptor.
- IMFMediaSink *pSink
- )
- {
- IMFTopologyNode *pSourceNode = NULL;
- IMFTopologyNode *pOutputNode = NULL;
- HRESULT hr = S_OK;
- hr = CreateSourceNode(pSource, pPD, pSD, &pSourceNode);
- if (SUCCEEDED(hr))
- {
- hr = CreateOutputNode(pSink, 0, &pOutputNode);
- }
- if (SUCCEEDED(hr))
- {
- hr = pTopology->AddNode(pSourceNode);
- }
- if (SUCCEEDED(hr))
- {
- hr = pTopology->AddNode(pOutputNode);
- }
- if (SUCCEEDED(hr))
- {
- hr = pSourceNode->ConnectOutput(0, pOutputNode, 0);
- }
- SAFE_RELEASE(pSourceNode);
- SAFE_RELEASE(pOutputNode);
- return hr;
- }
- //////////////////////////////////////////////////////////////////////
- // Name: CreateSourceNode
- // Creates a source node for a media stream.
- //
- // pSource: Pointer to the media source.
- // pSourcePD: Pointer to the source's presentation descriptor.
- // pSourceSD: Pointer to the stream descriptor.
- // ppNode: Receives the IMFTopologyNode pointer.
- ///////////////////////////////////////////////////////////////////////
- HRESULT CHSPlayer::CreateSourceNode(
- IMFMediaSource *pSource, // Media source.
- IMFPresentationDescriptor *pPD, // Presentation descriptor.
- IMFStreamDescriptor *pSD, // Stream descriptor.
- IMFTopologyNode **ppNode // Receives the node pointer.
- )
- {
- IMFTopologyNode *pNode = NULL;
- HRESULT hr = S_OK;
- // Create the node.
- hr = MFCreateTopologyNode(
- MF_TOPOLOGY_SOURCESTREAM_NODE,
- &pNode);
- // Set the attributes.
- if (SUCCEEDED(hr))
- {
- hr = pNode->SetUnknown(MF_TOPONODE_SOURCE, pSource);
- }
- if (SUCCEEDED(hr))
- {
- hr = pNode->SetUnknown(
- MF_TOPONODE_PRESENTATION_DESCRIPTOR,
- pPD);
- }
- if (SUCCEEDED(hr))
- {
- hr = pNode->SetUnknown(
- MF_TOPONODE_STREAM_DESCRIPTOR,
- pSD);
- }
- // Return the pointer to the caller.
- if (SUCCEEDED(hr))
- {
- *ppNode = pNode;
- (*ppNode)->AddRef();
- }
- SAFE_RELEASE(pNode);
- return hr;
- }
- ///////////////////////////////////////////////////////////////////////
- // Name: CreateOutputNode
- // Description: Creates an output node for a stream sink.
- //
- // pSink: The media sink.
- // iStream: Index of the stream sink on the media sink.
- // ppNode: Receives a pointer to the topology node.
- ///////////////////////////////////////////////////////////////////////
- HRESULT CHSPlayer::CreateOutputNode(IMFMediaSink *pSink, DWORD iStream, IMFTopologyNode **ppNode)
- {
- IMFTopologyNode *pNode = NULL;
- IMFStreamSink *pStream = NULL;
- HRESULT hr = S_OK;
- hr = pSink->GetStreamSinkByIndex(iStream, &pStream);
- if (SUCCEEDED(hr))
- {
- hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &pNode);
- }
- if (SUCCEEDED(hr))
- {
- hr = pNode->SetObject(pStream);
- }
- if (SUCCEEDED(hr))
- {
- *ppNode = pNode;
- (*ppNode)->AddRef();
- }
- SAFE_RELEASE(pNode);
- SAFE_RELEASE(pStream);
- return hr;
- }
- ///////////////////////////////////////////////////////////////////////
- // Name: GetStreamMajorType
- // Description: Get the major media type from a stream descriptor.
- //
- // Note:
- // To get the major media type from a stream descriptor, you need to go
- // through the stream descriptor's media type handler. Use this helper
- // function if you don't need the type handler for anything else.
- //
- /////////////////////////////////////////////////////////////////////////
- HRESULT CHSPlayer::GetStreamMajorType(IMFStreamDescriptor *pSD, GUID *pguidMajorType)
- {
- CheckPointer(pSD, E_POINTER);
- CheckPointer(pguidMajorType, E_POINTER);
- HRESULT hr = S_OK;
- IMFMediaTypeHandler *pHandler = NULL;
- hr = pSD->GetMediaTypeHandler(&pHandler);
- if (SUCCEEDED(hr))
- {
- hr = pHandler->GetMajorType(pguidMajorType);
- }
- SAFE_RELEASE(pHandler);
- return hr;
- }
- // AddRef and Release for callbacks only; not functional
- LONG CHSPlayer::AddRef()
- {
- return m_cRef;
- }
- LONG CHSPlayer::Release()
- {
- return m_cRef;
- }