IOS硬解码流程笔记

IOS硬解码:

流程步骤:

1初始化:CMVideoFormatDescriptionCreateFromH264ParameterSets

注意SPSPPS不要携带冗余,携带冗余可能导致无法某些手机无法正常解码

  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

设置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);

输入的解码数据转换成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);

回调函数中拿YUV

CVPixelBufferLockBaseAddress(pixbuf, kCVPixelBufferLock_ReadOnly) 

YUV处理

CVPixelBufferUnlockBaseAddress(pixbuf, kCVPixelBufferLock_ReadOnly);

posted on 2023-03-15 12:51  邗影  阅读(201)  评论(0)    收藏  举报

导航