Memory leak in VideoPlayer

Hello!

I have simple code:

public class JustVideo : MonoBehaviour
{
    // Start is called before the first frame update
    public VideoClip[] clips;
    public VideoPlayer videoPlayer;
    int i=0;
    void Start()
    {
        videoPlayer.loopPointReached += VideoPlayer_loopPointReached;
    }

    private void VideoPlayer_loopPointReached(VideoPlayer source)
    {
        i++;
        videoPlayer.clip = clips[i%6];
        videoPlayer.Play();
    }
}

VideoClips are about 400kBytes;

When I start with profiling, Used Total = 30 Mb, after 10 minutes Used Total = 100Mb.
After two hour:
Used Total: 0.9Gb
GfxDriver: 0.85Gb
Total System Memory Usage: 1.7Gb

Why? What is wrong?

Maybe -just maybe it’s an idea- you have to Stop() it just to free the resources from previous clip, so before assigning the clip again (videoPlayer.clip = clips[i%6];), run a videoplyer.Stop().

1 Like

Did this solve your Problem?
I have the same problem, and stop() doesn’t help. Is there anything i’m not getting here?

I made a clean test-project and scene with nothing but a videoplayer rendering to camera near-plane and a little script - see below. All it does is toggling between stop() and play(). I don’t change the url / clip.

With every play() gfxDriver@profiler takes up some memory it never releases until it crashes once the memory is full, though the texture-count or their memory-usage doesn’t change.
How much memory it takes depends on the video-resolution - FullHD takes around 3.5mb, 4k uses around 12mb.
This happens in Editor as well as in PC-Builds. It does not happen in ios-Builds.

It doesn’t matter wether i use Clip or URL as Source. It doesn’t matter wether i render to a RenderTarget or Near-/Far-plane.

I tried it in Unity 2018.3.5, 2018.3.14 as well as 2019.1.2.
I tried it on 3 different PCs with different gfx-cards, win7 and win10 - all the same.

Is noone else having this Problem?

Thanks for your help.

using System;
using UnityEngine;
using UnityEngine.Video;

public class TestCtrl : MonoBehaviour {
    VideoPlayer m_vid;

    DateTime m_lastChange = DateTime.Now;
    bool toggle = false;

    void Start() {
        m_vid = GetComponent<VideoPlayer>();
    }

    void Update() {
        if ( ( DateTime.Now - m_lastChange ).TotalSeconds > 1 ) {       
            if( toggle )
                m_vid.Stop();
            else
                m_vid.Play();
          
            toggle = !toggle;
            m_lastChange = DateTime.Now;
        }
    }
}

I always use a clean videoplayer, so I have to assign the videoclip by code, prepare it manually using video.Prepare() and then I play it when video.isPrepared is true.

The videoplayer has PlayOnAwake to False and waitforfirstFrame to False too because I do all of it manually by code.
When I release the video I always use video.Stop() and after it is stopped I assign the video.clip = null;

I’ve never use the same videoplayer twice to play two different videoclips, so if I have to play another clip I create another videoplayer (even by code at runtime using AddComponent) and when I end playing it I can disable or destroy it.

I made an app with 100 clips and I used 100 different videoplayers created at runtime so I can jump from one clip to another depending on player’s interactions without any kind or gap or even a black screen for a single frame (on IOS & standalone). Using this method is almost imposible to run into memory problems because you can Prepare/Release any player as you please by code.

You can check it here, it’s a basket game made using videoclips to play it: https://itunes.apple.com/es/app/basketkid/id1363876181?mt=8

On the other hand, in your case you could try cleaning garbage. It’s a long shot but I’m out of ideas…
System.GC.Collect();
Resources.UnloadUnusedAssets();
Application.GarbageCollectUnusedAssets();

Thanks for all your help.

I tried creating a new Videoplayer every time ( AddComponent ) like you said, but it’s still the same.
iOS works - only PC-Builds and PC-Editor show this behaviour.

It takes several thousand fullhd-videos ( or play-stop-cycles ) until it really crashes. But i need my app to run for days nonstop and i cannot distribute it while it’s leaking memory.

I guess i’m gonna go with a bug-report then.

In case anyone else stumples upon this - the issue has been fixed with 2019.2b Beta

“Graphics: Fixed Video Player Leaks GfxDriver Memory. (1136233, 1148733)”

Thanks for the info.

I suppose it will be fixed in future Unity LTS releases too (to pathch previous unity versions as usual).

Any news on that ?
I did not find the issue report even if there is an issue number in the beta changelog.
Any clue as to when this fix will be available for the 2019.1 ?

