- March 1, 2011
- 7
- 10
- Home Country
- Germany
Hi,
as you may (or may not) know, i'm the developer of LAV Splitter.
I've recently been thinking about how to improve the whole mess that is stream switching and the possibility to let the player build a custom filter graph while doing so.
The situation right now:
- (On Audio only) LAV Splitter will try to replace the audio decoder with a new one, trying to honor the users preferences. This method does not work with custom graph building routines, as it relys on the default GraphBuilder interface to select the new decoder.
- Other splitters do not do this at all, the MPC-HC splitter will never replace the original decoder, Haali will only replace it if the old one does not support the new codec.
The idea that came to mind (actually, tourette (a MediaPortal developer) triggered it) is as follows:
Just let the player deal with it, if it wants to.
The general concept is simple. The player needs to provide a yet non-existant interface, dubbed "IGraphRebuilder". This interface would hold simply one function, possibly called "HRESULT RebuildPin(IFilterGraph *pGraph, IPin *pPin)", which the splitter would call on stream changes to tell the Player to re-render the pin with its own graph building logic.
From my point of view, this method of stream changes would be optimal, as only the player really knows how its filter graphs should be constructed. However, i need to rally the support of player developers for this to make sense.
I will myself implement this in MPC-HC, and i'm hoping for the developers of JRiver MC16, MediaPortal and ZoomPlayer to eventually join the boat (at least i approached them about it). Any other players are of course welcome to implement it as well.
On to the technical stuff:
I discussed the IGraphRebuilder interface above, and there really isn't much about it. On stream changes, the splitter would set the new media types on the output pin, and call that interface with a reference to that output pin. Its then 100% the players responsibility to deal with the change. How that looks is all your choice, it can be as simple as checking if the existing decoder supports the codec, and only if it does not change it, or you can implement a full blown codec priority system.
I'm not 100% decided if the splitter should do anything else after the call. I could simply send the new media type to the codec with the next data package, to ensure it really has the updated information. I think i would base that on the return value, S_OK means "do nothing, we took care of it", S_FALSE means "the existing graph is fine, send new media type".
The main question that bugged me for a while was how would the player get a reference to that interface to the splitter. I think i found a neat solution: IObjectWithSite. Through the IObjectWithSite interface, objects can be assigned a "site", which is basically their owning object. The player would simply query the IObjectWithSite interface from the splitter, and set its class that holds the IGraphRebuilder interface as the new site.
The Splitter would then query the IGraphRebuilder interface from the site reference, whenever its needed.
Anyhow, this is not a "finished" spec, its mostly a draft of how things would work, and i think it could work out quite nice, allowing the player to switch the decoder based on its preferences, and nothing else.
I would appreciate any support, feedback and comments from the different player developers!
Cross-posted to MediaPortal Forum, MC16 Beta Forum and ZoomPlayer forums.
as you may (or may not) know, i'm the developer of LAV Splitter.
I've recently been thinking about how to improve the whole mess that is stream switching and the possibility to let the player build a custom filter graph while doing so.
The situation right now:
- (On Audio only) LAV Splitter will try to replace the audio decoder with a new one, trying to honor the users preferences. This method does not work with custom graph building routines, as it relys on the default GraphBuilder interface to select the new decoder.
- Other splitters do not do this at all, the MPC-HC splitter will never replace the original decoder, Haali will only replace it if the old one does not support the new codec.
The idea that came to mind (actually, tourette (a MediaPortal developer) triggered it) is as follows:
Just let the player deal with it, if it wants to.
The general concept is simple. The player needs to provide a yet non-existant interface, dubbed "IGraphRebuilder". This interface would hold simply one function, possibly called "HRESULT RebuildPin(IFilterGraph *pGraph, IPin *pPin)", which the splitter would call on stream changes to tell the Player to re-render the pin with its own graph building logic.
From my point of view, this method of stream changes would be optimal, as only the player really knows how its filter graphs should be constructed. However, i need to rally the support of player developers for this to make sense.
I will myself implement this in MPC-HC, and i'm hoping for the developers of JRiver MC16, MediaPortal and ZoomPlayer to eventually join the boat (at least i approached them about it). Any other players are of course welcome to implement it as well.
On to the technical stuff:
I discussed the IGraphRebuilder interface above, and there really isn't much about it. On stream changes, the splitter would set the new media types on the output pin, and call that interface with a reference to that output pin. Its then 100% the players responsibility to deal with the change. How that looks is all your choice, it can be as simple as checking if the existing decoder supports the codec, and only if it does not change it, or you can implement a full blown codec priority system.
I'm not 100% decided if the splitter should do anything else after the call. I could simply send the new media type to the codec with the next data package, to ensure it really has the updated information. I think i would base that on the return value, S_OK means "do nothing, we took care of it", S_FALSE means "the existing graph is fine, send new media type".
The main question that bugged me for a while was how would the player get a reference to that interface to the splitter. I think i found a neat solution: IObjectWithSite. Through the IObjectWithSite interface, objects can be assigned a "site", which is basically their owning object. The player would simply query the IObjectWithSite interface from the splitter, and set its class that holds the IGraphRebuilder interface as the new site.
The Splitter would then query the IGraphRebuilder interface from the site reference, whenever its needed.
Anyhow, this is not a "finished" spec, its mostly a draft of how things would work, and i think it could work out quite nice, allowing the player to switch the decoder based on its preferences, and nothing else.
I would appreciate any support, feedback and comments from the different player developers!
Cross-posted to MediaPortal Forum, MC16 Beta Forum and ZoomPlayer forums.