为什么AVSampleBufferDisplayLayer因操作中断而失败(-11847)?

时间:2015-03-03 21:07:15

标签: ios h.264 video-toolbox

我正在使用AVSampleBufferDisplayLayer来解码和显示从服务器流式传输的H.264视频。当我的应用程序进入后台然后返回到前台时,解码过程变得紧张,AVSampleBufferDisplayLayer失败。我看到的错误是:

H.264 decoding layer has failed: Error Domain=AVFoundationErrorDomain
  Code=-11847 "Operation Interrupted" UserInfo=0x17426c500
  {NSUnderlyingError=0x17805fe90 "The operation couldn’t be completed.
    (OSStatus error -12084.)",
   NSLocalizedRecoverySuggestion=Stop other operations and try again.,
   NSLocalizedDescription=Operation Interrupted}

是否有其他人遇到AVSampleBufferDisplayLayer这样的问题?这是什么意思?

当我收到错误时,我试图销毁AVSampleBufferDisplayLayer并创建一个新的,但后来我开始从H.264解码器接收其他错误:

Error Domain=AVFoundationErrorDomain Code=-11821 "Cannot Decode"
UserInfo=0x1740e9700 {AVErrorMediaSubTypeKey=(1635148593),
  NSLocalizedFailureReason=The media data could not be decoded. It may be damaged.,
  NSUnderlyingError=0x174247680 "The operation couldn’t be completed. (OSStatus error -12909.)",
  AVErrorMediaTypeKey=vide,
  AVErrorPresentationTimeStampKey=CMTime: {7/30 = 0.233},
  NSLocalizedDescription=Cannot Decode}

AVSampleBufferDisplayLayer失败之前,我没有收到任何错误。

3 个答案:

答案 0 :(得分:0)

重建一个新的AVSampleBufferDisplayLayer后,你应该用最后一个最近的IDR帧排队,除了当前帧是IDR,这意味着你应该在解码时将nalus保存在一个GOP中,并在下一个IDR到来时删除它们。

答案 1 :(得分:0)

我解决了

// create renderer
let renderingLayer = AVSampleBufferDisplayLayer()

// when enqueue data
if renderingLayer.status == .failed {
    // this way
    renderingLayer.flushAndRemoveImage()
}

答案 2 :(得分:0)

我遇到了同样的问题,并且能够使用以下代码解决。我需要使用 pubDidBecomeActive 事件而不是 willEnterForeground 事件来处理 Siri 被激活的情况。

class RoomState: NSObject, ObservableObject  {
    private var subs = [AnyCancellable]()
    @Published var displayLayer = AVSampleBufferDisplayLayer()

    override init() {
        super.init()
        let pubDidBecomeActive = NotificationCenter.default.publisher(for: UIApplication.didBecomeActiveNotification)
        subs.append(pubDidBecomeActive.sink { [weak self] _ in
            self?.displayLayer = AVSampleBufferDisplayLayer()
        })
    }
}