So for now we can’t release on mobile devices

The release-log says it was fixed with 2019.1.6 and 2018.4.3

As far as i can tell mobile devices were never affected by this bug - only PC.

1 Like

I’m having the same leak on 2019.1.8f on iOS
Didn’t have it in 2018 :frowning:

EDIT.
I’m also experiencing it on Mac - the Unity profile doesn’t show the leak at all ( not for iOS and neither for macOS ) but when using profiling tools in xcode or just keeping an eye out on the activity monitor the memory just keeps increasing

Have same problem, clips downgraded to 720, standard mp4 h264 compr. instancing Video players in runtime, stoping videoPlayers at end and destroying after that. Nothing, the memory is increasing , ridiculous. Problems with the render engine, problems with the video… This is too painly my friends…

I have the same issue with Unity 2019.1.0 on iOS devices, instance VideoPlayer in run time render mode to API only, and stop and destroy video player game object but the memory allocation never got released… very bad :frowning:

same problem please any fix ?

I also have the same problem and it’s driving me crazy. I am using quite large 360 video files, around 5gb per video and I’m running the app on an oculus go. When I reload a video 3 times in a short amount of time it crashes. Then I tried making a new videoplayer when I want to change a video and destroying the old one but now it just instantly crashes when I try to change the video. This is my adb logcat output:

