zoukankan      html  css  js  c++  java
  • h.264硬件解码

    //  H264HWDecoder.m
    //  H264EncoderDecoder
    //
    //  Created by lujunjie on 2016/11/28.
    //  Copyright © 2016年 陆俊杰. All rights reserved.
    //
    
    #import "H264HWDecoder.h"
    
    @implementation H264HWDecoder
    
    - (void)dealloc
    {
        if(self.decompressionSession != NULL){
            VTDecompressionSessionInvalidate(self.decompressionSession);
            CFRelease(self.decompressionSession);
            self.decompressionSession=NULL;
        }
    }
    - (int)DecodeH264Frames:(unsigned char *)frame withLength:(int)frameSize
    {
        OSStatus status = -1;
        
        uint8_t *data = NULL;
        uint8_t *pps = NULL;
        uint8_t *sps = NULL;
        
        int startCodeIndex = 0;
        int secondStartCodeIndex = 0;
        int thirdStartCodeIndex = 0;
        
        long blockLength = 0;
        
        CMSampleBufferRef sampleBuffer = NULL;
        CMBlockBufferRef blockBuffer = NULL;
        
        int nalu_type = (frame[startCodeIndex + 4] & 0x1F);
        
        if (nalu_type != 7 && _formatDesc == NULL)
        {
            NSLog(@"Video error: Frame is not an I Frame and format description is null");
            return -1;
        }
       
        
        if (nalu_type == 7)
        {
    //        NSLog(@"=================================================");
    //        for (int i = 0; i<frameSize; i++) {
    //            printf(" %x",frame[i]);
    //        }
            for (int i = startCodeIndex + 4; i < startCodeIndex + 256; i++)
            {
                if (frame[i] == 0x00 && frame[i+1] == 0x00 && frame[i+2] == 0x00 && frame[i+3] == 0x01)
                {
                    secondStartCodeIndex = i;
                    _spsSize = secondStartCodeIndex;
                    break;
                }
            }
            nalu_type = (frame[secondStartCodeIndex + 4] & 0x1F);
            
        }
        
        if(nalu_type == 8)
        {
            
            for (int i = _spsSize + 4; i < _spsSize + 128; i++)
            {
                if (frame[i] == 0x00 && frame[i+1] == 0x00 && frame[i+2] == 0x00 && frame[i+3] == 0x01)
                {
                    thirdStartCodeIndex = i;
                    _ppsSize = thirdStartCodeIndex - _spsSize;
                    break;
                }
            }
            
            
            sps = malloc(_spsSize - 4);
            pps = malloc(_ppsSize - 4);
            
            memcpy (sps, &frame[4], _spsSize-4);
            memcpy (pps, &frame[_spsSize+4], _ppsSize-4);
            
            
            uint8_t*  parameterSetPointers[2] = {sps, pps};
            size_t parameterSetSizes[2] = {_spsSize-4, _ppsSize-4};
            
            status = CMVideoFormatDescriptionCreateFromH264ParameterSets(kCFAllocatorDefault, 2,
                                                                         (const uint8_t *const*)parameterSetPointers,
                                                                         parameterSetSizes, 4,
                                                                         &_formatDesc);
            
            if(status != noErr){
                NSLog(@"MVideoFormatDescriptionCreateFromH264ParameterSets ERROR type: %d", (int)status);
            }
            
            
            
            nalu_type = (frame[thirdStartCodeIndex + 4] & 0x1F);
        }
        
        if(nalu_type == 5 )
        {
            
            int offset = _spsSize + _ppsSize;
            blockLength = frameSize - offset;
            data = malloc(blockLength);
            data = memcpy(data, &frame[offset], blockLength);
            
            uint32_t dataLength32 = htonl (blockLength - 4);
            memcpy (data, &dataLength32, sizeof (uint32_t));
            
            
            status = CMBlockBufferCreateWithMemoryBlock(NULL, data,
                                                        blockLength,
                                                        kCFAllocatorNull, NULL,
                                                        0,
                                                        blockLength,
                                                        0, &blockBuffer);
            if(status != noErr){
                NSLog(@"I Frame: CMBlockBufferCreateWithMemoryBlock Error type: %d", (int)status);
            }
            
        }
        
        
        if (nalu_type == 1)
        {
            
            blockLength = frameSize;
            data = malloc(blockLength);
            data = memcpy(data, &frame[0], blockLength);
            
            uint32_t dataLength32 = htonl (blockLength - 4);
            memcpy (data, &dataLength32, sizeof (uint32_t));
            
            status = CMBlockBufferCreateWithMemoryBlock(NULL, data,
                                                        blockLength,
                                                        kCFAllocatorNull, NULL,
                                                        0,
                                                        blockLength,
                                                        0, &blockBuffer);
            if(status != noErr){
                NSLog(@"P Frame: CMBlockBufferCreateWithMemoryBlock Error type: %d", (int)status);
            }
            
        }
        
        if(status == noErr)
        {
            const size_t sampleSize = blockLength;
            status = CMSampleBufferCreate(kCFAllocatorDefault,
                                          blockBuffer, true, NULL, NULL,
                                          _formatDesc, 1, 0, NULL, 1,
                                          &sampleSize, &sampleBuffer);
            if(status != noErr){
                NSLog(@"CMSampleBufferCreate Error type: %d", (int)status);
            }
            
        }
        
        if(status == noErr)
        {
            
            CFArrayRef attachments = CMSampleBufferGetSampleAttachmentsArray(sampleBuffer, YES);
            CFMutableDictionaryRef dict = (CFMutableDictionaryRef)CFArrayGetValueAtIndex(attachments, 0);
            CFDictionarySetValue(dict, kCMSampleAttachmentKey_DisplayImmediately, kCFBooleanTrue);
            
            if([self.updateDelegate respondsToSelector:@selector(updateDecodedSampleBuffer:)]){
                [self.updateDelegate updateDecodedSampleBuffer:sampleBuffer];
                
                
            }
            
        }
        
        if (data != NULL)
        {
            free (data);
            data = NULL;
        }
        if(sps != NULL)
        {
            free(sps);
            sps = NULL;
        }
        if(pps != NULL)
        {
            free(pps);
            pps = NULL;
        }
        
        
        return 0;
    }
    @end
  • 相关阅读:
    CSS布局设计
    Gulp自动化构建工具的简单使用
    雅虎前端优化的35条军规
    CSS预编译器less简单用法
    java 数据相除
    idea 配置文件中文显示问题
    postgresql 表触发器
    postgresql 自定义函数
    postgresql 自定义聚合函数
    CentOS 6.5 yum安装mysql5.6或其他版本【默认yum只能安装mysql 5.1】 by jason
  • 原文地址:https://www.cnblogs.com/-ljj/p/6373838.html
Copyright © 2011-2022 走看看