objective-c - 使用Videotoolbox进行H264编解码

标签 objective-c cocoa encoding video-toolbox

我正在使用 videotoolbox 测试编码和解码,将捕获的帧转换为 H264 并使用该数据在 AVSampleBufferdisplayLayer 中显示它。

解压缩 CMVideoFormatDescriptionCreateFromH264ParameterSets 时出错,错误代码为 -12712

我关注this code from mobisoftinfotech.com

status = CMVideoFormatDescriptionCreateFromH264ParameterSets(
    kCFAlloc‌​‌ atorDefault, 2,
    (const uint8_t const)parameterSetPointers, 
    parameterSetSizes, 4, &_formatDesc);

视频压缩测试;谁能解决这个问题吗?

最佳答案

我不确定你是否已经解决了这个问题。但是,我在您的代码中发现了导致错误的两个地方。修复它们并在本地运行您的测试应用程序后,它似乎工作正常。 (使用 Xcode 9.4.1、MacOS 10.13 测试)

第一个位于-(void)CompressAndConvertToData:(CMSampleBufferRef)sampleBuffer方法中,其中while循环应如下所示

while (bufferOffset < blockBufferLength - AVCCHeaderLength) {
    // Read the NAL unit length
    uint32_t NALUnitLength = 0;
    memcpy(&NALUnitLength, bufferDataPointer + bufferOffset, AVCCHeaderLength);
    // Convert the length value from Big-endian to Little-endian
    NALUnitLength = CFSwapInt32BigToHost(NALUnitLength);
    // Write start code to the elementary stream
    [elementaryStream appendBytes:startCode length:startCodeLength];
    // Write the NAL unit without the AVCC length header to the elementary stream
    [elementaryStream appendBytes:bufferDataPointer + bufferOffset + AVCCHeaderLength
                           length:NALUnitLength];
    // Move to the next NAL unit in the block buffer
    bufferOffset += AVCCHeaderLength + NALUnitLength;
}

uint8_t *bytes = (uint8_t*)[elementaryStream bytes];
int size = (int)[elementaryStream length];

[self receivedRawVideoFrame:bytes withSize:size];

第二个地方是处理 NALU 类型 8 的解压代码,即 if(nalu_type == 8) 语句中的代码块。这是一个棘手的问题。 要修复它,请更新

for (int i = _spsSize + 12; i < _spsSize + 50; i++)

for (int i = _spsSize + 12; i < _spsSize + 12 + 50; i++)

您可以自由地删除此黑客

//was crashing here
    if(_ppsSize == 0)
        _ppsSize = 4;
为什么?让我们打印出帧数据包格式。 PO 帧 ▿ 4282 个元素 - 0:0 - 1:0 - 2:0 - 3:1 - 4:39 - 5:100 - 6:0 - 7 : 30 - 8:172 - 9 : 86 - 10:193 - 11:112 - 12:247 - 13:151 - 14:64 - 15:0 - 16:0 - 17:0 - 18:1 - 19:40 - 20:238 - 21:60 - 22:176 - 23:0 - 24:0 - 25:0 - 26:1 - 27:6 - 28:5 - 29 : 35 - 30:71 - 31:86 - 32:74 - 33:220 - 34:92 - 35:76 - 36:67 - 37:63 - 38:148 - 39:239 - 40:197 - 41:17 - 42:60 - 43:209 - 44:67 - 45:168 - 46:0 - 47:0 - 48:3 - 49:0 - 50:0 - 51:3 - 52:0 - 53:2 - 54:143 - 55:92 - 56:40 - 57:1 - 58:221 - 59:204 - 60:204 - 61:221 - 62:2 - 63:0 - 64:76 - 65 : 75 - 66:64 - 67:128 - 68:0 - 69:0 - 70:0 - 71:1 - 72:37 - 73:184 - 74:32 - 75:1 - 76:223 - 77:205 - 78:248 - 79:30 - 80:231 … 更多的

第一个NALU起始码if (nalu_type == 7)是从索引15到18的0,0,0,1。接下来的0,0,0,1(从23到26) 是类型 6,类型 8 NALU 起始代码是从 68 到 71。这就是为什么我稍微修改一下 for 循环,从起始索引 (_spsSize + 12) 开始扫描,范围为 50。

我尚未完全测试您的代码以确保编码和解码按预期正常工作。不过,我希望这一发现能够对您有所帮助。 顺便说一句,如果有任何误解,我很乐意从您的评论中学习。

关于objective-c - 使用Videotoolbox进行H264编解码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47217998/

相关文章:

javascript - 解码 Node.js 中用 Python 编码的字符串

objective-c - Xcode 验证错误 : non-public selectors

ios - 如何使图像和字符串的单个数组?在IOS中

objective-c - NSAlert 调整窗口大小

swift - 打印用户点击的NSTableView的行号

hadoop - Ambari Hive UTF-8 问题

Python:通过 utf-8 字符串进行迭代 -> 迭代器的数据类型/编码是什么?

objective-c - Objective-C 中的抽象类

ios - 将插入符号拖动到 View 边缘时如何使我的 UITextView 自动滚动?

objective-c - 在xcode中使用esellerate SDK问题