VTDecompressionSessionDecodeFrame ERROR -12916(kVTFormatDescriptionChangeNotSupportedErr)

时间:2015-01-12 15:35:45

标签: ios objective-c h.264

我遇到了一个问题,我无法理解。

首先我创建一个VTCompressionSessionCreate(h264)然后在我的压缩回调中,当我开始提供图像时,我按预期得到CMSampleBufferRef sampleBuffer

只是为了调试代码流,我创建一个VTDecompressionSessionCreate并将包含H264流的'sampleBuffer'提供给VTDecompressionSessionDecodeFrame,我希望在我的解压缩回调中有一个CVImageBufferRef imageBuffer

现在问题:

如果我使用压缩回调中的'sampleBuffer'创建VTDecompressionSessionCreate,如下所示:

CMFormatDescriptionRef format = CMSampleBufferGetFormatDescription(sampleBuffer);

一切都按预期工作,我在解压缩回调中得到CVImageBufferRef's

但我的目的是通过网络发送数据,因此我需要从流式SPS和PPS信息中获取格式说明。

那么我必须'伪造'获取SPS和PPS,首先提取它们然后像这样使用它们:

CMFormatDescriptionRef format = CMSampleBufferGetFormatDescription(sampleBuffer);
size_t spsSize, ppsSize;
size_t parmCount;
const uint8_t* sps, *pps;

CMVideoFormatDescriptionGetH264ParameterSetAtIndex(format, 0, &sps, &spsSize, &parmCount, NULL );
CMVideoFormatDescriptionGetH264ParameterSetAtIndex(format, 1, &pps, &ppsSize, &parmCount, NULL );
const uint8_t* const parameterSetPointers[2] = {sps, pps};
const size_t parameterSetSizes[2] = {spsSize, ppsSize};
CMFormatDescriptionRef format2;
status = CMVideoFormatDescriptionCreateFromH264ParameterSets(kCFAllocatorDefault, 2, parameterSetPointers, parameterSetSizes, 4, &format2);

我希望format和format2包含相同的信息,但是:

format = <CMVideoFormatDescription 0x17004fd50 [0x19483ac80]> {
    mediaType:'vide' 
    mediaSubType:'avc1' 
    mediaSpecific: {
        codecType: 'avc1'       dimensions: 1280 x 720 
    } 
    extensions: {<CFBasicHash 0x170270cc0 [0x19483ac80]>{type = immutable dict, count = 2,
entries =>
    0 : <CFString 0x194935fa0 [0x19483ac80]>{contents = "SampleDescriptionExtensionAtoms"} = <CFBasicHash 0x170270c40 [0x19483ac80]>{type = immutable dict, count = 1,
entries =>
    2 : <CFString 0x194939fa0 [0x19483ac80]>{contents = "avcC"} = <CFData 0x1700c9920 [0x19483ac80]>{length = 35, capacity = 35, bytes = 0x0164001fffe100106764001fac56c050 ... 28ee3cb0fdf8f800}
}

    2 : <CFString 0x194936000 [0x19483ac80]>{contents = "FormatName"} = <CFString 0x17003a160 [0x19483ac80]>{contents = "H.264"}
}
}
}

FORMAT2:

format2 = <CMVideoFormatDescription 0x174051c70 [0x19483ac80]> {
    mediaType:'vide' 
    mediaSubType:'avc1' 
    mediaSpecific: {
        codecType: 'avc1'       dimensions: 1280 x 720 
    } 
    extensions: {<CFBasicHash 0x17426f9c0 [0x19483ac80]>{type = immutable dict, count = 5,
entries =>
    0 : <CFString 0x19499a608 [0x19483ac80]>{contents = "CVImageBufferChromaLocationBottomField"} = <CFString 0x19499a648 [0x19483ac80]>{contents = "Center"}
    1 : <CFString 0x19499a328 [0x19483ac80]>{contents = "CVFieldCount"} = <CFNumber 0xb000000000000012 [0x19483ac80]>{value = +1, type = kCFNumberSInt32Type}
    3 : <CFString 0x194935fa0 [0x19483ac80]>{contents = "SampleDescriptionExtensionAtoms"} = <CFBasicHash 0x17426b100 [0x19483ac80]>{type = immutable dict, count = 1,
entries =>
    2 : <CFString 0x174031560 [0x19483ac80]>{contents = "avcC"} = <CFData 0x1740c4910 [0x19483ac80]>{length = 35, capacity = 35, bytes = 0x0164001fffe100106764001fac56c050 ... 28ee3cb0fdf8f800}
}

    5 : <CFString 0x19499a5e8 [0x19483ac80]>{contents = "CVImageBufferChromaLocationTopField"} = <CFString 0x19499a648 [0x19483ac80]>{contents = "Center"}
    6 : <CFString 0x1949360e0 [0x19483ac80]>{contents = "FullRangeVideo"} = <CFBoolean 0x19483b030 [0x19483ac80]>{value = false}
}
}
}

格式有效 forma2不会和VTDecompressionSessionDecodeFrame抛出错误-12916。

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

解决了它。这是我创建CMFormatDescriptionRef的方式,其中包含导致错误的代码流。

SPS和PPS取自CFSampleBuffer。然后我创建了一个CMVideoFormatDescriptionCreateFromH264ParameterSets到目前为止一切顺利。但在同一个应用程序中,我转过流并使用相同的CFSampleBuffer解码图片。这不起作用,导致错误。我必须首先将有效负载转换为NSData,然后从NSData创建一个新的CFSampleBuffer。然后它工作