在 Swift 中使用 FFmpeg 和 VideoToolbox 从 H.264 RTSP-Stream 获取 NALU

问题描述

我对视频处理非常陌生,现在我无法在 Swift 中使用 FFmpeg 和 VideoToolbox 解码我的 H.264 RTSP-Stream。

目前我对提取 sps 和 pps 有点不知所措

-> 它们存储在哪里?我有以下获取数据的选项

 - AVFrame.data
 - AVFrame.extended_data
 - AVFrame.metadata
 - AVPacket.data
 - AVPacket.side_data
 - AVCodecContext.extra_data

.. 等等

目前我正在使用 AVCodecContext.extra_data,但这似乎与 here

中的示例有点不同

我获取 SPS 和 PPS 的代码是这个

private func receiveRawFrame(frame:AVFrame,codecContext:AVCodecContext){
        //Get the extradata,where the SPS and the PPS is stored?
        let codecContextExtraData:UnsafeMutablePointer<UInt8> = codecContext.extradata
        
        let startCodeIndex = 0
        var secondStartCodeIndex = 0
        var thirdStartCodeIndex = 0
        
        var naluType = self.getNaluType(naluTypeRaw: codecContextExtraData[startCodeIndex + 4] & 0x1F)
        
        if naluType == .sps{
            print("Yeah SPS")
            for i in startCodeIndex+4...startCodeIndex + 40{
                if (codecContextExtraData[Int(i)] == 0x00 && codecContextExtraData[Int(i)+1] == 0x00 && codecContextExtraData[Int(i)+2] == 0x00 && codecContextExtraData[Int(i)+3] == 0x01){
                    secondStartCodeIndex = i
                    spsSize = i
                    break
                }
            }
            let secondNaluTypeRaw = (codecContextExtraData[Int(secondStartCodeIndex) + 4] & 0x1F)
            naluType = self.getNaluType(naluTypeRaw: secondNaluTypeRaw)
        }
        if naluType == .pps{
            print("Yeah PPS")
            for i in (spsSize+4)..<(spsSize+30){
                if (codecContextExtraData[Int(i)] == 0x00 && codecContextExtraData[Int(i)+1] == 0x00 && codecContextExtraData[Int(i)+2] == 0x00 && codecContextExtraData[Int(i)+3] == 0x01){
                    print("Never gets here")
                    break
                }
            }
        }
        else{
            print("other -> TBD")
        }
    }
}

获取naluType的进一步函数:

private func getNaluType(naluTypeRaw:UInt8) -> NaluType {
        switch naluTypeRaw {
        case 0: return .pframe
        case 5: return .iframe
        case 7: return .sps
        case 8: return .pps
        default:
            return .unknown
        }
    }

使用这个自定义枚举器:

enum NaluType {
        case sps
        case pps
        case pframe
        case iframe
        case unknown
    }

正如您在 receiveRawFrame 函数的注释中所见,我从未得到第三个 NALU。当我将 AVCodecContext.extraData[0] 打印到 [50] 时,我得到以下输出

0 0 0 1 103 66 192 30 217 3 197 104 64 0 0 3 0 64 0 0 12 3 197 139 146 0 0 0 1 104 203 140 178 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

现在说得通了,我从来没有得到第三个 NALU,因为只有 2 个 StartCode,但其余的在哪里?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...