Refresh Rate Control Plugin (1 Viewer)

poffe

Portal Member
January 20, 2007
9
0
51
OK, content of RefreshRateControl.txt:

2007-08-16 10:34:32: RefreshRateControl start. Def RR: 0
2007-08-16 10:34:45: Playback started. Playing file G:\movie\dvd\300\VIDEO_TS\VIDEO_TS.IFO
2007-08-16 10:34:45: Trying to connect to current MediaPortal's DirectShow graph
2007-08-16 10:34:45: Player is type DVDPlayer9
2007-08-16 10:34:45: Got IGraphBuilder field: _graphBuilder
2007-08-16 10:34:45: Got valid graph!
2007-08-16 10:34:45: Got frame time 0, frame rate is 0
2007-08-16 10:34:45: Finding best refresh rate for 0 fps
2007-08-16 10:34:45: Couldn't find good refresh rate, returning default 0 Hz)
2007-08-16 10:34:49: Playback stopped
2007-08-16 10:34:53: RefreshRateControl stop.

When I in plugin setup test the same file it correctly finds 25 fps and choose 75 Hz refreshrate. But for some reason it fails to do this during playback.

I am using MPV and MPA as codec

Since I never get a trace like: "Video has VideoInfoHeader...." in RefreshRateControl.txt it seems that somthing goes wrong somwhere in this code snippet (sorry for bad ident of code...):

foreach (IBaseFilter filter in new FilterEnumrerator((IFilterGraph)graphBuilder))
{
foreach (IPin pin in new PinEnumerator(filter))
{
/*
* try to find video
*/

mediaType = new AMMediaType();
hr = pin.ConnectionMediaType(mediaType);
if (hr == 0)
{

if (mediaType.formatType == DirectShowLib.FormatType.VideoInfo &&
mediaType.formatSize == Marshal.SizeOf(typeof(DirectShowLib.VideoInfoHeader)))
{
WriteToLog("Video has VideoInfoHeader info, getting frame time");

VideoInfoHeader videoHeader = new VideoInfoHeader();
Marshal.PtrToStructure(mediaType.formatPtr, videoHeader);

if (videoHeader.AvgTimePerFrame != 0)
{
frameTime = videoHeader.AvgTimePerFrame;
}

WriteToLog("Frame time is {0}", videoHeader.AvgTimePerFrame);
}

if (mediaType.formatType == DirectShowLib.FormatType.VideoInfo2 &&
mediaType.formatSize == Marshal.SizeOf(typeof(DirectShowLib.VideoInfoHeader2)))
{
WriteToLog("Video has VideoInfoHeader2 info, getting frame time");

VideoInfoHeader2 videoHeader2 = new VideoInfoHeader2();
Marshal.PtrToStructure(mediaType.formatPtr, videoHeader2);

if (videoHeader2.AvgTimePerFrame != 0)
{
frameTime = videoHeader2.AvgTimePerFrame;
}

WriteToLog("Frame time is {0}", videoHeader2.AvgTimePerFrame);
}
}
hr = 0;
// /
}
}

if (frameTime != 0)
frameRate = (float)(10000000.0f / frameTime);

WriteToLog("Got frame time {0}, frame rate is {1}", frameTime, frameRate);
 

kenwonders

