在VTDecompressionSessionCreate中解码H264 VideoToolkit API失败,错误-8971

我正在尝试使用硬件支持的video工具包解码器编写video解码器。 但是,如果我尝试像下面发布的例子那样初始化解码会话,那么在调用VTDecompressionSessionCreate时会出现错误-8971。 任何人都可以告诉我我在这里做错了吗?

感谢你并致以真诚的问候,

奥利弗

OSStatus status; int tmpWidth = sps.EncodedWidth(); int tmpHeight = sps.EncodedHeight(); NSLog(@"Got new Width and Height from SPS - %dx%d", tmpWidth, tmpHeight); const VTDecompressionOutputCallbackRecord callback = { ReceivedDecompressedFrame, self }; status = CMVideoFormatDescriptionCreate(NULL, kCMVideoCodecType_H264, tmpWidth, tmpHeight, NULL, &decoderFormatDescription); if (status == noErr) { // Set the pixel attributes for the destination buffer CFMutableDictionaryRef destinationPixelBufferAttributes = CFDictionaryCreateMutable( NULL, // CFAllocatorRef allocator 0, // CFIndex capacity &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); SInt32 destinationPixelType = kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange; CFDictionarySetValue(destinationPixelBufferAttributes,kCVPixelBufferPixelFormatTypeKey, CFNumberCreate(NULL, kCFNumberSInt32Type, &destinationPixelType)); CFDictionarySetValue(destinationPixelBufferAttributes,kCVPixelBufferWidthKey, CFNumberCreate(NULL, kCFNumberSInt32Type, &tmpWidth)); CFDictionarySetValue(destinationPixelBufferAttributes, kCVPixelBufferHeightKey, CFNumberCreate(NULL, kCFNumberSInt32Type, &tmpHeight)); CFDictionarySetValue(destinationPixelBufferAttributes, kCVPixelBufferOpenGLCompatibilityKey, kCFBooleanTrue); // Set the Decoder Parameters CFMutableDictionaryRef decoderParameters = CFDictionaryCreateMutable( NULL, // CFAllocatorRef allocator 0, // CFIndex capacity &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFDictionarySetValue(decoderParameters,kVTDecompressionPropertyKey_RealTime, kCFBooleanTrue); // Create the decompression session // Throws Error -8971 (codecExtensionNotFoundErr) status = VTDecompressionSessionCreate(NULL, decoderFormatDescription, decoderParameters, destinationPixelBufferAttributes, &callback, &decoderDecompressionSession); // release the dictionaries CFRelease(destinationPixelBufferAttributes); CFRelease(decoderParameters); // Check the Status if(status != noErr) { NSLog(@"Error %d while creating Video Decompression Session.", (int)status); continue; } } else { NSLog(@"Error %d while creating Video Format Descripttion.", (int)status); continue; } 

我也偶然发现了kVTVideoDecoderBadDataErr 。 在我的情况下,我正在改变头0x00000001的大小NAL包,其中包括这个头的4个字节,这就是原因。 我改变了大小不包括这4个字节( frame_size = sizeof(NAL) - 4 )。 这个大小应该用big-endian编码。

您需要从您的SPS和PPS创buildCMFormatDescriptionRef

 CMFormatDescriptionRef decoderFormatDescription; const uint8_t* const parameterSetPointers[2] = { (const uint8_t*)[currentSps bytes], (const uint8_t*)[currentPps bytes] }; const size_t parameterSetSizes[2] = { [currentSps length], [currentPps length] }; status = CMVideoFormatDescriptionCreateFromH264ParameterSets(NULL, 2, parameterSetPointers, parameterSetSizes, 4, &decoderFormatDescription); 

另外,如果您以Annex-B格式获取video数据,则需要删除开始代码并将其replace为解码器的4字节大小信息,以将其识别为avcc格式(即,CMVideoFormatDescriptionCreateFromH264ParameterSets的第5个参数是什么) 。

@Joride

请参阅http://www.szatmary.org/blog/25

它解释了NALU中每个缓冲区的头(第一个)字节描述了缓冲区的types。 你需要掩盖掉这些位并将它们与提供的表进行比较。 注意关于位域的注释。 您需要用0x1f掩码字节的types值。