- September 1, 2008
- 21,578
- 8,228
- Home Country
-
New Zealand
Hi all
-----------------------------------------------------------------------------------------
Background:
I have four hybrid cards in my system. With recent versions of MediaPortal I have trouble listening to FM radio or watching/recording more than one analog channel at a time.
-----------------------------------------------------------------------------------------
Testing/diagnosis:
I tested each tuner individually by disabling all the other cards and they all work fine by themselves. This led me to suspect that my issues were caused by attempts to share resources that should not be shared or to use resources [that can only be used once] more than once. In particular I suspected issues around the use of audio and video encoders (all four of my cards use software encoders rather than hardware encoders to support analog TV and FM).
I have 3 pairs of software encoders installed on my system:
1. Intervideo
2. Cyberlink(Twinhan)
3. PCTV Systems [formerly Pinnacle]
As I suspected I found that one pair of encoders was being used for all four tuners. I believe some encoders may support encoding for multiple tuners simultaneously, but I suspect that some or all of mine do not for the following reasons:
1. When tuning an FM station, all analog tuners must be tested to see if they support FM radio. This can only be determined once the tuner graph has been built. On my system this means that four graphs have to be built. All four graphs use the same audio and video encoders. Once it is determined that all four tuners support FM radio (because they do), TV Server attempts to tune and start timeshifting on the first analog tuner. Tuning is successful, however timeshifting fails. The server waits 15 seconds for audio and video to be seen but they never arrive. This pattern continues for the next two tuners; tuning succeeds but timeshifting fails to start. On the last tuner tuning succeeds as well... and timeshifting also succeeds. Note that the last tuner is also the last tuner to have had its graph built. I don't think this is a coincidence.
2. When tuning a TV station on a second tuner a second analog graph will have to be built (assuming an FM radio station hasn't yet been tuned). The second graph is built using the same software encoder pair as the first graph. Tuning is successful, however timeshifting fails after waiting 15 seconds for audio to arrive.
-----------------------------------------------------------------------------------------
A solution:
1. I have created a patch that prevents audio and video encoders from being used more than once [by MediaPortal]. Unfortunately it doesn't seem to be possible to query the filter itself to determine whether it has already been used. This means that usage outside MediaPortal cannot be taken into account. This assumption might well be wrong because I don't have a whole lot of experience with DirectShow. Anyhow the solution I have implemented adds two (one for audio compressors, one for video compressors) private static lists to the TVLibrary.Implementations.Analog.Components.Encoder class. The lists are checked and updated each time an analog graph is built, and updated each time an analog graph is disposed. I use locking to ensure that the lists are only accessed by one thread at a time.
This change allows me to watch/record up to three analog TV/FM streams on my system successfully.
2. In addition: I mentioned earlier that when I tune to an FM station for the first time the TVServer has to build four graphs (one for each tuner). This takes quite a long time!
"AdvancedCardAllocation.GetAvailableCardsForChannel took 6673 msec"
I thought it would be a good idea to swap the order of the CanTune and IsChannelMappedToCard checks in the TvService.CardManagement.CardAllocation.AdvancedCardAllocation.GetAvailableCardsForChannel() function. Checking CanTune() for an FM channel requires the full tuner graph to be built. If you can reduce the number of graphs that have to be built then you can speed up this process quite significantly. If you check IsChannelMappedToCard first and FM channels are only mapped to 1 tuner (instead of four) then you save the time that it takes to build 3 graphs. Of course this time can only be saved on the first attempt to tune an FM channel because after that the graphs would already be built, but still... Hopefully all of that makes sense.
Better fix already in SVN...
3. Finally, I have found that some of my tuners will not tune to FM after watching analog TV. The issue is *1 line* in the TVLibrary.Implementations.Analog.Graphs.Analog.TvCardAnalog.Tune() function:
_encoder.UpdatePinVideo(channel.IsTv, _graphBuilder);
The effect is to connect the video pin if changing from FM to TV and disconnect it if changing from TV to FM. Perhaps some encoders require this, however at least one of the encoders on my machine does not. In fact, it prevents the channel from successfully changing and the TV Server is forced to use a different tuner.
Assumed hardware-specific ==> will be kept as a private fix for me...
-----------------------------------------------------------------------------------------
Feedback:
I welcome any comments and feedback, particularly about detecting whether a filter is already being used.
- I am running SVN head on my machine. The changes related to software encoder prioritisation that misterd has added (see here) work well for me. Perhaps if some encoders support simultaneous use with multiple tuners, a simultaneousUseSupported column could be added to the new softwareencoder table. Likewise, a disconnectVideoPinForRadio column could be added to indicate whether the video pin should be disconnected when changing to radio.
Thanks for reading...
-----------------------------------------------------------------------------------------
Update 25 October 2010
I discovered that the lists of encoders were not being updated properly when analog graphs were destroyed because for some reason it was not possible to get the compressor/encoder filter names in the encoder dispose function. The workaround is to store the names of the encoders as private instance variables. These variables are set when the encoders are selected and unset when the encoder instance is disposed. Sorry for any inconvenience.
-----------------------------------------------------------------------------------------
Update 11 January 2011
Team member MisterD informed me that some encoders do support encoding multiple channels at once. I will be adding a setting in the encoder priority tab to support this. In the meantime, back to WIP...
-----------------------------------------------------------------------------------------
Update 26 January 2011
New (and hopefully, final) patch available. I confirmed MisterD's observation that some encoders support simultaneous use with multiple tuners. On my system the ATI AVIVO encoders can be simultaneously used with all four of my analog (hybrid) tuners - it takes 80-90% of my Core2 e6600 2.4GHz CPU, but it can be done.
Changes:
- issue 2 already committed to SVN in a separate patch
- issue 3 *not* included (at this point I consider the fix to be hardware-specific)
- additional "reuse" column on each of the grids on the software encoders configuration tab to indicate/control whether an encoder can be used with multiple tuners at once
- additional "reuse cap" setting at the bottom of the software encoders configuration tab to specify the maximum number of times that each encoder can be reused
(- extra debug included only while testing)
-----------------------------------------------------------------------------------------
Update 26 January 2011
Minor changes in response to feedback from MisterD (thank you
).
- rows no longer resizeable and squashed a little
- columns use total width of lists
- a little refactoring to improve code efficiency
- remove extra debug
Note that versions 2 and 3 require DB structure changes.
-----------------------------------------------------------------------------------------
Background:
I have four hybrid cards in my system. With recent versions of MediaPortal I have trouble listening to FM radio or watching/recording more than one analog channel at a time.
-----------------------------------------------------------------------------------------
Testing/diagnosis:
I tested each tuner individually by disabling all the other cards and they all work fine by themselves. This led me to suspect that my issues were caused by attempts to share resources that should not be shared or to use resources [that can only be used once] more than once. In particular I suspected issues around the use of audio and video encoders (all four of my cards use software encoders rather than hardware encoders to support analog TV and FM).
I have 3 pairs of software encoders installed on my system:
1. Intervideo
2. Cyberlink(Twinhan)
3. PCTV Systems [formerly Pinnacle]
As I suspected I found that one pair of encoders was being used for all four tuners. I believe some encoders may support encoding for multiple tuners simultaneously, but I suspect that some or all of mine do not for the following reasons:
1. When tuning an FM station, all analog tuners must be tested to see if they support FM radio. This can only be determined once the tuner graph has been built. On my system this means that four graphs have to be built. All four graphs use the same audio and video encoders. Once it is determined that all four tuners support FM radio (because they do), TV Server attempts to tune and start timeshifting on the first analog tuner. Tuning is successful, however timeshifting fails. The server waits 15 seconds for audio and video to be seen but they never arrive. This pattern continues for the next two tuners; tuning succeeds but timeshifting fails to start. On the last tuner tuning succeeds as well... and timeshifting also succeeds. Note that the last tuner is also the last tuner to have had its graph built. I don't think this is a coincidence.
-----------------------------------------------------------------------------------------
A solution:
1. I have created a patch that prevents audio and video encoders from being used more than once [by MediaPortal]. Unfortunately it doesn't seem to be possible to query the filter itself to determine whether it has already been used. This means that usage outside MediaPortal cannot be taken into account. This assumption might well be wrong because I don't have a whole lot of experience with DirectShow. Anyhow the solution I have implemented adds two (one for audio compressors, one for video compressors) private static lists to the TVLibrary.Implementations.Analog.Components.Encoder class. The lists are checked and updated each time an analog graph is built, and updated each time an analog graph is disposed. I use locking to ensure that the lists are only accessed by one thread at a time.
This change allows me to watch/record up to three analog TV/FM streams on my system successfully.
"AdvancedCardAllocation.GetAvailableCardsForChannel took 6673 msec"
I thought it would be a good idea to swap the order of the CanTune and IsChannelMappedToCard checks in the TvService.CardManagement.CardAllocation.AdvancedCardAllocation.GetAvailableCardsForChannel() function. Checking CanTune() for an FM channel requires the full tuner graph to be built. If you can reduce the number of graphs that have to be built then you can speed up this process quite significantly. If you check IsChannelMappedToCard first and FM channels are only mapped to 1 tuner (instead of four) then you save the time that it takes to build 3 graphs. Of course this time can only be saved on the first attempt to tune an FM channel because after that the graphs would already be built, but still... Hopefully all of that makes sense.
Better fix already in SVN...
_encoder.UpdatePinVideo(channel.IsTv, _graphBuilder);
The effect is to connect the video pin if changing from FM to TV and disconnect it if changing from TV to FM. Perhaps some encoders require this, however at least one of the encoders on my machine does not. In fact, it prevents the channel from successfully changing and the TV Server is forced to use a different tuner.
Assumed hardware-specific ==> will be kept as a private fix for me...
-----------------------------------------------------------------------------------------
Feedback:
I welcome any comments and feedback, particularly about detecting whether a filter is already being used.
- I am running SVN head on my machine. The changes related to software encoder prioritisation that misterd has added (see here) work well for me. Perhaps if some encoders support simultaneous use with multiple tuners, a simultaneousUseSupported column could be added to the new softwareencoder table. Likewise, a disconnectVideoPinForRadio column could be added to indicate whether the video pin should be disconnected when changing to radio.
Thanks for reading...
-----------------------------------------------------------------------------------------
Update 25 October 2010
I discovered that the lists of encoders were not being updated properly when analog graphs were destroyed because for some reason it was not possible to get the compressor/encoder filter names in the encoder dispose function. The workaround is to store the names of the encoders as private instance variables. These variables are set when the encoders are selected and unset when the encoder instance is disposed. Sorry for any inconvenience.
-----------------------------------------------------------------------------------------
Update 11 January 2011
Team member MisterD informed me that some encoders do support encoding multiple channels at once. I will be adding a setting in the encoder priority tab to support this. In the meantime, back to WIP...
-----------------------------------------------------------------------------------------
Update 26 January 2011
New (and hopefully, final) patch available. I confirmed MisterD's observation that some encoders support simultaneous use with multiple tuners. On my system the ATI AVIVO encoders can be simultaneously used with all four of my analog (hybrid) tuners - it takes 80-90% of my Core2 e6600 2.4GHz CPU, but it can be done.
Changes:
- issue 2 already committed to SVN in a separate patch
- issue 3 *not* included (at this point I consider the fix to be hardware-specific)
- additional "reuse" column on each of the grids on the software encoders configuration tab to indicate/control whether an encoder can be used with multiple tuners at once
- additional "reuse cap" setting at the bottom of the software encoders configuration tab to specify the maximum number of times that each encoder can be reused
(- extra debug included only while testing)
-----------------------------------------------------------------------------------------
Update 26 January 2011
Minor changes in response to feedback from MisterD (thank you
- rows no longer resizeable and squashed a little
- columns use total width of lists
- a little refactoring to improve code efficiency
- remove extra debug
Note that versions 2 and 3 require DB structure changes.