Skip to content

Commit

Permalink
* modules/access/dshow/*:
Browse files Browse the repository at this point in the history
  - switch to access_demux module for raw video/audio streams.
  - massive cleanup and simplifications.
  - a bunch of fixes.
  • Loading branch information
Gildas Bazin committed Sep 12, 2004
1 parent b2c7b5a commit 6bc91ea
Show file tree
Hide file tree
Showing 6 changed files with 1,125 additions and 1,216 deletions.
2 changes: 1 addition & 1 deletion modules/access/dshow/Modules.am
Original file line number Diff line number Diff line change
@@ -1 +1 @@
SOURCES_dshow = dshow.cpp filter.cpp filter.h
SOURCES_dshow = dshow.cpp common.h filter.cpp filter.h crossbar.cpp
93 changes: 93 additions & 0 deletions modules/access/dshow/common.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/*****************************************************************************
* common.h : DirectShow access module for vlc
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id$
*
* Author: Gildas Bazin <[email protected]>
*
* 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;
};
240 changes: 240 additions & 0 deletions modules/access/dshow/crossbar.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,240 @@
/*****************************************************************************
* 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;
}
Loading

0 comments on commit 6bc91ea

Please sign in to comment.