//  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 = -; uint8_t *data = NULL;
uint8_t *pps = NULL;
uint8_t *sps = NULL; int startCodeIndex = ;
int secondStartCodeIndex = ;
int thirdStartCodeIndex = ; long blockLength = ; CMSampleBufferRef sampleBuffer = NULL;
CMBlockBufferRef blockBuffer = NULL; int nalu_type = (frame[startCodeIndex + ] & 0x1F); if (nalu_type != && _formatDesc == NULL)
{
NSLog(@"Video error: Frame is not an I Frame and format description is null");
return -;
} if (nalu_type == )
{
// NSLog(@"=================================================");
// for (int i = 0; i<frameSize; i++) {
// printf(" %x",frame[i]);
// }
for (int i = startCodeIndex + ; i < startCodeIndex + ; i++)
{
if (frame[i] == 0x00 && frame[i+] == 0x00 && frame[i+] == 0x00 && frame[i+] == 0x01)
{
secondStartCodeIndex = i;
_spsSize = secondStartCodeIndex;
break;
}
}
nalu_type = (frame[secondStartCodeIndex + ] & 0x1F); } if(nalu_type == )
{ for (int i = _spsSize + ; i < _spsSize + ; i++)
{
if (frame[i] == 0x00 && frame[i+] == 0x00 && frame[i+] == 0x00 && frame[i+] == 0x01)
{
thirdStartCodeIndex = i;
_ppsSize = thirdStartCodeIndex - _spsSize;
break;
}
} sps = malloc(_spsSize - );
pps = malloc(_ppsSize - ); memcpy (sps, &frame[], _spsSize-);
memcpy (pps, &frame[_spsSize+], _ppsSize-); uint8_t* parameterSetPointers[] = {sps, pps};
size_t parameterSetSizes[] = {_spsSize-, _ppsSize-}; status = CMVideoFormatDescriptionCreateFromH264ParameterSets(kCFAllocatorDefault, ,
(const uint8_t *const*)parameterSetPointers,
parameterSetSizes, ,
&_formatDesc); if(status != noErr){
NSLog(@"MVideoFormatDescriptionCreateFromH264ParameterSets ERROR type: %d", (int)status);
} nalu_type = (frame[thirdStartCodeIndex + ] & 0x1F);
} if(nalu_type == )
{ int offset = _spsSize + _ppsSize;
blockLength = frameSize - offset;
data = malloc(blockLength);
data = memcpy(data, &frame[offset], blockLength); uint32_t dataLength32 = htonl (blockLength - );
memcpy (data, &dataLength32, sizeof (uint32_t)); status = CMBlockBufferCreateWithMemoryBlock(NULL, data,
blockLength,
kCFAllocatorNull, NULL,
,
blockLength,
, &blockBuffer);
if(status != noErr){
NSLog(@"I Frame: CMBlockBufferCreateWithMemoryBlock Error type: %d", (int)status);
} } if (nalu_type == )
{ blockLength = frameSize;
data = malloc(blockLength);
data = memcpy(data, &frame[], blockLength); uint32_t dataLength32 = htonl (blockLength - );
memcpy (data, &dataLength32, sizeof (uint32_t)); status = CMBlockBufferCreateWithMemoryBlock(NULL, data,
blockLength,
kCFAllocatorNull, NULL,
,
blockLength,
, &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, , , NULL, ,
&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, );
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 ;
}
@end

