IOS硬解码流程笔记
IOS硬解码:
流程步骤:
1初始化:CMVideoFormatDescriptionCreateFromH264ParameterSets
注意SPS。PPS不要携带冗余,携带冗余可能导致无法某些手机无法正常解码
|
size_t ParameterSetSizes[2] = {(size_t)FrameInfo->nSpsLen, (size_t)FrameInfo->nPpsLen};
const uint8_t* const ParameterSetPointers[2] = {( uint8_t*)FrameInfo->pSpsStart, ( uint8_t*)FrameInfo->pPpsStart};
CMVideoFormatDescriptionCreateFromH264ParameterSets(NULL, 2, ParameterSetPointers, ParameterSetSizes, 4, &FormatDesc); |
|
size_t ParameterSetSizes[3] = {(size_t)FrameInfo->nVpsLen, (size_t)FrameInfo->nSpsLen, (size_t)FrameInfo->nPpsLen};
uint8_t* const nParameterSetPointers[3] = {(const uint8_t*)FrameInfo->pVpsStart, (const uint8_t*)FrameInfo->pSpsStart, (const uint8_t*)FrameInfo->pPpsStart};
#ifdef __IPHONE_11_0 if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 11.0) { nStatus = CMVideoFormatDescriptionCreateFromHEVCParameterSets(NULL, 3, ParameterSetPointers, ParameterSetSizes, 4, NULL, &FormatDesc); } #endif |
2 设置pixelbuffer属性
CFMutableDictionaryRef PixelBufferAttributes =
CFDictionaryCreateMutable(NULL,0,&kCFTypeDictionaryKeyCallBacks,&kCFTypeDictionaryValueCallBacks);
3设置解码参数:这里设置的宽高可以让硬解码按照你设置的分辨率解码。
|
SInt32 nPixelType = kCVPixelFormatType_420YpCbCr8BiPlanarFullRange; CFDictionarySetValue(PixelBufferAttributes, kCVPixelBufferPixelFormatTypeKey, CFNumberCreate(NULL, kCFNumberSInt32Type, &PixelType)); CFDictionarySetValue(PixelBufferAttributes, kCVPixelBufferWidthKey, CFNumberCreate(NULL, kCFNumberSInt32Type, &Width)); CFDictionarySetValue(PixelBufferAttributes, kCVPixelBufferHeightKey, CFNumberCreate(NULL, kCFNumberSInt32Type, &Height)); CFMutableDictionaryRef pDecoderParameters = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); |
4设置解码回调(异步的时候需要设置,同步的时候不需要设置)
|
const VTDecompressionOutputCallbackRecord stCallBack = {HWDecompressionOutputCallback, this}; nStatus = VTDecompressionSessionCreate(NULL, FormatDesc, NULL, PixelBufferAttributes, &stCallBack, &DecSession); |
5 初始化结束后进行属性的释放
|
CFRelease(PixelBufferAttributes); CFRelease(DecParameters); |
6 输入的解码数据转换成CMBlockBufferRef
|
CMBlockBufferCreateWithMemoryBlock(NULL, Data, Len, kCFAllocatorNull, NULL, 0, Len, 0, &BlockBufferRefobj); |
7 blockbuf转成CMSampleBufferRef
|
CMSampleBufferCreate(NULL, BlockBufferRefobj, true, 0, 0, FormatDesc, 1, 0, NULL, 0, NULL, &SampleBufferRef); |
8 硬解码;之后释放samplebufref 和 blockbufferref
|
VTDecompressionSessionDecodeFrame(DecSession, SampleBufferRef, 0, pDecodeInfo, 0); |
9 回调函数中拿YUV
|
CVPixelBufferLockBaseAddress(pixbuf, kCVPixelBufferLock_ReadOnly) YUV处理 CVPixelBufferUnlockBaseAddress(pixbuf, kCVPixelBufferLock_ReadOnly); |
浙公网安备 33010602011771号