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 <timur.pocheptsov@theqtcompany.com>
This commit is contained in:
@@ -35,6 +35,8 @@
|
|||||||
#include "avfmediaplayerservice.h"
|
#include "avfmediaplayerservice.h"
|
||||||
#include "avfvideooutput.h"
|
#include "avfvideooutput.h"
|
||||||
|
|
||||||
|
#include <qpointer.h>
|
||||||
|
|
||||||
#import <AVFoundation/AVFoundation.h>
|
#import <AVFoundation/AVFoundation.h>
|
||||||
|
|
||||||
QT_USE_NAMESPACE
|
QT_USE_NAMESPACE
|
||||||
@@ -105,15 +107,23 @@ static void *AVFMediaPlayerSessionObserverCurrentItemObservationContext = &AVFMe
|
|||||||
//Create an asset for inspection of a resource referenced by a given URL.
|
//Create an asset for inspection of a resource referenced by a given URL.
|
||||||
//Load the values for the asset keys "tracks", "playable".
|
//Load the values for the asset keys "tracks", "playable".
|
||||||
|
|
||||||
AVURLAsset *asset = [AVURLAsset URLAssetWithURL:m_URL options:nil];
|
// use __block to avoid maintaining strong references on variables captured by the
|
||||||
NSArray *requestedKeys = [NSArray arrayWithObjects:AVF_TRACKS_KEY, AVF_PLAYABLE_KEY, nil];
|
// 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.
|
// Tells the asset to load the values of any of the specified keys that are not already loaded.
|
||||||
[asset loadValuesAsynchronouslyForKeys:requestedKeys completionHandler:
|
[asset loadValuesAsynchronouslyForKeys:requestedKeys completionHandler:
|
||||||
^{
|
^{
|
||||||
dispatch_async( dispatch_get_main_queue(),
|
dispatch_async( dispatch_get_main_queue(),
|
||||||
^{
|
^{
|
||||||
[self prepareToPlayAsset:asset withKeys:requestedKeys];
|
if (session)
|
||||||
|
[blockSelf prepareToPlayAsset:asset withKeys:requestedKeys];
|
||||||
|
[asset release];
|
||||||
|
[requestedKeys release];
|
||||||
});
|
});
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user