locked
MediaElement stutters and goes black after a while

    Question

  • Hello,

    I'm developing a metro app that utilizes the MediaElement class in C++/XAML.

    My app has the video being swapped many times over the course of the execution, and it seems that after a while (15 minutes), in the middle of a video it will just stutter for a few frames and then go black with the audio still playing in the background.

    I'm using this line of code to swap the video:

    ME->Source = this->BaseUri->CombineUri( <filename> );

    "this" refers to my "MainPage" class that is created when a new project is made in Visual Studio 11. "ME" is the mediaElement.

    Does anyone know a cause of this? The memory on my computer when this happens is not any higher than when the application starts so I don't believe it's a memory leak. Could it be a video card problem? Doesn't always happen on the same video.

    I would appreciate any help you guys can give thanks! If you need any more information let me know.

    Thanks,

    Alex


    • Edited by DLAlex Friday, March 02, 2012 4:52 PM
    Friday, March 02, 2012 4:51 PM

All replies

  • Hello Alex,

    It does sound like a resource problem. Likely what is happening is that you are running out of video memory due to a memory leak. Are you shutting down the Media Element completely before changing the URL (i.e. stopping the Media Element and waiting for the "stopped" state)?. I don't know if you can run GPUView on windows 8 but you might want to give that a try and see if you can verify if you are leaking video memory. I'll talk with some folks on Monday and see if we can come up with other resources for you to get to the bottom of this issue.

    GPUView landing page:

    http://msdn.microsoft.com/en-us/library/windows/hardware/ff570133(v=vs.85).aspx

    -James


    Windows Media SDK Technologies - Microsoft Developer Services - http://blogs.msdn.com/mediasdkstuff/

    Saturday, March 03, 2012 1:09 AM
    Moderator
  • I have not been using the method you described, I thought that maybe the MediaElement would handle the background checking when a new source was set. I can change my method to stopping and waiting for a stop message. Then changing the media.

    Thanks for your input.

    EDIT:

    I've started to implement this fix for the video memory (I wasn't able to get GPUView to work, don't know if it's Windows 8 or not) but I'm having issues with the video leaving it's first frame on the screen when it's stopped. I need to have flawless transition between videos (which is why the previous method worked so well), is there a way to achieve the flawless transition between videos using the method described?

    • Edited by DLAlex Monday, March 05, 2012 7:42 PM Updated Information
    Monday, March 05, 2012 1:15 PM
  • Hey DLAlex,

    Let me look into this for you. Unfortunately with the CP release things are a bit crazy. If you don't hear from me in a couple of days give me a bump because I want to make sure to help you with this.

    Thanks,

    James


    Windows Media SDK Technologies - Microsoft Developer Services - http://blogs.msdn.com/mediasdkstuff/

    Tuesday, March 06, 2012 2:13 AM
    Moderator
  • Thanks James,

    I look forward to your help.

    Tuesday, March 06, 2012 2:02 PM
  • Hello DLAlex,

    I spent most of the day today trying to reproduce your issue. Unfortunately I am not able to reproduce the problem. Unfortunately I have not see the type of resource leak that you described in your original post. I will leave the app running overnight and let you know what I find. Hopefully I will be able to help you find a workaround to the first frame being displayed after stop since this is really the best way to go.

    -James


    Windows Media SDK Technologies - Microsoft Developer Services - http://blogs.msdn.com/mediasdkstuff/

    Thursday, March 08, 2012 1:30 AM
    Moderator
  • Hi James,

    Thanks for getting back to me.

    I've been working back and forth between this issue, and progressing the app further in other areas and I was thinking, that it could be a different issue. I also have images on the screen during the playing of this video. I need these images to swap, to different images occasionally and I'm thinking it might be those that are causing the overload of memory. From my understanding of the new WinRT C++, using 'ref new' allocated a variable safely on a special heap, and the background of Windows handled the management of resources (am I correct with this?), now with that I've been using this line to swap the images:

    <Already declared image^> = ref new BitmapImage( ref new Uri( this->BaseUri->AbsoluteUri, <FileName> ) );

    Looking at that, it seems wrong because I'm using 'ref new', and like I said before I'm not 100% confident I'm using it correctly. Could this cause the problem? Is there a better way to swap image sources that exist on screen?

    I'm sorry if I have caused any inconvenience with this thread. I appreciate all the help you've given. Let me know!

    Alex.

    Thursday, March 08, 2012 7:22 PM
  • Hey DLAlex,

    That should work. C++ Cx uses a reference count mechanism to keep track of outstanding references. As long as nothing else in your application has an outstanding reference to your image, calling "ref new" *should* automatically clean up the previous reference and allocate a new one. Is it possible that you still have an outstanding reference when you are calling "ref new"?

    I hope this helps,

    James


    Windows Media SDK Technologies - Microsoft Developer Services - http://blogs.msdn.com/mediasdkstuff/

    Saturday, March 10, 2012 2:26 AM
    Moderator
  • Hey James,

    The variable holding the new image described above isn't a local variable, it's a class variable that I'm using elsewhere. I change the source in a function called by markers in the video that I've placed. Then I leave the function with that new image, and I don't do anything but display the image until it is time to change it again, then call the previously mentioned line. I'm thinking a list of references could be piling up because I'm constantly calling ref new and putting them into a class variable which wouldn't be getting removed until application completion. Is this correct?

    Also, is it possible that markers could be causing this? I'm thinking not, because I'm constantly clearing the list of markers whenever I go to add new ones, so they should be freeing up memory when I use the clear method, correct?

    Thanks again,

    Alex

    Monday, March 12, 2012 1:31 PM
  • Alex,

    Unfortunately without actually seeing your code I just can't be sure what is going on. It is very possible that you are leaking due to outstanding references due to the way you are just calling ref new on your class variable. Unfortunately without more information I just can't be sure. I wrote some code that I thought was creating the objects as you do in your code but I did not see a leak. So unfortunately I just don't have enough information to help you make a reasonable diagnosis.

    As far as the markers go... If you use the "clear" method this should release all of the references. Just check your code and make sure you haven't added them to another data structure such as an array or collection of some type.

    I hope this helps,

    James


    Windows Media SDK Technologies - Microsoft Developer Services - http://blogs.msdn.com/mediasdkstuff/

    Monday, March 12, 2012 10:29 PM
    Moderator
  • Hi James,

    I'll try and give you a sample of what I'm doing with my code to try and help show you what's going on.

    To explain the Media Element Source changing:

    <Grid x:Name="LayoutRoot" Background="#FF0C0C0C">

    <MediaElement x:Name="ME" Source="Media/Videos/test.wmv" IsLooping="True" MarkerReached="ME_MarkerReached" MediaEnded="ME_MediaEnded" MediaOpened="ME_MediaOpened" CurrentStateChanged="ME_StateChanged"></MediaElement>

    </Grid>

    *NOTE: The media element doesn't always stay looping, it just is at application start.*

    Above is the definition of the Media Element. Now to change the source of the media element I use the following piece of code:

    ME->Source = this->BaseUri->CombineUri( "Media/Videos/test2.wmv" );

    This is called within a class function that belongs to the MainPage class created when a new project is created in Visual Studio. I don't see how this could be a problem, so long as changing sources this way has some background memory that isn't being cleared.

    Now for the images, I declare an image in XAML similar to the Media Element.

    <Image x:Name="TestImage"
                   Stretch="None"
                   HorizontalAlignment="Left"
                   VerticalAlignment="Top"
                   Source="Media/Artwork/testImage.png">
                <Image.RenderTransform>
                    <TranslateTransform x:Name="TestImageTransform"></TranslateTransform>
                </Image.RenderTransform>
            </Image>

    Now if I want to change the source of this image while the code is running or when a marker is reached within the video I call:

    testImage->Source = ref new BitmapImage( ref new Uri( this->BaseUri->AbsoluteUri, "Media/Artwork/testImage2.png" ) );

    If this is called within ME_MarkerReached as an example, I just exit the function and continue on without freeing anything. This is a simple version of what I'm doing and the only thing I can think of is that when I 'ref new' into the class variable. I'm creating an reference everytime that just gets overwritten and not freed.

    A possible solution I thought of was to include a temp variable, like so:

    BitmapImage^ tempImage = ref new BitmapImage( ref new Uri( this->BaseUri->AbsoluteUri, "Media/Artwork/testImage2.png" ) );
    testImage->Source = tempImage;

    Now the tempImage is a local reference which gets freed when I leave the scope, and it seems to do the work of swapping the image even though the reference is being deleted. I haven't done this for all of my images yet because I'm not sure if it works. Would that help? Changing only a couple doesn't do anything the Media Element still stalls/stutters eventually.

    If you need more than this I'll try and come up with some more information as you need.

    Hope this helps,

    Alex.

    Monday, March 19, 2012 7:37 PM