diff options
authorYoann Lopes <>2016-08-17 14:03:49 +0200
committerYoann Lopes <>2016-08-22 09:51:20 +0000
commit69296d229eb2f5b5842f7855ef4110e0e4817da2 (patch)
parenta52aa624e69fa618aa0d29c2a147a7d472751de1 (diff)
AVFoundation: fix memory leak
Using 'self' in a block maintains a strong reference to it, the previous code would never release that reference and therefore leak the AVFMediaPlayerSessionObserver object when the session was deleted. Captured variables used in the relevant block are now marked with '__block' to make sure no strong references are maintained. We now also make sure the session still exist when that callback block is called. Change-Id: I847b524d8692559fe5884517abb5b9cc7696b4fd Reviewed-by: Timur Pocheptsov <>
1 files changed, 13 insertions, 3 deletions
diff --git a/src/plugins/avfoundation/mediaplayer/ b/src/plugins/avfoundation/mediaplayer/
index d3ec2ff9..24b6fe46 100644
--- a/src/plugins/avfoundation/mediaplayer/
+++ b/src/plugins/avfoundation/mediaplayer/
@@ -35,6 +35,8 @@
#include "avfmediaplayerservice.h"
#include "avfvideooutput.h"
+#include <qpointer.h>
#import <AVFoundation/AVFoundation.h>
@@ -105,15 +107,23 @@ static void *AVFMediaPlayerSessionObserverCurrentItemObservationContext = &AVFMe
//Create an asset for inspection of a resource referenced by a given URL.
//Load the values for the asset keys "tracks", "playable".
- AVURLAsset *asset = [AVURLAsset URLAssetWithURL:m_URL options:nil];
- NSArray *requestedKeys = [NSArray arrayWithObjects:AVF_TRACKS_KEY, AVF_PLAYABLE_KEY, nil];
+ // use __block to avoid maintaining strong references on variables captured by the
+ // following block callback
+ __block AVURLAsset *asset = [[AVURLAsset URLAssetWithURL:m_URL options:nil] retain];
+ __block NSArray *requestedKeys = [[NSArray arrayWithObjects:AVF_TRACKS_KEY, AVF_PLAYABLE_KEY, nil] retain];
+ __block AVFMediaPlayerSessionObserver *blockSelf = self;
+ QPointer<AVFMediaPlayerSession> session(m_session);
// Tells the asset to load the values of any of the specified keys that are not already loaded.
[asset loadValuesAsynchronouslyForKeys:requestedKeys completionHandler:
dispatch_async( dispatch_get_main_queue(),
- [self prepareToPlayAsset:asset withKeys:requestedKeys];
+ if (session)
+ [blockSelf prepareToPlayAsset:asset withKeys:requestedKeys];
+ [asset release];
+ [requestedKeys release];