Hello
how to change the format type to media video?
which filter to use?
While I got mediatypes working 12 years ago (sigh) - I no longer have that code with me (company owned code). For my recent DSPack work, I've only ever been interested in playing video - and for that, the general FilterGraph.RenderFile is more than sufficient...
This works only MPG2 file.
how can I work with all video formats?
and which filter to use?
As I say, with regards to MPEG-2, I've only ever ensured a valid codec is installed on the system, then used the standard FilterGraph.RenderFile('C:\film\01\video.mp4') to play the video.
If insufficient filters exist in the graph, then RenderFile adds video/audio renderers (as required) then attempts to build up the graph between them. RenderFile then attempts to connect all the pins together using the most valid mediatypes - automatically.
Looks like you're attempting to do something other than play video... So I've no concrete advice, only ideas.
Try adding a consumer of some sort to the graph (video renderer, file writer - whatever it is you're trying to do), add whatever other filters you need. Don't attempt to connect any pins, don't attempt to set any mediatypes. Once everything is in the FilterGraph - try calling FilterGraph.RenderFile(<source filename>).
Here's some sample code of me adding a Filter to the FilterGraph before calling RenderFile... And in this case, just happens to be a MPEG2 filter...
Function TFrameDirectShowVideo.Play: Boolean;
Const
CLSID_MOONLIGHT_ELECARD_DECODER_2: TGUID = '{F50B3F13-19C4-11CF-AA9A-02608C9BABA2}';
CLSID_MOONLIGHT_ELECARD_DECODER_4: TGUID = '{BC4EB321-771F-4E9F-AF67-37C631ECA106}';
Var
oFilter: IBaseFilter;
sExt: String;
Begin
Result := False;
If Assigned(FDSFilterGraph) And FileExists(FFilename) Then
If FDSFilterGraph.State = gsPaused Then
Result := FDSFilterGraph.Play
Else
Begin
FDuration := -1;
If FDSFilterGraph.Active Then
FDSFilterGraph.Active := False;
oFilter := nil;
FDSFilterGraph.Active := True;
sExt := Lowercase(ExtractFileExt(FFilename));
// Having to do this in case the Microsoft DVD Decoder is in town...
If (sExt = '.mpg') Or (sExt = '.pkt') Then
If SUCCEEDED(CoCreateInstance(CLSID_MOONLIGHT_ELECARD_DECODER_2,
nil, CLSCTX_INPROC_SERVER, IID_IBaseFilter, oFilter)) Then
FDSFilterGraph.AddFilter(oFilter, 'Elecard MPEG2 Video Decoder')
Else If SUCCEEDED(CoCreateInstance(CLSID_MOONLIGHT_ELECARD_DECODER_4, nil,
CLSCTX_INPROC_SERVER, IID_IBaseFilter, oFilter)) Then
FDSFilterGraph.AddFilter(oFilter, 'Elecard MPEG2 Video Decoder');
FDSFilterGraph.RenderFile(WideString(FFilename));
Result := FDSFilterGraph.Play;
End;
End;
RenderFile will always attempt to use the Filters already existing in the graph *before* adding any new ones. On Windows 7 and above - when playing video, Microsoft have started breaking the DirectShow Filter Priorities, and instead just inserts a Microsoft filter for handling MPEG-2. I don't know why they do that - I've never seen it work. So the above code is me forcing a filter I know works into the Graph so that DirectShow won't add the Microsoft one...
(Don't worry about the .pkt extension. It is probably very specific to just the industry I work in...)
Who knows - This approach might work for you... Sorry if it doesn't - I'm not in a position to research further...
Depends on where you got your DSPack from, you may need to move
Procedure AddFilter(AFilter: IBaseFilter; sName : UnicodeString); in DSPack.pas to Public. (Change already made in my copy, not done in PilotLogic's version)
The above code should play ANY video for which there is a valid DirectShow codec installed on the system... I've only had a quick look, but I'm having some problems sourcing a decent DirectShow mp4 filter... In all honesty, for playback I'm in the process to switching to mplayer/ffmpeg routines as I'm tired of endlessly ensuring the correct codecs are installed on client PCs...