09-11 02:05:01.696 22170 22487 I Unity   : changed url
09-11 02:05:01.696 22170 22487 I Unity   : UnityEngine.DebugLogHandler:Internal_Log(LogType, LogOption, String, Object)
09-11 02:05:01.696 22170 22487 I Unity   : UnityEngine.DebugLogHandler:LogFormat(LogType, Object, String, Object[])
09-11 02:05:01.696 22170 22487 I Unity   : UnityEngine.Logger:Log(LogType, Object)
09-11 02:05:01.696 22170 22487 I Unity   : UnityEngine.Debug:Log(Object)
09-11 02:05:01.696 22170 22487 I Unity   : WebServer:ListenerCallback(IAsyncResult) (at C:\Users\Felix\MyFirstGame\Assets\WebServer.cs:156)
09-11 02:05:01.696 22170 22487 I Unity   : System.Net.ListenerAsyncResult:InvokeCallback(Object)
09-11 02:05:01.696 22170 22487 I Unity   : System.Threading.QueueUserWorkItemCallback:System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
09-11 02:05:01.696 22170 22487 I Unity   : System.Threading.ThreadPoolWorkQueue:smile:ispatch()
09-11 02:05:01.696 22170 22487 I Unity   : System.Threading._ThreadPoolWaitCallback:PerformWaitCallback()
09-11 02:05:01.696 22170 22487 I Unity   :
09-11 02:05:01.696 22170 22487 I Unity   : (Filename: C Line: 0)
09-11 02:05:01.696 22170 22487 I Unity   :
09-11 02:05:01.702 22170 22487 I Unity   : started video3
09-11 02:05:01.702 22170 22487 I Unity   : UnityEngine.DebugLogHandler:Internal_Log(LogType, LogOption, String, Object)
09-11 02:05:01.702 22170 22487 I Unity   : UnityEngine.DebugLogHandler:LogFormat(LogType, Object, String, Object[])
09-11 02:05:01.702 22170 22487 I Unity   : UnityEngine.Logger:Log(LogType, Object)
09-11 02:05:01.702 22170 22487 I Unity   : UnityEngine.Debug:Log(Object)
09-11 02:05:01.702 22170 22487 I Unity   : WebServer:ListenerCallback(IAsyncResult) (at C:\Users\Felix\MyFirstGame\Assets\WebServer.cs:159)
09-11 02:05:01.702 22170 22487 I Unity   : System.Net.ListenerAsyncResult:InvokeCallback(Object)
09-11 02:05:01.702 22170 22487 I Unity   : System.Threading.QueueUserWorkItemCallback:System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
09-11 02:05:01.702 22170 22487 I Unity   : System.Threading.ThreadPoolWorkQueue:smile:ispatch()
09-11 02:05:01.702 22170 22487 I Unity   : System.Threading._ThreadPoolWaitCallback:PerformWaitCallback()
09-11 02:05:01.702 22170 22487 I Unity   :
09-11 02:05:01.702 22170 22487 I Unity   : (Filename: C Line: 0)
09-11 02:05:01.702 22170 22487 I Unity   :
09-11 02:05:01.738 22170 22185 I Unity   : created new video player
09-11 02:05:01.738 22170 22185 I Unity   : UnityEngine.DebugLogHandler:Internal_Log(LogType, LogOption, String, Object)
09-11 02:05:01.738 22170 22185 I Unity   : UnityEngine.DebugLogHandler:LogFormat(LogType, Object, String, Object[])
09-11 02:05:01.738 22170 22185 I Unity   : UnityEngine.Logger:Log(LogType, Object)
09-11 02:05:01.738 22170 22185 I Unity   : UnityEngine.Debug:Log(Object)
09-11 02:05:01.738 22170 22185 I Unity   : WebServer:Update() (at C:\Users\Felix\MyFirstGame\Assets\WebServer.cs:65)
09-11 02:05:01.738 22170 22185 I Unity   :
09-11 02:05:01.738 22170 22185 I Unity   : (Filename: C Line: 0)
09-11 02:05:01.738 22170 22185 I Unity   :
09-11 02:05:01.752 22170 22236 D Unity   : Unloading 4 Unused Serialized files (Serialized files now loaded: 0)
09-11 02:05:01.757 22170 22185 I Unity   : changed url in main thread
09-11 02:05:01.757 22170 22185 I Unity   : UnityEngine.DebugLogHandler:Internal_Log(LogType, LogOption, String, Object)
09-11 02:05:01.757 22170 22185 I Unity   : UnityEngine.DebugLogHandler:LogFormat(LogType, Object, String, Object[])
09-11 02:05:01.757 22170 22185 I Unity   : UnityEngine.Logger:Log(LogType, Object)
09-11 02:05:01.757 22170 22185 I Unity   : UnityEngine.Debug:Log(Object)
09-11 02:05:01.757 22170 22185 I Unity   : WebServer:Update() (at C:\Users\Felix\MyFirstGame\Assets\WebServer.cs:78)
09-11 02:05:01.757 22170 22185 I Unity   :
09-11 02:05:01.757 22170 22185 I Unity   : (Filename: C Line: 0)
09-11 02:05:01.757 22170 22185 I Unity   :
09-11 02:05:01.780   592  2754 W ServiceManager: Permission failure: com.oma.drm.permission.ACCESS_OMA_DRM from uid=10182 pid=22170
09-11 02:05:01.782 22170 22185 D Unity   : System memory in use before: 17.0 MB.
09-11 02:05:01.798 22170 22185 D Unity   : System memory in use after: 17.1 MB.
09-11 02:05:01.798 22170 22185 D Unity   :
09-11 02:05:01.798 22170 22185 D Unity   : Unloading 3 unused Assets to reduce memory usage. Loaded Objects now: 742.
09-11 02:05:01.798 22170 22185 D Unity   : Total: 16.163699 ms (FindLiveObjects: 0.871041 ms CreateObjectMapping: 0.125520 ms MarkObjects: 12.846407 ms  DeleteObjects: 2.311198 ms)
09-11 02:05:01.798 22170 22185 D Unity   :
09-11 02:05:01.859   596  2869 I OMX-VDEC-1080P: omx_vdec::component_deinit() complete
09-11 02:05:01.863   596  2869 I OMX-VDEC-1080P: Exit OMX vdec Destructor: fd=8
09-11 02:05:01.865   596  2869 I OMX-VDEC-1080P: Video slvp perflock released
09-11 02:05:01.892   592  2754 W ServiceManager: Permission failure: com.oma.drm.permission.ACCESS_OMA_DRM from uid=10182 pid=22170
09-11 02:05:01.901   592   592 W ServiceManager: Permission failure: com.oma.drm.permission.ACCESS_OMA_DRM from uid=10182 pid=22170
09-11 02:05:01.902   598   598 I ExtendedExtractor: QTIParser is prefered .. flags 0
09-11 02:05:01.906   598   598 D MMParserExtractor: setExtraFlags called with flags 0 for paser instance f5f2dd20
09-11 02:05:01.906   598   598 I ExtendedExtractor: ExtendedExtractor::create 0xf5f2dd20
09-11 02:05:01.942   598  2824 E MM_OSAL : Atom::Atom _success is false due to size < DEFAULT_ATOM_SIZE
09-11 02:05:01.971   598  2824 E MM_OSAL : Atom::Atom _success is false due to size < DEFAULT_ATOM_SIZE
09-11 02:05:02.030 31468 31875 I MediaPlayerService: MediaPlayerService::getOMX
09-11 02:05:02.031 22170 22491 I OMXClient: MuxOMX ctor
09-11 02:05:02.038   596  1517 I OMXMaster: makeComponentInstance(OMX.qcom.video.decoder.hevc) in mediacodec process
09-11 02:05:02.040   596  1517 I OMX-VDEC-1080P: Video slvp perflock acquired
09-11 02:05:02.042   596  1517 I OMX-VDEC-1080P: component_init: OMX.qcom.video.decoder.hevc : fd=8
09-11 02:05:02.056   596  1517 I OMX-VDEC-1080P: omx_vdec::component_init() success : fd=8
09-11 02:05:02.059 22170 22491 I ExtendedACodec: setupVideoDecoder()
09-11 02:05:02.059 22170 22491 I ExtendedACodec: vpp-enable search is 0 and value is 0
09-11 02:05:02.062   596  2843 E OMX-VDEC-1080P: Extension: OMX.google.android.index.storeANWBufferInMetadata not implemented
09-11 02:05:02.062   596  2843 E OMX-VDEC-1080P: Extension: OMX.google.android.index.configureVideoTunnelMode not implemented
09-11 02:05:02.062   596  2843 E OMX-VDEC-1080P: Extension: OMX.google.android.index.useAndroidNativeBuffer is supported
09-11 02:05:02.098   596   596 E C2DColorConvert: unknown format passed for luma alignment number
09-11 02:05:02.099   596  1517 E C2DColorConvert: unknown format passed for luma alignment number
09-11 02:05:02.100   596  2841 E C2DColorConvert: unknown format passed for luma alignment number
09-11 02:05:02.103 22170 22491 I ExtendedACodec: Decoder will be in frame by frame mode
09-11 02:05:02.108   596  2866 E C2DColorConvert: unknown format passed for luma alignment number
09-11 02:05:02.109   596  2869 E C2DColorConvert: unknown format passed for luma alignment number
09-11 02:05:02.111   596  1517 E OMXNodeInstance: getParameter(2540255:qcom.decoder.hevc, ??(0x7f000044)) ERROR: UnsupportedSetting(0x80001019)
09-11 02:05:02.185   596  2843 E C2DColorConvert: unknown format passed for luma alignment number
09-11 02:05:02.312 31467   917 W audio_hw_extn: audio_extn_snd_device_out_get_parameters: Error(22): audio usecase 1 returned NULL
09-11 02:05:02.466 22170 22230 I VrApi   : FPS=31,Prd=32ms,Tear=0,Early=0,Stale=34,VSnc=1,Lat=1,Fov=0,CPU2/GPU=4/3,1593/401MHz,OC=F,TA=E/0/0,SP=F/N/N,Mem=1804MHz,Free=499MB,PSM=0,PLS=0,Temp=31.7C/25.0C,TW=1.82ms,App=16.04ms,GD=0.00ms,CPU&GPU=0.00ms,LCnt=1,GPU%=0.49,CPU%=0.84(W1.00),DSF=1.00
09-11 02:05:02.470 31468 31477 I MediaPlayerService: MediaPlayerService::getOMX
09-11 02:05:02.472 22170 22497 I OMXClient: MuxOMX ctor
09-11 02:05:02.475   596   596 I OMXMaster: makeComponentInstance(OMX.google.aac.decoder) in mediacodec process
09-11 02:05:02.519   596 22498 I SoftAAC2: Reconfiguring decoder: 0->48000 Hz, 0->2 channels
09-11 02:05:02.742   596  1517 E C2DColorConvert: unknown format passed for luma alignment number
09-11 02:05:02.743   596   747 E C2DColorConvert: unknown format passed for luma alignment number
09-11 02:05:02.746   596  2866 E OMXNodeInstance: getParameter(2540255:qcom.decoder.hevc, ??(0x7f000044)) ERROR: UnsupportedSetting(0x80001019)
09-11 02:05:02.780   596  2869 E C2DColorConvert: unknown format passed for luma alignment number
09-11 02:05:02.780   596  2869 E C2DColorConvert: unknown format passed for luma alignment number
09-11 02:05:03.406   572   572 I lowmemorykiller: Killing 'android.process.media' (22302), uid 10006, adj 900
09-11 02:05:03.406   572   572 I lowmemorykiller:    to free 36392kB because cache 218936kB is below limit 221184kB for oom_adj 900
09-11 02:05:03.406   572   572 I lowmemorykiller:    Free memory is 34792kB below reserved
09-11 02:05:03.446 31651 32011 I ActivityManager: Process android.process.media (pid 22302) has died
09-11 02:05:03.446 31651 32011 D ActivityManager: cleanUpApplicationRecord -- 22302
09-11 02:05:03.455   572   572 D LMKTelemetry: LMK telemetry stats: {"killed_task_adj":900,"killed_task_name":"android.process.media","killed_task_size_kbytes":36392,"killed_task_uid":10006,"os_cache_kbytes":218936,"os_cache_min_kbytes":221184,"os_min_adj":900,"os_prev_overcommit_kbytes":34792,"processes":"null\n","source":1,"zram_enabled":0}
09-11 02:05:03.460 31651 31700 W libprocessgroup: failed to open /acct/uid_10006/pid_22302/cgroup.procs: No such file or directory
09-11 02:05:03.516 22170 22230 I VrApi   : FPS=30,Prd=36ms,Tear=0,Early=0,Stale=55,VSnc=1,Lat=1,Fov=0,CPU2/GPU=4/3,1593/401MHz,OC=F,TA=E/0/0,SP=F/N/N,Mem=1804MHz,Free=202MB,PSM=0,PLS=0,Temp=31.7C/25.0C,TW=1.71ms,App=3.43ms,GD=0.00ms,CPU&GPU=0.00ms,LCnt=1,GPU%=0.21,CPU%=0.97(W1.00),DSF=1.00
09-11 02:05:03.638   572   572 I lowmemorykiller: Killing 'com.oculus.micservice' (22262), uid 1000, adj 800
09-11 02:05:03.638   572   572 I lowmemorykiller:    to free 27252kB because cache 125532kB is below limit 129024kB for oom_adj 300
09-11 02:05:03.638   572   572 I lowmemorykiller:    Free memory is 32500kB below reserved

