2014-09-26 456 views
1

我一直在尝试使用VTDecompressionSessionDecodeFrame解码H264,但得到错误。参数集已被创建并且看起来很好,到目前为止没有任何错误,所以它可能与我对CMSampleBufferRef中定时信息​​的理解有关。任何投入将不胜感激VTDecompressionSessionDecodeFrame失败,代码为-kVTVideoDecoderBadDataErr

void didDecompress(void *decompressionOutputRefCon, void *sourceFrameRefCon, OSStatus status, VTDecodeInfoFlags infoFlags, CVImageBufferRef imageBuffer, CMTime presentationTimeStamp, CMTime presentationDuration){ 

    NSLog(@"In decompression callback routine"); 

}

void decodeH264 { 

VTDecodeInfoFlags infoFlags; 
[NALPacket appendBytes: NalPacketSize length:4]; 
        [NALPacket appendBytes: &NALCODE length:1]; 
        [NALPacket appendBytes: startPointer length:buflen]; 
        void *samples = (void *)[NALTestPacket bytes]; 

        blockBuffer = NULL; 

        // add the nal raw data to the CMBlockBuffer 
        status = CMBlockBufferCreateWithMemoryBlock(
                   kCFAllocatorDefault, 
                   samples, 
                   [NALPacket length], 
                   kCFAllocatorDefault, 
                   NULL, 
                   0, 
                   [NALPacket length], 
                   0, 
                   &blockBuffer); 

         const size_t * samplesizeArrayPointer; 
         size_t sampleSizeArray= buflen; 
         samplesizeArrayPointer = &sampleSizeArray; 

         int32_t timeSpan = 1000000; 
         CMTime PTime = CMTimeMake(presentationTime, timeSpan); 
         CMSampleTimingInfo timingInfo; 
         timingInfo.presentationTimeStamp = PTime; 
         timingInfo.duration = kCMTimeZero; 
         timingInfo.decodeTimeStamp = kCMTimeInvalid; 

         status = CMSampleBufferCreate(kCFAllocatorDefault, blockBuffer, YES, NULL, NULL, formatDescription, 1, 1, &timingInfo, 0, samplesizeArrayPointer, &sampleBuffer); 

         CFArrayRef attachmentsArray = CMSampleBufferGetSampleAttachmentsArray(sampleBuffer, true); 
         for (CFIndex i = 0; i < CFArrayGetCount(attachmentsArray); ++i) { 
          CFMutableDictionaryRef attachments = (CFMutableDictionaryRef)CFArrayGetValueAtIndex(attachmentsArray, i); 
          CFDictionarySetValue(attachments, kCMSampleAttachmentKey_DoNotDisplay, kCFBooleanFalse); 
          CFDictionarySetValue(attachments, kCMSampleAttachmentKey_DisplayImmediately, kCFBooleanTrue); 
         } 

// I Frame 
         status = VTDecompressionSessionDecodeFrame(decoder, sampleBuffer, kVTDecodeFrame_1xRealTimePlayback, (void*)CFBridgingRetain(currentTime), &infoFlags); 
         if (status != noErr) { 
          NSLog(@"Decode error"); 
         } 

回答

0

发现为什么这是行不通的,我忘了设定CMSampleBufferRef每一个新的样本被抓获的时间为NULL。

samples = NULL; 

status = CMSampleBufferCreate(kCFAllocatorDefault, blockBuffer, YES, NULL, NULL, formatDescription, 1, 1, &timingInfo, 0, samplesizeArrayPointer, &sampleBuffer); 
+0

请您详细说明一下吗?我从VTDecompressionSessionDecodeFrame()获得相同的返回值,但是我无法从您的评论中判断出您需要做什么来避免此错误返回。谢谢! – rpj 2014-10-14 00:34:54

+0

不幸的是,我不能,这是我的一些尝试和错误。我正在通过网络解码一个比特流,每当我得到一个新的nal单元并在一个采样缓冲区中准备它时,我需要将先前使用的采样缓冲区设置为NULL。有趣的是,我已经停止使用VTDecompressionDecodeFrame,并使用AVSampleBufferDisplayLayer,它在你的应用程序的图层中显示H264的效果很好。 – Md1079 2014-10-14 11:29:19

+0

听起来像你的问题与帧缓冲区的内存管理有关,最终也是我的问题。谢谢你的提示! – rpj 2014-11-20 01:49:42