问题
I am trying to create an AVURLAsset from an mp4 in memory. So I have created an implementation of AVAssetResourceLoaderDelegate.
@interface RLDelegate : NSObject <AVAssetResourceLoaderDelegate>
- (instancetype)initWithData:(NSData *)data contentType:(NSString *)contentType;
@end
@interface RLDelegate()
@property (nonatomic) NSData *data;
@property (nonatomic) NSString *contentType;
@end
@implementation RLDelegate
- (instancetype)initWithData:(NSData *)data contentType:(NSString *)contentType {
if (self = [super init]) {
self.data = [data copy];
self.contentType = contentType;
}
return self;
}
- (BOOL)resourceLoader:(AVAssetResourceLoader *)resourceLoader shouldWaitForLoadingOfRequestedResource:(AVAssetResourceLoadingRequest *)loadingRequest {
if (!self->_data)
return NO;
NSString * scheme = loadingRequest.request.URL.scheme;
AVAssetResourceLoadingContentInformationRequest* contentRequest = loadingRequest.contentInformationRequest;
if (contentRequest) {
contentRequest.contentType = self.contentType;
contentRequest.contentLength = self.data.length;
contentRequest.byteRangeAccessSupported = NO;
}
AVAssetResourceLoadingDataRequest* dataRequest = loadingRequest.dataRequest;
if (dataRequest) {
if (dataRequest.requestsAllDataToEndOfResource)
{
[dataRequest respondWithData:[self.data copy]];
}
else
{
NSRange range = NSMakeRange((NSUInteger)dataRequest.requestedOffset, (NSUInteger)dataRequest.requestedLength);
[dataRequest respondWithData:[[self.data subdataWithRange:range] copy]];
}
[loadingRequest finishLoading];
return YES;
}
return NO;
}
@end
I use it to read an MP4 like this:
void AssetFromMP4Data(NSData* videData)
{
@autoreleasepool {
tetRLDelegate = [[RLDelegate alloc] initWithData:videData contentType:AVFileTypeMPEG4];
NSURL *url = [NSURL URLWithString:@"tetData://"];
asset = [[AVURLAsset alloc] initWithURL:url options:nil];
loaderQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// or some other queue != main queue
[asset.resourceLoader setDelegate:tetRLDelegate queue:loaderQueue];
}
}
I am able to read the frames from the video track. However, the other processes memory constantly increase until it consume all memory in the device. I believe this loader delegate is the reason, because before I used the loader delegate, I would write the NSDATA to a file and read it with the AVAsset, utilising the disk instead of reading directly from NSData. This worked with no memory issues, but it's not ideal to read MP4 files like that, having to write them first to disk.
Any suggestions where the other processes memory leaks come from? I also don't see any memory leak from my own app with Xcode instrumentation.
来源:https://stackoverflow.com/questions/61617762/other-processes-untraceable-memory-leaks-when-using-avassetresourceloaderdeleg