h.264硬件解码的更多相关文章

  1. 树莓派编译安装 FFmpeg(添加 H.264 硬件编解码器支持)

    说明 FFmpeg 是一套开源的音视频编解码库,有非常强大的功能,包括视频采集功能.视频格式转换等.众所周知视频编解码是一个非常消耗系统资源的过程,而树莓派自带了 H.264 的硬件编解码器,因此本文 ...

  2. h.264并行解码算法3D-Wave实现(基于多核共享内存系统)

    3D-Wave算法是2D-Wave的扩展.3D-Wave相对于只在帧内并行的2D-Wave来说,多了帧间并行,不用等待前一帧完成解码后才开始下一帧的解码,而是只要宏块的帧间参考部分以及帧内依赖宏块解码 ...

  3. h.264并行解码算法2D-Wave实现(基于多核共享内存系统)

    cache-coherent shared-memory system 我们最平常使用的很多x86.arm芯片都属于多核共享内存系统,这种系统表现为多个核心能直接对同一内存进行读写访问.尽管内存的存取 ...

  4. h.264并行解码算法2D-Wave实现(基于多核非共享内存系统)

    在<Scalable Parallel Programming Applied to H.264/AVC Decoding>书中,作者基于双芯片18核的Cell BE系统实现了2D-Wav ...

  5. h.264并行解码算法分析

    并行算法类型可以分为两类 Function-level Decomposition,按照功能模块进行并行 Data-level Decomposition,按照数据划分进行并行 Function-le ...

  6. 让dcef3支持mp3和h.264 mp4解码播放

    嵌入式Chromium框架(简称CEF) 是一个由Marshall Greenblatt在2008建立的开源项目,它主要目的是开发一个基于Google Chromium的Webbrowser控件.CE ...

  7. 音视频编解码技术(一):MPEG-4/H.264 AVC 编解码标准

    一.H264 概述 H.264,通常也被称之为H.264/AVC(或者H.264/MPEG-4 AVC或MPEG-4/H.264 AVC) 1. H.264视频编解码的意义 H.264的出现就是为了创 ...

  8. Android IOS WebRTC 音视频开发总结(七九)-- WebRTC选择H.264的四大理由

    本文主要介绍WebRTC选择H.264的理由(我们翻译和整理的,译者:weizhenwei,校验:blacker),最早发表在[编风网] 支持原创,转载必须注明出处,欢迎关注我的微信公众号blacke ...

  9. iOS硬解H.264:-VideoToolboxDemo源码分析[草稿]

    来源:http://www.cnblogs.com/michaellfx/p/understanding_-VideoToolboxDemo.html iOS硬解H.264:-VideoToolbox ...

随机推荐

  1. 在Windows上如何安装和彻底卸载Adobe Flash Player教程

    很多小伙伴在安装水晶易表的时候,经常会遇到“Xcelsius2008需要使用Adobe Flash Player(9.151或者更高版本)”报错问题,如下图所示. 导致安装进程受阻,此时就需要安装高版 ...

  2. ping 原理及ICMP协议简介

    //Ping IP/域名 public static String pingIPCennect(String ipStr) {  String result = "";  if ( ...

  3. Centos6.5 安装lnmp环境

    最近项目要配置在nginx上,所以搜索了下具体nginx的安装,看到这篇文章简洁明了而且测试成功就借用了,作品出处:http://www.cnblogs.com/xiaoit/p/3991037.ht ...

  4. iOS基本UI控件总结

    包括以下几类: //继承自NSObject:(暂列为控件) UIColor *_color;    //颜色 UIImage *_image;    //图像 //继承自UIView:只能相应手势UI ...

  5. 一个project师该怎样高效工作

    1.  静. 在千头万绪,百般push.各种IM电话邮件狂轰滥炸中保持一个静字.找到最适合如今做的事情,情绪不要被外界所干扰.一次仅仅做一件事,不要被打断. 有的公司土鳖文化严重,领导一会儿要求你干这 ...

  6. openfire 开发遇到的些问题

    openfire的 jid    账户名 + '@" + 你的域名      可是当你的账户名中 有大拼音的 时候  就会变成小写   比如     Test  ,  jid  =  tes ...

  7. spring 使用c3po连接池

    1 数据源:能够简单理解为数据的来源. 2 连接池:是缓存一定数量的数据库连接,当程序须要数据库连接的时候,直接在连接池中获取空暇的连接,使用完再放回连接池中,此连接又变成空暇状态,等待下一次连接. ...

  8. localtime死锁——多线程下fork子进程

    近期測试我们自己改进的redis,发如今做rdb时,子进程会一直hang住.gdb attach上.堆栈例如以下: (gdb) bt #0 0x0000003f6d4f805e in __lll_lo ...

  9. Docs-->.NET-->API reference-->System.​Web.​UI.​Web​Controls-->Repeater

    https://docs.microsoft.com/en-us/dotnet/api/system.web.ui.webcontrols.repeater?view=netframework-4.7 ...

  10. zoj 1119 / poj 1523 SPF (典型例题 求割点 Tarjan 算法)

    poj : http://poj.org/problem?id=1523 如果无向图中一个点 u 为割点 则u 或者是具有两个及以上子女的深度优先生成树的根,或者虽然不是一个根,但是它有一个子女 w, ...