【问题标题】:Memory leak when using avplayer and opengl使用 avplayer 和 opengl 时的内存泄漏
【发布时间】:2016-01-09 13:12:24
【问题描述】:

编辑 3

我找到了根本原因。 CADisplayLink 对目标有强引用。所以它产生了 Retain Cycles。

编辑 2

现在我认为是内存问题导致崩溃。

我正在做的是捕获播放器的输出并将其绘制在opengl层上。

AVPlayerItem *item = ...;
if (!self.player) {
    self.player = [AVPlayer playerWithPlayerItem:item];
} else {
    [self.player replaceCurrentItemWithPlayerItem:item];
}

NSDictionary *pixBuffAttributes = @{(id)kCVPixelBufferPixelFormatTypeKey: @(kCVPixelFormatType_32BGRA)};
self.videoOutput = [[AVPlayerItemVideoOutput alloc] initWithPixelBufferAttributes:pixBuffAttributes];
[self.player.currentItem addOutput:self.videoOutput];

[self.player seekToTime:kCMTimeZero];
[self.player play];

DisplayLink的回调中

CMTime itemTime = [self.videoOutput itemTimeForHostTime:CACurrentMediaTime()];
BOOL hasNewContent = [self.videoOutput hasNewPixelBufferForItemTime:itemTime];
if (hasNewContent) {
    CVPixelBufferRef pixelBuffer = [self.videoOutput copyPixelBufferForItemTime:itemTime itemTimeForDisplay:NULL];
    // creat texture with pixelBuffer
    // display texture on opengl surface
    if (pixelBuffer != NULL) {
        CFRelease(pixelBuffer);
    }
}

仪器没有内存泄漏,但内存正在上升。

编辑 1:

我找到了解决方法。 “video_1”和“video_3”的分辨率为3840 * 1920,“video_2”的分辨率为2160 * 1080。

当我使用 ffmpeg 将所有分辨率更改为 2160 * 1080 时,它起作用了。

起源

我想依次播放几个视频,遇到一个很奇怪的行为。

AVPlayerItem *item = ...;
if (!self.player) {
    self.player = [AVPlayer playerWithPlayerItem:item];
} else {
    [self.player replaceCurrentItemWithPlayerItem:item];
}
[self.player seekToTime:kCMTimeZero];
[self.player play];

例如,我有三个视频文件,例如 video_1、video_2 和 video_3。

首先,我将 playerItem 设置为“video_1”,然后替换为“video_2”。没关系。

但我用“video_3”替换,应用程序崩溃了。我在我的 iPhone 上找不到任何设备日志。更何况,我在调试和替换为“video_3”的时候,它会断开调试,也不例外!

更多信息:

"video_2" can replace "video_1"
"video_1" can replace "video_2"
"video_3" can replace "video_2"
"video_3" can't replace "video_1"
"video_1" can't replace "video_3"

所有视频都可以单独正常播放。

【问题讨论】:

  • 我想我和你有同样的问题。你最后是怎么解决的?你是如何删除强引用的?
  • 偶然解决?

标签: ios memory-leaks opengl-es avfoundation


【解决方案1】:

试试下面的代码

if ([playerItemVideoOutput hasNewPixelBufferForItemTime:currentTime]) {
    __unsafe_unretained ViewController *weakSelf = self; //create weak reference of your viewcontroller
    CVPixelBufferRef pixelBuffer = [playerItemVideoOutput copyPixelBufferForItemTime:currentTime itemTimeForDisplay:nil];
    if(pixelBuffer) { //check if buffer exist
            [weakSelf.metalView.realTimeRender setPixelBuffer:pixelBuffer]; //use weakSelf here
            CFRelease(pixelBuffer);
    }
}

【讨论】:

  • 你能扩展答案吗?我遇到了类似的问题,但是一旦我停止播放,内存就会恢复正常。想知道可以做些什么……
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多