Hi,
I am a newbie, so please excuse any unqualified remarks.
I am trying to write a little movie player and want it to play ANY media file imaginable. After installing Real Alternative, I was hoping that I could play rm files, but there seems to be a bit of a problem. The sound is OK, yet the picture stays black. GraphEdit shows that by default the AVI decoder filter is being used, even with rm files. Removing this filter in GraphEdit solves the problem, the picture is OK.
My question is, Does PB offer a way to "disable" a certain filter? Or would there be a way to build a custom graph for a media file?
Any help will be appreciated.
Directshow Filter Selection
Directshow Filter Selection
The manual said 'Windows XP or better' ... so I used Linux.
Re: Directshow Filter Selection
Here's some code (from the german forums) using a dedicated filtergraph, maybe that helps:
http://forums.purebasic.com/german/viewtopic.php?t=1054
http://forums.purebasic.com/german/viewtopic.php?t=1054
Code: Select all
;
; http://forums.purebasic.com/german/viewtopic.php?t=1054
;
#CLSCTX_INPROC_SERVER = $1
#VFW_E_NOT_FOUND = $80040216
#MAX_FILTER_NAME = 128
Structure FilterInfo
achName.b[#MAX_FILTER_NAME]
lpFilterGraph.IFilterGraph
EndStructure
Enumeration
#PINDIR_INPUT
#PINDIR_OUTPUT
EndEnumeration
CoInitialize_(0)
Debug CoCreateInstance_(?CLSID_FilterGraph, #NULL,#CLSCTX_INPROC_SERVER,?IID_IGraphBuilder,@lpGB.IGraphBuilder)
Debug lpGB\QueryInterface(?IID_IMediaControl,@lpMC.IMediaControl)
Debug CoCreateInstance_(?CLSID_Source_Filter, #NULL, #CLSCTX_INPROC_SERVER,?IID_IBaseFilter,@lpSource_Filter.IBaseFilter)
Debug CoCreateInstance_(?CLSID_Avi_Decompressor, #NULL, #CLSCTX_INPROC_SERVER,?IID_IBaseFilter,@lpAvi_Decompressor.IBaseFilter)
Debug CoCreateInstance_(?CLSID_VideoRenderer, #NULL, #CLSCTX_INPROC_SERVER,?IID_IBaseFilter,@lpVRender.IBaseFilter)
file.s = "I:\Clock.avi"
; SOURCE Filter
Dim wavFile.w(Len(file))
MultiByteToWideChar_(#CP_ACP, 0, file, -1, wavFile(), Len(file))
Debug lpGB\AddSourceFilter(@wavFile(), @wavFile(), @lpSource_Filter)
lpSource_Filter\EnumPins(@lpNUM.IEnumPins)
While lpNUM\Next(1,@lpPin.IPin,0) = #S_OK
lpPin\QueryDirection(@a)
If a = #PINDIR_OUTPUT
lpSource_FilterPinOut = lpPin
EndIf
Wend
Debug lpSource_FilterPinOut
;AVI_Decompressor
Debug lpGB\AddFilter(lpAvi_Decompressor, @"AVI_Decompressor")
lpAvi_Decompressor\EnumPins(@lpNUM.IEnumPins)
While lpNUM\Next(1,@lpPin.IPin,0) = #S_OK
lpPin\QueryDirection(@a)
If a = #PINDIR_OUTPUT
lpAvi_DecompressorPinOut = lpPin
EndIf
If a = #PINDIR_INPUT
lpAvi_DecompressorPinIn = lpPin
EndIf
Wend
Debug lpAvi_DecompressorPinIn
Debug lpAvi_DecompressorPinOut
; Renderer
Debug lpGB\AddFilter(lpVRender, @"Video_Renderer")
lpVRender\EnumPins(@lpNUM.IEnumPins)
While lpNUM\Next(1,@lpPin.Ipin,0) = #S_OK
lpPin\QueryDirection(@a)
If a = #PINDIR_INPUT
lpVRenderPinIn = lpPin
EndIf
Wend
Debug lpVRenderPinIn
; Pins verbinden
Debug lpGB\Connect(lpSource_FilterPinOut,lpAvi_DecompressorPinIn)
Debug lpGB\Connect(lpAvi_DecompressorPinOut,lpVRenderPinIn)
; Verwendete Filter anzeigen
Debug lpGB\EnumFilters(@lpEnum.IEnumFilters)
While lpEnum\Next(1,@lpFilter.IBaseFilter,0) = #S_OK
lpFilter\QueryFilterinfo(@info.FilterInfo)
Debug PeekS(@info\achName)
Wend
; Wiedergabe starten
lpMC\Run()
; Freigabe
lpFilter\Release()
lpEnum\Release()
lpPin\Release()
lpNUM\Release()
lpVRender\Release()
lpAvi_Decompressor\Release()
lpSource_Filter\Release()
lpMC\Release()
lpGB\Release()
CoUninitialize_()
DataSection
CLSID_FilterGraph:
Data.l $E436EBB3
Data.w $524F,$11CE
Data.b $9F,$53,$00,$20,$AF,$0B,$A7,$70
IID_IGraphBuilder:
Data.l $56A868A9
Data.W $0AD4,$11CE
Data.b $B0,$3A,$00,$20,$AF,$0B,$A7,$70
CLSID_Source_Filter:
Data.l $D3588AB0
Data.w $0781,$11CE
Data.b $B0,$3A,$00,$20,$AF,$0B,$A7,$70
CLSID_Avi_Splitter:
Data.l $1B544C20
Data.w $FD0B,$11CE
Data.b $8C,$63,$00,$AA,$00,$44,$B5,$1E
IID_IBaseFilter:
Data.l $56A86895
Data.w $0AD4,$11CE
Data.b $B0,$3A,$00,$20,$AF,$0B,$A7,$70
CLSID_Avi_Decompressor:
Data.l $CF49D4E0
Data.w $1115,$11CE
Data.b $B0,$3A,$00,$20,$AF,$0B,$A7,$70
CLSID_VideoRenderer:
Data.l $70E102B0
Data.w $5556,$11CE
Data.b $97,$C0,$00,$AA,$00,$55,$59,$5A
IID_IMediaControl:
Data.l $56A868B1
Data.w $0AD4,$11CE
Data.b $B0,$3A,$00,$20,$AF,$0B,$A7,$70
EndDataSection
Last edited by traumatic on Tue Mar 15, 2005 9:33 am, edited 1 time in total.
Good programmers don't comment their code. It was hard to write, should be hard to read.
I have another question. For debug purposes, is there a simple way in PureBasic to either save the used gragh to a .grf file to be opened later in GraphEdit or add the running graph to the Running Objects Table in order to connect GraphEdit to the graph.
I did find c++ functions on the Microsoft website for this, but neither am I overly familiar with c++ nor do I know PureBasic well enough to convert these funtions from c++.
I did find c++ functions on the Microsoft website for this, but neither am I overly familiar with c++ nor do I know PureBasic well enough to convert these funtions from c++.
The manual said 'Windows XP or better' ... so I used Linux.
Here's the MS-code to add a graph to the tablenormen wrote:[...] or add the running graph to the Running Objects Table in order to connect GraphEdit to the graph.
(see http://forums.purebasic.com/german/view ... 6301#26301 for further explanations in german)
Code: Select all
#ROTFLAGS_REGISTRATIONKEEPSALIVE = $01
Structure WCHAR
c.w[#MAX_PATH]
EndStructure
Procedure.l AddToRot(*pUnkGraph.IUnknown, *pdwRegister.l)
*pMoniker.IMoniker
*pROT.IRunningObjectTable
If GetRunningObjectTable_(0, @*pROT) <> 0
ProcedureReturn #E_FAIL
EndIf
sz.s = "FilterGraph "+LCase(RSet(Hex(*pUnkGraph), 8, "0"))+" pid "+LCase(RSet(Hex(GetCurrentProcessId_()), 8, "0"))
MultiByteToWideChar_(#CP_ACP, 0, sz, -1, @wsz.WCHAR, Len(sz))
MultiByteToWideChar_(#CP_ACP, 0, "!", -1, @wsz2.WCHAR, 1)
hr.l = CreateItemMoniker_(wsz2, wsz, @*pMoniker)
If hr = 0
hr = *pROT\Register(#ROTFLAGS_REGISTRATIONKEEPSALIVE, *pUnkGraph, *pMoniker, *pdwRegister)
*pMoniker\Release()
EndIf
*pROT\Release()
ProcedureReturn hr
EndProcedure
BTW: Does anyone have a good (a really good
Good programmers don't comment their code. It was hard to write, should be hard to read.
Maybe something like this:traumatic wrote:BTW: Does anyone have a good (a really good) idea to simplify the widechar mess?
Code: Select all
Procedure.l L(string.s)
*out = AllocateMemory(Len(string)*2 * #SIZEOF_WORD)
MultiByteToWideChar_(#CP_ACP, 0, string, -1, *out, Len(string))
ProcedureReturn *out
EndProcedure
Code: Select all
.
.
.
Code: Select all
wsz.l = L("FilterGraph "+LCase(RSet(Hex(*pUnkGraph), 8, "0"))+" pid "+LCase(RSet(Hex(GetCurrentProcessId_()), 8, "0")))
hr.l = CreateItemMoniker_(L("!"), wsz, @*pMoniker)
Good programmers don't comment their code. It was hard to write, should be hard to read.