Obviously somehow the memory is instantly full and android starts klling off processes with lowmemory killer. The first error after sending the command is

09-11 02:05:01.942 598 2824 E MM_OSAL : Atom::Atom _success is false due to size < DEFAULT_ATOM_SIZE
09-11 02:05:01.971 598 2824 E MM_OSAL : Atom::Atom _success is false due to size < DEFAULT_ATOM_SIZE

that might have something to do with it but I have no idea. Does anybody know I can get this to work?

This is my code from the update method:

if (_stopped)
        {
            _videoPlayer.Stop();
            _stopped = false; //reset variable
            Destroy(_videoPlayer); //destroy old video player and create a new one below
           
            gameObject.AddComponent<UnityEngine.Video.VideoPlayer>();
            _videoPlayer = GetComponent<VideoPlayer>();
            //set basic settings of the new videoplayer
            _videoPlayer.enabled = true;
            _videoPlayer.skipOnDrop = true;
            _videoPlayer.renderMode = VideoRenderMode.RenderTexture;
            _videoPlayer.targetTexture = Resources.Load<RenderTexture>("RT 360 Video");
            _videoPlayer.aspectRatio = VideoAspectRatio.FitHorizontally;
            _videoPlayer.audioOutputMode = VideoAudioOutputMode.Direct;
            Debug.Log("created new video player");
           

            Resources.UnloadUnusedAssets(); //manual garbage collection
            GC.Collect();
        }
       
        if(_urlChanged && _url != "") {
            _videoPlayer.url = _url;
            _urlChanged = false;
            _videoPlayer.Prepare();
            Debug.Log("changed url in main thread");
        }

