Commit 6bc91ea5 authored by Gildas Bazin's avatar Gildas Bazin

* modules/access/dshow/*:

  - switch to access_demux module for raw video/audio streams.
  - massive cleanup and simplifications.
  - a bunch of fixes.
parent b2c7b5a0
SOURCES_dshow = dshow.cpp filter.cpp filter.h SOURCES_dshow = dshow.cpp common.h filter.cpp filter.h crossbar.cpp
/*****************************************************************************
* common.h : DirectShow access module for vlc
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id$
*
* Author: Gildas Bazin <gbazin@videolan.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#include <string>
#include <list>
#include <deque>
using namespace std;
#ifndef _MSC_VER
# include <wtypes.h>
# include <unknwn.h>
# include <ole2.h>
# include <limits.h>
# define _WINGDI_ 1
# define AM_NOVTABLE
# define _OBJBASE_H_
# undef _X86_
# define _I64_MAX LONG_LONG_MAX
# define LONGLONG long long
#endif
#include <dshow.h>
typedef struct dshow_stream_t dshow_stream_t;
/****************************************************************************
* Crossbar stuff
****************************************************************************/
#define MAX_CROSSBAR_DEPTH 10
typedef struct CrossbarRouteRec
{
IAMCrossbar *pXbar;
LONG VideoInputIndex;
LONG VideoOutputIndex;
LONG AudioInputIndex;
LONG AudioOutputIndex;
} CrossbarRoute;
void DeleteCrossbarRoutes( access_sys_t * );
HRESULT FindCrossbarRoutes( vlc_object_t *, access_sys_t *,
IPin *, LONG, int = 0 );
/****************************************************************************
* Access descriptor declaration
****************************************************************************/
struct access_sys_t
{
/* These 2 must be left at the beginning */
vlc_mutex_t lock;
vlc_cond_t wait;
IFilterGraph *p_graph;
ICaptureGraphBuilder2 *p_capture_graph_builder2;
IMediaControl *p_control;
int i_crossbar_route_depth;
CrossbarRoute crossbar_routes[MAX_CROSSBAR_DEPTH];
/* list of elementary streams */
dshow_stream_t **pp_streams;
int i_streams;
int i_current_stream;
/* misc properties */
int i_width;
int i_height;
int i_chroma;
};
/*****************************************************************************
* crossbar.c : DirectShow access module for vlc
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id$
*
* Author: Damien Fouilleul <damien dot fouilleul at laposte dot net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <vlc/vlc.h>
#include <vlc/input.h>
#include <vlc/vout.h>
#include "common.h"
/*****************************************************************************
* DeleteCrossbarRoutes
*****************************************************************************/
void DeleteCrossbarRoutes( access_sys_t *p_sys )
{
/* Remove crossbar filters from graph */
for( int i = 0; i < p_sys->i_crossbar_route_depth; i++ )
{
p_sys->crossbar_routes[i].pXbar->Release();
}
p_sys->i_crossbar_route_depth = 0;
}
/*****************************************************************************
* RouteCrossbars (Does not AddRef the returned *Pin)
*****************************************************************************/
static HRESULT GetCrossbarIPinAtIndex( IAMCrossbar *pXbar, LONG PinIndex,
BOOL IsInputPin, IPin ** ppPin )
{
LONG cntInPins, cntOutPins;
IPin *pP = 0;
IBaseFilter *pFilter = NULL;
IEnumPins *pins=0;
ULONG n;
if( !pXbar || !ppPin ) return E_POINTER;
*ppPin = 0;
if( S_OK != pXbar->get_PinCounts(&cntOutPins, &cntInPins) ) return E_FAIL;
LONG TrueIndex = IsInputPin ? PinIndex : PinIndex + cntInPins;
if( pXbar->QueryInterface(IID_IBaseFilter, (void **)&pFilter) == S_OK )
{
if( SUCCEEDED(pFilter->EnumPins(&pins)) )
{
LONG i = 0;
while( pins->Next(1, &pP, &n) == S_OK )
{
pP->Release();
if( i == TrueIndex )
{
*ppPin = pP;
break;
}
i++;
}
pins->Release();
}
pFilter->Release();
}
return *ppPin ? S_OK : E_FAIL;
}
/*****************************************************************************
* GetCrossbarIndexFromIPin: Find corresponding index of an IPin on a crossbar
*****************************************************************************/
static HRESULT GetCrossbarIndexFromIPin( IAMCrossbar * pXbar, LONG * PinIndex,
BOOL IsInputPin, IPin * pPin )
{
LONG cntInPins, cntOutPins;
IPin *pP = 0;
IBaseFilter *pFilter = NULL;
IEnumPins *pins = 0;
ULONG n;
BOOL fOK = FALSE;
if(!pXbar || !PinIndex || !pPin )
return E_POINTER;
if( S_OK != pXbar->get_PinCounts(&cntOutPins, &cntInPins) )
return E_FAIL;
if( pXbar->QueryInterface(IID_IBaseFilter, (void **)&pFilter) == S_OK )
{
if( SUCCEEDED(pFilter->EnumPins(&pins)) )
{
LONG i=0;
while( pins->Next(1, &pP, &n) == S_OK )
{
pP->Release();
if( pPin == pP )
{
*PinIndex = IsInputPin ? i : i - cntInPins;
fOK = TRUE;
break;
}
i++;
}
pins->Release();
}
pFilter->Release();
}
return fOK ? S_OK : E_FAIL;
}
/*****************************************************************************
* FindCrossbarRoutes
*****************************************************************************/
HRESULT FindCrossbarRoutes( vlc_object_t *p_this, access_sys_t *p_sys,
IPin *p_input_pin, LONG physicalType, int depth )
{
HRESULT result = S_FALSE;
IPin *p_output_pin;
if( FAILED(p_input_pin->ConnectedTo(&p_output_pin)) ) return S_FALSE;
// It is connected, so now find out if the filter supports IAMCrossbar
PIN_INFO pinInfo;
if( FAILED(p_output_pin->QueryPinInfo(&pinInfo)) ||
PINDIR_OUTPUT != pinInfo.dir )
{
p_output_pin->Release ();
return S_FALSE;
}
IAMCrossbar *pXbar=0;
if( FAILED(pinInfo.pFilter->QueryInterface(IID_IAMCrossbar,
(void **)&pXbar)) )
{
pinInfo.pFilter->Release();
p_output_pin->Release ();
return S_FALSE;
}
LONG inputPinCount, outputPinCount;
if( FAILED(pXbar->get_PinCounts(&outputPinCount, &inputPinCount)) )
{
pXbar->Release();
pinInfo.pFilter->Release();
p_output_pin->Release ();
return S_FALSE;
}
LONG inputPinIndexRelated, outputPinIndexRelated;
LONG inputPinPhysicalType, outputPinPhysicalType;
LONG inputPinIndex, outputPinIndex;
if( FAILED(GetCrossbarIndexFromIPin( pXbar, &outputPinIndex,
FALSE, p_output_pin )) ||
FAILED(pXbar->get_CrossbarPinInfo( FALSE, outputPinIndex,
&outputPinIndexRelated,
&outputPinPhysicalType )) )
{
pXbar->Release();
pinInfo.pFilter->Release();
p_output_pin->Release ();
return S_FALSE;
}
//
// for all input pins
//
for( inputPinIndex = 0; S_OK != result && inputPinIndex < inputPinCount;
inputPinIndex++ )
{
if( FAILED(pXbar->get_CrossbarPinInfo( TRUE, inputPinIndex,
&inputPinIndexRelated, &inputPinPhysicalType )) ) continue;
// Is the pin a video pin?
if( inputPinPhysicalType != physicalType ) continue;
// Can we route it?
if( FAILED(pXbar->CanRoute(outputPinIndex, inputPinIndex)) ) continue;
IPin *pPin;
if( FAILED(GetCrossbarIPinAtIndex( pXbar, inputPinIndex,
TRUE, &pPin)) ) continue;
result = FindCrossbarRoutes( p_this, p_sys, pPin,
physicalType, depth+1 );
if( S_OK == result || (S_FALSE == result &&
physicalType == inputPinPhysicalType &&
(p_sys->i_crossbar_route_depth = depth+1) < MAX_CROSSBAR_DEPTH) )
{
// hold on crossbar
pXbar->AddRef();
// remember crossbar route
p_sys->crossbar_routes[depth].pXbar = pXbar;
p_sys->crossbar_routes[depth].VideoInputIndex = inputPinIndex;
p_sys->crossbar_routes[depth].VideoOutputIndex = outputPinIndex;
p_sys->crossbar_routes[depth].AudioInputIndex = inputPinIndexRelated;
p_sys->crossbar_routes[depth].AudioOutputIndex = outputPinIndexRelated;
msg_Dbg( p_this, "Crossbar at depth %d, Found Route For "
"ouput %ld (type %ld) to input %ld (type %ld)", depth,
outputPinIndex, outputPinPhysicalType, inputPinIndex,
inputPinPhysicalType );
result = S_OK;
}
}
pXbar->Release();
pinInfo.pFilter->Release();
p_output_pin->Release ();
return result;
}
This diff is collapsed.
This diff is collapsed.
...@@ -69,7 +69,8 @@ class CapturePin: public IPin, public IMemInputPin ...@@ -69,7 +69,8 @@ class CapturePin: public IPin, public IMemInputPin
{ {
friend class CaptureEnumMediaTypes; friend class CaptureEnumMediaTypes;
access_t *p_input; vlc_object_t *p_input;
access_sys_t *p_sys;
CaptureFilter *p_filter; CaptureFilter *p_filter;
IPin *p_connected_pin; IPin *p_connected_pin;
...@@ -84,7 +85,8 @@ class CapturePin: public IPin, public IMemInputPin ...@@ -84,7 +85,8 @@ class CapturePin: public IPin, public IMemInputPin
long i_ref; long i_ref;
public: public:
CapturePin( access_t * _p_input, CaptureFilter *_p_filter, CapturePin( vlc_object_t *_p_input, access_sys_t *p_sys,
CaptureFilter *_p_filter,
AM_MEDIA_TYPE *mt, size_t mt_count ); AM_MEDIA_TYPE *mt, size_t mt_count );
virtual ~CapturePin(); virtual ~CapturePin();
...@@ -134,7 +136,7 @@ class CaptureFilter : public IBaseFilter ...@@ -134,7 +136,7 @@ class CaptureFilter : public IBaseFilter
{ {
friend class CapturePin; friend class CapturePin;
access_t *p_input; vlc_object_t *p_input;
CapturePin *p_pin; CapturePin *p_pin;
IFilterGraph *p_graph; IFilterGraph *p_graph;
//AM_MEDIA_TYPE media_type; //AM_MEDIA_TYPE media_type;
...@@ -143,7 +145,8 @@ class CaptureFilter : public IBaseFilter ...@@ -143,7 +145,8 @@ class CaptureFilter : public IBaseFilter
long i_ref; long i_ref;
public: public:
CaptureFilter( access_t * _p_input, AM_MEDIA_TYPE *mt, size_t mt_count ); CaptureFilter( vlc_object_t *_p_input, access_sys_t *p_sys,
AM_MEDIA_TYPE *mt, size_t mt_count );
virtual ~CaptureFilter(); virtual ~CaptureFilter();
/* IUnknown methods */ /* IUnknown methods */
...@@ -178,14 +181,14 @@ class CaptureFilter : public IBaseFilter ...@@ -178,14 +181,14 @@ class CaptureFilter : public IBaseFilter
****************************************************************************/ ****************************************************************************/
class CaptureEnumPins : public IEnumPins class CaptureEnumPins : public IEnumPins
{ {
access_t * p_input; vlc_object_t *p_input;
CaptureFilter *p_filter; CaptureFilter *p_filter;
int i_position; int i_position;
long i_ref; long i_ref;
public: public:
CaptureEnumPins( access_t * _p_input, CaptureFilter *_p_filter, CaptureEnumPins( vlc_object_t *_p_input, CaptureFilter *_p_filter,
CaptureEnumPins *pEnumPins ); CaptureEnumPins *pEnumPins );
virtual ~CaptureEnumPins(); virtual ~CaptureEnumPins();
...@@ -206,7 +209,7 @@ public: ...@@ -206,7 +209,7 @@ public:
****************************************************************************/ ****************************************************************************/
class CaptureEnumMediaTypes : public IEnumMediaTypes class CaptureEnumMediaTypes : public IEnumMediaTypes
{ {
access_t * p_input; vlc_object_t *p_input;
CapturePin *p_pin; CapturePin *p_pin;
AM_MEDIA_TYPE cx_media_type; AM_MEDIA_TYPE cx_media_type;
...@@ -214,7 +217,7 @@ class CaptureEnumMediaTypes : public IEnumMediaTypes ...@@ -214,7 +217,7 @@ class CaptureEnumMediaTypes : public IEnumMediaTypes
long i_ref; long i_ref;
public: public:
CaptureEnumMediaTypes( access_t * _p_input, CapturePin *_p_pin, CaptureEnumMediaTypes( vlc_object_t *_p_input, CapturePin *_p_pin,
CaptureEnumMediaTypes *pEnumMediaTypes ); CaptureEnumMediaTypes *pEnumMediaTypes );
virtual ~CaptureEnumMediaTypes(); virtual ~CaptureEnumMediaTypes();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment