[vlc] Re: Live Streaming
Bill Eldridge
bill at rfa.org
Wed Aug 6 13:57:49 CEST 2003
Alexis de Lattre wrote:
>On Tue, Aug 05, 2003, Mathew, Tisson K wrote :
>
>
>>Does VLC support live video streaming on windows?
>>
>>
>
>No... this feature is "Linux only", as explained on
>
>http://www.videolan.org/vlc/features.html
>
>We would love to have a "Direct Show" input for VLC... but no developer
>have volunteered for this work.
>
>
>
Here's some DirectX 8.1 code off codeguru from which someone could hack
out the video device part. I don't know anything about various issues
that would make this unworkable or way too primitive to be usable.
Relevant Functions:
CPreviewMovieDlg::GetDeviceInterfaces()
CPreviewMovieDlg::FindCaptureDevice(IBaseFilter** ppBaseFilter)
CPreviewMovieDlg::CaptureVideo()
CPreviewMovieDlg::CloseInterfaces()
http://www.codeguru.com/directx/DirectXApp.html
Excerpt:
===============================================
BOOL CPreviewMovieDlg::OnInitDialog()
{
CDialog::OnInitDialog();
HRESULT hr;
hr = CaptureVideo();
if(FAILED(hr))
{
CloseInterfaces();
OnOK();
}
return TRUE;
}
HRESULT CPreviewMovieDlg::CaptureVideo()
{
HRESULT hr;
IBaseFilter *pBaseFilter = NULL;
//Get DirectShow Interfaces
hr = GetDeviceInterfaces();
if(FAILED(hr))
{
TRACE1(("Could not initialize the video interfaces!
hr=0x%x"), hr);
return hr;
}
// Attach the filter graph to the capture graph
hr = m_pCaptureGraphBuilder->SetFiltergraph(m_pGraphBuilder);
if(FAILED(hr))
{
TRACE1(("Could not set the filter graph to capture
graph! hr=0x%x"), hr);
return hr;
}
// Add our graph to the running object table, which will allow
// the GraphEdit application to "spy" on our graph
#ifdef REGISTER_FILTERGRAPH
hr = AddGraphToRot(m_pGraphBuilder, &m_dwGraphRegister);
if (FAILED(hr))
{
TRACE1(TEXT("Failed to register filter graph with ROT!
hr=0x%x"), hr);
m_dwGraphRegister = 0;
}
#endif
// Use the system device enumerator and class enumerator to find
// a video capture/preview device, such as a desktop USB video camera.
hr = FindCaptureDevice(&pBaseFilter);
if(FAILED(hr))
{
return hr;
}
// Add Capture filter to our graph.
hr = m_pGraphBuilder->AddFilter(pBaseFilter, L"Video Capture");
if(FAILED(hr))
{
TRACE1(TEXT("Couldn't add capture filter to graph! hr=0x%x"), hr);
pBaseFilter->Release();
return hr;
}
hr = m_pCaptureGraphBuilder->RenderStream(&PIN_CATEGORY_PREVIEW,
&MEDIATYPE_Video, pBaseFilter,
NULL, NULL);
if (FAILED(hr))
{
TRACE1(TEXT("Couldn't render capture stream. "
"The device may already be in use.\r\n\r\nhr=0x%x"), hr);
pBaseFilter->Release();
return hr;
}
// Now that the filter has been added to the graph and we have
// rendered its stream, we can release this reference to the filter.
pBaseFilter->Release();
// Set video window style and position
hr = SetupVideoWindow();
if (FAILED(hr))
{
TRACE1(TEXT("Couldn't initialize video window! hr=0x%x"), hr);
return hr;
}
// Start previewing video data
hr = m_pMediaControl->Run();
if(FAILED(hr))
{
TRACE1(TEXT("Couldn't run the graph! hr=0x%x"), hr);
return hr;
}
return S_OK;
}
HRESULT CPreviewMovieDlg::GetDeviceInterfaces()
{
HRESULT hr;
//Create the filter graph
hr = CoCreateInstance (CLSID_FilterGraph, NULL, CLSCTX_INPROC,
IID_IGraphBuilder, (void **)&m_pGraphBuilder);
if(FAILED(hr))
return hr;
//Create the Capture graph
hr = CoCreateInstance (CLSID_CaptureGraphBuilder2, NULL,
CLSCTX_INPROC,
IID_ICaptureGraphBuilder2, (void
**)&m_pCaptureGraphBuilder);
if(FAILED(hr))
return hr;
//Obtain the interfaces for media control, video and media event
interfaces
hr = m_pGraphBuilder->QueryInterface (IID_IMediaControl, (void
**)&m_pMediaControl);
if(FAILED(hr))
return hr;
hr = m_pGraphBuilder->QueryInterface (IID_IVideoWindow, (void
**)&m_pViewWindow);
if(FAILED(hr))
return hr;
hr = m_pGraphBuilder->QueryInterface (IID_IMediaEvent, (void
**)&m_pMediaEventEx);
if(FAILED(hr))
return hr;
//Set the window handle used to process graph events
m_pMediaEventEx->SetNotifyWindow((OAHWND)m_hWnd, WM_GRAPHNOTIFY, 0);
return hr;
}
HRESULT CPreviewMovieDlg::FindCaptureDevice(IBaseFilter** ppBaseFilter)
{
IBaseFilter *pBase = NULL;
HRESULT hr;
CComPtr <IMoniker> pMoniker = NULL;
ULONG lFetched;
// Create the system device enumerator
CComPtr <ICreateDevEnum> pDevEnum = NULL;
hr = CoCreateInstance (CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC,
IID_ICreateDevEnum, (void **)&pDevEnum);
if(FAILED(hr))
{
TRACE1(("Failed to create the device enumerator!
hr=0x%x"), hr);
return hr;
}
// Create an enumerator for the video capture devices
CComPtr <IEnumMoniker> pClassEnum = NULL;
hr = pDevEnum->CreateClassEnumerator
(CLSID_VideoInputDeviceCategory, &pClassEnum, 0);
if(FAILED(hr))
{
TRACE1(("Failed to create the class enumerator!
hr=0x%x"), hr);
return hr;
}
// If there are no enumerators for the requested type, then
// CreateClassEnumerator will succeed, but pClassEnum will be NULL.
if (pClassEnum == NULL)
{
MessageBox(TEXT("No video capture device was detected.\r\n\r\n")
TEXT("This program requires a video capture device,
such as a USB WebCam,\r\n")
TEXT("to be installed and working properly. The
program will now close."),
TEXT("No Video Capture Hardware"), MB_OK |
MB_ICONINFORMATION);
return E_FAIL;
}
// Note that if the Next() call succeeds but there are no monikers,
// it will return S_FALSE (which is not a failure). Therefore, we
// check that the return code is S_OK instead of using SUCCEEDED()
macro.
//loop while we can still enumerate, the enumeration succeeds, and
while we have'nt yet found a dv camera
while( (pClassEnum->Next(1, &pMoniker, &lFetched)) == S_OK)
{
// getting the propert page to get the device name
IPropertyBag *pBag;
hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag,
reinterpret_cast<PVOID *>(&pBag));
if ( SUCCEEDED(hr) )
{
VARIANT var;
var.vt = VT_BSTR;
hr = pBag->Read(L"FriendlyName", &var, NULL);
if ( SUCCEEDED(hr) )
{
CString strDevName;
USES_CONVERSION;
strDevName = W2A(var.bstrVal);
m_cboDevice.AddString(strDevName);
SysFreeString(var.bstrVal);
// Bind Moniker to a filter object
hr = pMoniker->BindToObject(0, 0,
IID_IBaseFilter, reinterpret_cast<LPVOID *>(&pBase));
if (FAILED(hr))
{
TRACE1(TEXT("Couldn't bind
moniker to filter object! hr=0x%x"), hr);
return hr;
}
}
pBag->Release();
}
}
*ppBaseFilter = pBase;
return hr;
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/vlc/attachments/20030806/a0da332a/attachment.html>
More information about the vlc
mailing list