I tried it with and without garbage collection, with and without preparing before playing the video. When using the same video player and just changing the url it crashes after 3 reloads as I already mentioned but with this code (trying to make a new videoplayer every time) it just crashes instantly when I reload the video.

Did you manage to find a solution? I’m having a very similar problem with 360º videos. Also, just out of curiosity, what resolution are you playing? I’m trying to play 4000x2000 clips and in many devices, I just get a black screen, both in Android and iOS… :confused:

I have a same problem with this… allocation never get released and profiler seemed didn’t detect it, task manager shown my VRAM is maxed out after playing 360videos in short amount of time.

I made another thread regarding this before I realize that this thread exist and discussing basically same thing…

Any help?

Edited: I found that this is not a problem in Unity 2018. I have not checked Unity 2020.

It’s not a fundamental solution, but it’s been solved.
Once the scene itself moves, it removes the reference count and unloads it, and if the video player unloads the scene before Stop(), the video clip and video player’s memory allocation will not be released. Therefore, I think you have to wait one frame after Stop() or make sure you stop before the scene is unloaded.

1 Like

Unity 2020: Memory leak is fixed under Mono and:

videoPlayer.Stop();
videoPlayer.clip = null; //Without this line it still leaks
GameObject.Destroy(videoPlayer.gameObject,1);

1 Like

If you play the video using RenderMode set as “Material Override” which you can find in the video player settings, device will consume too much memory but as soon you shift the RenderMode to “Render Texture”, you’ll notice a significant reduction in RAM usage.

9429569--1321997--Screenshot 2023-10-25 at 1.26.06 PM.png