RenderHeads / UnityPlugin-AVProVideo

AVPro Video is a multi-platform Unity plugin for advanced video playback
https://www.renderheads.com/products/avpro-video/
235 stars 28 forks source link

CloseMedia takes about a second hanging the main thread #983

Closed patrikmrazek closed 2 years ago

patrikmrazek commented 2 years ago

When closing a video on Android, calling MediaPlayer.CloseMedia(), the operation sometime (I would say with 33% probability) takes over a second for some videos, freezing the main thread, which is unacceptable for our VR app. Profiler says that this single line in AndroidMediaPlayer::CloseMedia() takes the whole processing time. m_Video.Call("CloseVideo");

We have tried multiple setups using both MediaPlayer and ExoPlayer, we tried AVPro1 paid and a trial version of AVPro2. It's all the same. Any help would be much appreciated.

Thank you.

Your Setup (please complete the following information):

kahnivore commented 2 years ago

Could you provide a little code snippet of how you're using mediaPlayer.CloseMedia() please?

patrikmrazek commented 2 years ago

Thank you for a quick reply. So there is a paused video opened in the MediaPlayer which is supposed to be replaced with another one. When this is about to happen a SetVideo method is called.

The provided code comes from the branch before our experimental update to AVPro v2 trial, but it is basically the same code after the update - just replacing "Video" methods with "Media" ones.

We call a VideoPlayer.CloseVideo() a frame before OpenVideoFromFile(). We do this because OpenVideoFromFile fires CloseVideo internally. When a video is opened in the player, CloseVideo method usually takes about 30ms (when not hanging for a second) and OpenVideoFromFile takes another 30ms itself - this is true for MediaPlayer backend which we prefer to ExoPlayer. The ExoPlayer actually takes much less time to open a video. When a video is already closed the CloseVideo method called by the OpenVideoFromFile method takes negligible amount of time. So we are basically trying to split the execution time needed to change a video into two frames. However the one second lag occured even before we started to use CloseVideo method separately.

Here comes the code snippet.

public MediaPlayer VideoPlayer {get; private set;}

public void SetVideo(int id)
{
    StartCoroutine(SetVideoCo(id));
}

IEnumerator SetVideoCo(int id)
{
    string VideoFile = Path.Combine(AgeGroupFolder, videoDrill.CurrentPucks()[id].filename);
    if (File.Exists(VideoFile))
    {
        //just some flags reseting, all of them are fields not triggering anything else
        CurrentVideoPuckCreated = false;
        CurrentVideoPuckProcessed = false;
        PreShotSignalSent = false;
        CurrentVideoPuckSoundProcessed = false;
        VideoPlayer.CloseVideo();
        yield return null;
        VideoPlayer.OpenVideoFromFile(MediaPlayer.FileLocation.AbsolutePathOrURL, VideoFile, false);
        CurrentVideo = id;
        ...
kahnivore commented 2 years ago

Thanks for the details. So, this is actually happening on 1.x? Have you run these tests on your updated 2.x trial version?

Also would be useful to know where your media is stored (if local) or if you're streaming it.

It would also be useful to see your video if it's possible for you to share - if so, please send to unitysupport@renderheads.com with "983" in the subject line.

Thanks!

patrikmrazek commented 2 years ago

Yes, as stated in the original post we have tried to upgrade to 2.2.1 trial version - it also hangs for about a second on the same line. The media is stored locally in Application.persistentDataPath subfolder. I am sending an example video to the unitysupport email in a minute.

Thank you for the support!

Ste-RH commented 2 years ago

This does not sound right at all. I will run some timing analysis on various aspects of the close process and see if I can narrow down what might be causing it. Have you profiled your close/open procedure at all? IF so, anything to report?

patrikmrazek commented 2 years ago

From the Unity profiler the application hangs the whole time on this line m_Video.Call("CloseVideo"); from AndroidMediaPlayer::CloseMedia(). This however does not happen every time I close a video but like on every third one aprox.

patrikmrazek commented 2 years ago

If I can help you profile this thing any further, I will be happy to do so. If so let me know how please.

Ste-RH commented 2 years ago

I have looked into the close routine in our MediaPlayer API path and narrowed down the culprit to I think a single call:

m_MediaPlayer.reset();

This, however, is essential. Without resetting the player it will not be possible to open another video on that player. See here for an explanation.

I have looked at possible spinning the reset up on a thread, and so far not seen any bad results - though that is not to say it is thread safe. Moving this call to a thread would also likely require deeper changes (e.g. defer opening a video if the reset has not completed yet).

I will look into the ExoPlayer path next.

patrikmrazek commented 2 years ago

Thank you for narrowing that down. I tried to create a prototype of CloseMediaAsync method. I used the body of CloseMedia and called m_Video.Call("CloseVideo"); on a separate thread. I used a coroutine to check when the thread has finished and tried continuing with base.CloseVideo(); on the main thread from the coroutine. Loading of next video was supposed to start after the base.CloseVideo(); However the only thing I got was a crash so I guess that was not probably the right way to go :)

Ste-RH commented 2 years ago

I have offloaded the expensive reset in the close onto a thread, and also moved almost the entire open' the above approach in the MediaPlayer API path as it appears to be thread safe. I guess time will tell!

ExoPlayer is a different animal and such a change will not be quick and quite a bit architecture change. I am putting into the 'more thought required' category of our roadmap.

Hopefully, all being well, this change should make it into v2.2.4. It is unfortunately not possible to back-port this to v1 even if we were still adding features/fixes and so will be v2 only.

patrikmrazek commented 2 years ago

So glad to hear that. This solution will do for us. Many thanks!

stale[bot] commented 2 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

AndrewRH commented 2 years ago

AVPro Video 2.3.0 has been released and includes a fix for this issue. Thanks,

patrikmrazek commented 2 years ago

Thank you!