The Media Center Sandbox

Resources and discussion for developing experiences in the Windows Media Center platform.
Welcome to The Media Center Sandbox Sign in | Join | Help
in Search

Why do I need to jump through hoops to use the MediaTransport object.

Last post 09-09-2009, 5:39 PM by eddyc. 13 replies.
Sort Posts: Previous Next
  •  03-15-2009, 5:20 PM 9123

    Why do I need to jump through hoops to use the MediaTransport object.

    Turns out that every single call to

    AddInHost.Current.MediaCenterEnvironment.MediaExperience.MediaTransport will create a new remoted object into ehshell.

    This object only gets released when you switch media experiences.

    The side effect of not releasing this proxy object is that gotofullscreen will gradually take longer and longer as you accumulate more of these proxies.

    Why oh why does this happen? And why do I have to jump through hoops just to figure out the position and playback state of a video?
    - Sam
    samsaffron.com
  •  03-16-2009, 1:05 AM 9127 in reply to 9123

    Re: Why do I need to jump through hoops to use the MediaTransport object.

    Not what you want to hear, but why not try writing a wrapper for MediaTransport that uses the existing object through a static class property surrounded by a try...catch to refresh the object if required?

    Cheers,
    Andrew

  •  03-16-2009, 2:03 AM 9129 in reply to 9127

    Re: Why do I need to jump through hoops to use the MediaTransport object.

    Thats what I did. Wrote a wrapper around playback and playback tracking, this will help us implement VLC playback later down the line.

    http://code.google.com/p/videobrowser/source/browse/trunk/MediaBrowser/Code/ModelItems/PlaybackController.cs

    - Sam
    samsaffron.com
  •  04-09-2009, 11:36 AM 9188 in reply to 9129

    Re: Why do I need to jump through hoops to use the MediaTransport object.

    I think that is easily solved so we dont need to change our design.  But let me know if this solution is not satisfactory.

     


    This posting is provided "AS IS" with no warranties, and confers no rights.

    David Teo
    SDET
    Microsoft Corporation
  •  04-09-2009, 6:03 PM 9190 in reply to 9188

    Re: Why do I need to jump through hoops to use the MediaTransport object.

    David,

    My solution is a MEGA hack, that sort of works, yet still has its own quirks. Some users are reporting issues with this area.

    At the bare minimum, ths SDK should include some sample code that shows how a 3rd party can track the current position and state for any file that is playing.

    The trivial intuitive implementation will TAKE OUT ALL PLAYBACK after a fairly short amount of time.

    Jumping through hoops has its own quirks and depends on the current buggy implementation.

    This really needs to be fixed.



    - Sam
    samsaffron.com
  •  04-14-2009, 5:09 PM 9197 in reply to 9190

    Re: Why do I need to jump through hoops to use the MediaTransport object.

    When I look at the code, I have not got a confirmation back yet, but it looks like this is already fixed in Windows 7.  :-)

    Edit:

    Confirmed, this bug is fixed in Windows 7.


    This posting is provided "AS IS" with no warranties, and confers no rights.

    David Teo
    SDET
    Microsoft Corporation
  •  04-14-2009, 11:57 PM 9198 in reply to 9197

    Re: Why do I need to jump through hoops to use the MediaTransport object.

    David - can we get this fix rolled in to Vista as well?  None of the workarounds really fix the problem and it limits the usability of the API as a result.

    Cheers,
    Andrew

  •  04-15-2009, 3:17 PM 9201 in reply to 9198

    Re: Why do I need to jump through hoops to use the MediaTransport object.

    AndyC:

    David - can we get this fix rolled in to Vista as well?  None of the workarounds really fix the problem and it limits the usability of the API as a result.

    Cheers,
    Andrew

    We are checking what the procedure is to escalate this issue right now and we will get back to you soon.

    Let us if know there are any other API that has similar issues.  Thanks.

     


    This posting is provided "AS IS" with no warranties, and confers no rights.

    David Teo
    SDET
    Microsoft Corporation
  •  04-16-2009, 2:46 PM 9202 in reply to 9198

    Re: Why do I need to jump through hoops to use the MediaTransport object.

    Andy,

    The bar is very high to get that fix into Vista.  Typically, the customer can call PSS and work with them.

    If this is blocking you and you really want to push for this, you should send email to Charlie. :-)


    This posting is provided "AS IS" with no warranties, and confers no rights.

    David Teo
    SDET
    Microsoft Corporation
  •  06-17-2009, 3:53 PM 9277 in reply to 9202

    Re: Why do I need to jump through hoops to use the MediaTransport object.

    Sam,

    I think I may be seeing a related problem. I'm curious as to how you identified that a large number of objects were being created through referencing MediaTransport? Is there an external resource monitoring tool that displays this sort of info?

    Cheers,

    Eddy

  •  06-22-2009, 4:50 PM 9287 in reply to 9277

    Re: Why do I need to jump through hoops to use the MediaTransport object.

    @Eddy,

    I deduced the implementation from the behaviour I observed, which means that I am likely to be wrong. If you really wanted to dig in to this I would recommend giving .net memory profiler a shot

    Cheers
    Sam
    - Sam
    samsaffron.com
  •  08-25-2009, 6:25 PM 9324 in reply to 9287

    Re: Why do I need to jump through hoops to use the MediaTransport object.

    Sam,

    I finally got around to playing with .net memory profiler recently -- great tool, by the way, so thanks for the recommendation.

    It seems to confirm your deduction, i.e. I see a substantial increase in the number of .net Remoted objects on the heap of my plug-in when I have a background loop running that polls MediaExperience.MediaTransport (under Vista).

    What may be of interest is that when I looked at the lease time on some of the remoted objects, the lease RenewOnCall time is set to the default of two minutes, rather than five minutes. The initial timeout is five minutes, but subsequently, it looks as if it will timeout after no more than two minutes of inactivity.

    I haven't confirmed that this is happening specifically with MediaTransport (it was a bit harder to track down the matching objects in ehshell.exe, since there's a lot more going on) but it seems a distinct possibility.

    Eddy


     

  •  09-01-2009, 2:15 AM 9325 in reply to 9324

    Re: Why do I need to jump through hoops to use the MediaTransport object.

    I just realised that the current version of SysInternal's Process Explorer (v11.33) will show the number of marshalled objects for a process, which is very useful:

    Find the exthost.exe process of the plug-in in Process Explorer, call up its properties, go to the .NET property sheet, then select .NET CLR Interop performance objects.

    The third item is the number of marshalled objects, which can be seen growing over time at about the same rate of new references to MediaTransport.

    (Edit: never mind -- reading up about the CLR performance counters, this is just counting the number of times marshalling has occurred, not the number of discrete marshalled objects.)

    Eddy
  •  09-09-2009, 5:39 PM 9340 in reply to 9325

    Re: Why do I need to jump through hoops to use the MediaTransport object.

    I've been investigating a bug that goes like this:

    - Launch a background add-in under Windows 7
    - Idle for a while (10-20 minutes); specifically, don't launch any media so that MediaExperience and MediaTransport remain NULL. Feel free to poll MediaCenterEnvironment.MediaExperience as much as you like.
    - Start a video file playing
    - Try and make it full-screen; it fails, because MediaExperience is still null, even though the media just started. From this point on, you can't access any MediaExperience/transport data until you restart Media Center. 100% repeatable.

    The normal trick of polling MediaTransport doesn't help here, because there is nothing to poll -- it's NULL.

    After doing some poking around the eHome assemblies, I found that the get_ property for MediaCenterEnvironment.MediaExperience uses a mini cache to avoid serving up a fresh MBRO-based object every time. I would guess it expects to get a PropertyChanged event from the remote MediaCenterEnvironment MBRO to let it know when MediaExperience changes -- but when this times out, the notification never arrives so the cache never gets flushed.

    I did a little bit of cheating with reflection to force the cache to empty. For the benefit of anyone else who has been beating their head against this same problem, here's the code I used.

    At the risk of stating the obvious: DO NOT USE THIS CODE UNLESS (a) YOU HAVE THIS SAME PROBLEM, and (b) YOU FULLY UNDERSTAND THE IMPLICATIONS. It is version-specific, likely to break on a future version of MCE (or maybe even a Windows Update) and is definitely not going to be supported in any way by Microsoft.

    On the other hand, my persistent crash is now gone, and things are working very nicely. If anyone can provide a better workaround, I'm all ears!


    public static void ResetMediaExperienceCache()
    {
    if (IsWindows7)
    {
    try
    {
    FieldInfo fi_single = AddInHost.Current.MediaCenterEnvironment.GetType().GetField("_checkedMediaExperience", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);

    if (fi_single != null)
    fi_single.SetValue(AddInHost.Current.MediaCenterEnvironment, false);
    else
    Debug.WriteLine("Warning: cannot find MediaCenterEnvironment._checkedMediaExperience field on Windows 7");
    }
    catch (Exception e)
    {
    Debug.WriteLine("Error setting MediaCenterEnvironment._checkedMediaExperience flag on Windows 7: " + e.ToString());
    }
    }
    }

    static public MediaExperience CurrentMediaExperience
    {
    get
    {
    MediaCenterEnvironment env = AddInHost.Current.MediaCenterEnvironment;
    if (env != null)
    {
    MediaExperience exp = env.MediaExperience;

    if (exp == null)
    {
    // Reset experience cache under Windows 7 and try again
    ResetMediaExperienceCache();
    exp = env.MediaExperience;
    }
    return exp;
    }
    return (null);
    }
    }

    I then reference CurrentMediaExperience from my own code, rather than MediaCenterEnvironment.MediaExperience. In addition, just to be safe, I do an explicit call to ResetMediaExperienceCache() immediately after any PlayMedia() call, to ensure that I am always using the most up-to-date object.

    (The usual MediaTransport polling rules still apply.)
View as RSS news feed in XML
Powered by Community Server, by Telligent Systems