MP Donator
  • Premium Supporter
  • January 19, 2007
    791
    741
    Home Country
    England England
    Hi, I just tested this plugin tonight and I'm really impressed, it worked better than I expected in terms of user experience. The difference in video quality when the refresh rate is correct is something I had seriously underated as a performance gain.

    Sadly I found some issues:

    - A few videos that opened as 29.97 in the configuration tool (correctly) showed as 25 fps in the logfile when played in Mediaportal (incorrectly). Using the 'VMR9' option alone fixed this. Examples are a 1080p mpeg2 TS file.

    - The PAL TV (coming from TV server on another machine) reported as 29.97 in the logfile when opened in Mediaportal.

    - If I set the VMR9 detection on, the TV correctly detects as 50fps, but my settings are only 24, 25 and 30. It chooses 30, but I'd rather it chose 25. Some 23.97 sources are detected as 25fps in this mode, possibly due to instability in VMR9 rate.

    Thanks for your work on this.
     

    kenwonders

    MP Donator
  • Premium Supporter
  • January 19, 2007
    791
    741
    Home Country
    England England
    I spent some time with the source code yesterday, and I can't find anything wrong with your DirectShow graph implementation at all. I mean, what's to go wrong!

    If only we could work out why the graph is reporting incorrect frame rates. Potential sources:

    - Codec? (I've tried with a difference codec on affected media with no success so probably not)
    - Haali?

    As for my problem with 50hz sources selecting 30 instead of 25, that's something I've patched locally, I am just /2 and checking against rate list.
     

    EViS

    Portal Pro
    September 30, 2006
    364
    2
    Home Country
    United Kingdom United Kingdom
    This is something that no software I have used is able to do. Please keep up the good work!! Would be fantastic if this was implemented into MediaPortal itself without the need for PowerStrip :eek:!
     

    seco

    Retired Team Member
  • Premium Supporter
  • August 7, 2007
    1,575
    1,239
    Home Country
    Finland Finland
    I cannot get this work with .mkv files.

    1) Log file only says that "19.9.2007 17:32:29: Playback started. Playing file I:\file.mkv" and nothing else.

    2) File starts to play but not in fullscreen mode, somehow like "top" of the Mediaportal (all MP controls, icons, graphics in the background) in a small window??

    If I play normal xvid .avi file, refresh rate is changed correctly.

    If I disable the plugin, everything works fine (but no refresh rate correction :().

    Am I missing something?
     

    kenwonders

    MP Donator
  • Premium Supporter
  • January 19, 2007
    791
    741
    Home Country
    England England
    I thought I'd get back to the thread with the patches I've made locally. I think I've got it nailed now, I had to make 3 changes to the source code:

    1. DirectShow occasionally got the wrong frametime. Fix:
    Add a delay of 2 seconds, once the graph is found. This seems to be enough time for videoHeader2.AvgTimePerFrame to start reporting the correct fps.

    Edit lines in RefreshRateControl.DirectShow.cs:

    if (graphBuilder != null)
    {
    WriteToLog("Got valid graph!");

    //PATCH
    Thread.Sleep(2000);
    WriteToLog("Delayed 2 seconds");
    //PATCH
    break;
    }
    else
    {
    WriteToLog("Couldn't cast it as IGraphBuilder");
    }

    2. Some videos don't work, namely MKV. They find a graph but 0 fps. Fix:
    Set option in configuration to perform VMR9 check. Change main code to continue picking a method if DirectShow returns 0 fps. Edit code in RefreshRateControl.cs (SetRefreshRate):

    if (settings.DirectShowSupport &&
    DirectShowGetFrameRate(fileName, out frameRate, settings.DirectShowBuilding))
    {

    //PATCH
    if (frameRate != 0)
    {

    //PATCH
    SetRefreshRate(GetBestRefreshRate(frameRate));
    return;

    //PATCH
    }

    //PATCH
    }

    //none found last chance
    if (settings.Vmr9Guessing)
    {

    //PATCH
    lastFPS = 0;
    //PATCH
    ProcessFrameRate();
    }

    3. VMR9 detection isn't a great FPS identifier. Fix:
    While testing using the ! key, I noticed a better indicater. Use MediaPortal.GUI.Library.VideoRendererStatistics.AverageFrameRate for a more accurate reporting of the source file FPS. Edit in RefreshRateControl.cs (ProcessFrameRate):

    float rate = MediaPortal.GUI.Library.VideoRendererStatistics.AverageFrameRate;//MediaPortal.GUI.Library.GUIGraphicsContext.DesiredFrameTime;



    With these edits, I am hitting 100% accuracy, albeit with a little stutter on startup. Hope they're useful to someone. I will probably clean things up a bit better. I am tempted to make a version that just uses the new AverageFrameRate I found, it usually gets the correct rate within two seconds, any other changes the RefreshRateControl makes later are mistakes based on the fact that I've skipped inside the video file.

    EDIT: secco do you have Haali Media Splitter installed?
     

    Taipan

    Retired Team Member
  • Premium Supporter
  • February 23, 2005
    2,075
    44
    Melbourne
    Home Country
    Australia Australia
    With these edits, I am hitting 100% accuracy, albeit with a little stutter on startup. Hope they're useful to someone.

    Yes, these changes are very useful - thankyou very much .... :)

    Do you know if these changes also fixes the problem with playing a physical DVD, where RefreshRateControl was trying to get the frame rate from the .IFO file instead of the .VOB file and thus returning 0fps?



    I will probably clean things up a bit better. I am tempted to make a version that just uses the new AverageFrameRate I found, it usually gets the correct rate within two seconds, ?

    That would be excellent - could you make it available here for me to try out, too?

    :D
     

    seco

    Retired Team Member
  • Premium Supporter
  • August 7, 2007
    1,575
    1,239
    Home Country
    Finland Finland
    I thought I'd get back to the thread with the patches I've made locally. I think I've got it nailed now, I had to make 3 changes to the source code:

    1. DirectShow occasionally got the wrong frametime. Fix:
    Add a delay of 2 seconds, once the graph is found. This seems to be enough time for videoHeader2.AvgTimePerFrame to start reporting the correct fps.

    Edit lines in RefreshRateControl.DirectShow.cs:

    if (graphBuilder != null)
    {
    WriteToLog("Got valid graph!");

    //PATCH
    Thread.Sleep(2000);
    WriteToLog("Delayed 2 seconds");
    //PATCH
    break;
    }
    else
    {
    WriteToLog("Couldn't cast it as IGraphBuilder");
    }

    2. Some videos don't work, namely MKV. They find a graph but 0 fps. Fix:
    Set option in configuration to perform VMR9 check. Change main code to continue picking a method if DirectShow returns 0 fps. Edit code in RefreshRateControl.cs (SetRefreshRate):

    if (settings.DirectShowSupport &&
    DirectShowGetFrameRate(fileName, out frameRate, settings.DirectShowBuilding))
    {

    //PATCH
    if (frameRate != 0)
    {

    //PATCH
    SetRefreshRate(GetBestRefreshRate(frameRate));
    return;

    //PATCH
    }

    //PATCH
    }

    //none found last chance
    if (settings.Vmr9Guessing)
    {

    //PATCH
    lastFPS = 0;
    //PATCH
    ProcessFrameRate();
    }

    3. VMR9 detection isn't a great FPS identifier. Fix:
    While testing using the ! key, I noticed a better indicater. Use MediaPortal.GUI.Library.VideoRendererStatistics.AverageFrameRate for a more accurate reporting of the source file FPS. Edit in RefreshRateControl.cs (ProcessFrameRate):

    float rate = MediaPortal.GUI.Library.VideoRendererStatistics.AverageFrameRate;//MediaPortal.GUI.Library.GUIGraphicsContext.DesiredFrameTime;



    With these edits, I am hitting 100% accuracy, albeit with a little stutter on startup. Hope they're useful to someone. I will probably clean things up a bit better. I am tempted to make a version that just uses the new AverageFrameRate I found, it usually gets the correct rate within two seconds, any other changes the RefreshRateControl makes later are mistakes based on the fact that I've skipped inside the video file.

    EDIT: secco do you have Haali Media Splitter installed?

    Yes, I am using Haali Media Splitter version 1.7.189.11
     

    AberDino

    MP Donator
  • Premium Supporter
  • February 17, 2005
    240
    28
    Kincardineshire
    Home Country
    Scotland Scotland
    It sounds like progress is being made with this plugin, and I would like to test it with the changes, but I'm not familiar at all with compiling code etc. Could somebody post or send a copy of the compiled DLL for me to try please? Thanks in advance.
     

    renzz

    Portal Member
    September 12, 2007
    18
    0
    Could I make a feature request on this please - make the refresh rate configurable for each framerate. My PC connects to my plasma TV via HDMI, and it will only accept HDTV resolutions and refresh rates (ie 50 or 60Hz). I'd like to be able to set this plugin so that all 25fps set to 50hz, but other rates (30, 24) set it to 60Hz.

    Keep up the good work - as others have said, this is something that should be built into MP.
     

    Users who are viewing this thread

    Top Bottom