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 = -; 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硬件解码的更多相关文章
- 树莓派编译安装 FFmpeg(添加 H.264 硬件编解码器支持)
说明 FFmpeg 是一套开源的音视频编解码库,有非常强大的功能,包括视频采集功能.视频格式转换等.众所周知视频编解码是一个非常消耗系统资源的过程,而树莓派自带了 H.264 的硬件编解码器,因此本文 ...
- h.264并行解码算法3D-Wave实现(基于多核共享内存系统)
3D-Wave算法是2D-Wave的扩展.3D-Wave相对于只在帧内并行的2D-Wave来说,多了帧间并行,不用等待前一帧完成解码后才开始下一帧的解码,而是只要宏块的帧间参考部分以及帧内依赖宏块解码 ...
- h.264并行解码算法2D-Wave实现(基于多核共享内存系统)
cache-coherent shared-memory system 我们最平常使用的很多x86.arm芯片都属于多核共享内存系统,这种系统表现为多个核心能直接对同一内存进行读写访问.尽管内存的存取 ...
- h.264并行解码算法2D-Wave实现(基于多核非共享内存系统)
在<Scalable Parallel Programming Applied to H.264/AVC Decoding>书中,作者基于双芯片18核的Cell BE系统实现了2D-Wav ...
- h.264并行解码算法分析
并行算法类型可以分为两类 Function-level Decomposition,按照功能模块进行并行 Data-level Decomposition,按照数据划分进行并行 Function-le ...
- 让dcef3支持mp3和h.264 mp4解码播放
嵌入式Chromium框架(简称CEF) 是一个由Marshall Greenblatt在2008建立的开源项目,它主要目的是开发一个基于Google Chromium的Webbrowser控件.CE ...
- 音视频编解码技术(一):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的出现就是为了创 ...
- Android IOS WebRTC 音视频开发总结(七九)-- WebRTC选择H.264的四大理由
本文主要介绍WebRTC选择H.264的理由(我们翻译和整理的,译者:weizhenwei,校验:blacker),最早发表在[编风网] 支持原创,转载必须注明出处,欢迎关注我的微信公众号blacke ...
- iOS硬解H.264:-VideoToolboxDemo源码分析[草稿]
来源:http://www.cnblogs.com/michaellfx/p/understanding_-VideoToolboxDemo.html iOS硬解H.264:-VideoToolbox ...
随机推荐
- sql中的 SET QUOTED_IDENTIFIER OFF、SET ANSI_NULLS ON
代码 Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-- ...
- 分享一下vue ui的分页的用法
var newToAddLeave = function(){ var goIndex = { template:` <i-table :columns="overTimeList.c ...
- 天意——thinkphp方法名大小写问题
今天星期六,晚一小时上班.早起后背了会单词就骑自行车上班了.我是个有豪车梦的男生,每看到什么保时捷啊,雷克萨斯啊开过都会呆呆的看一会.现在虽然我买不上车,但是我可以靠我自己先买一台帅气的大摩托啊哈哈. ...
- 实现人脸识别性别之路---try语句的使用
Try语句 用法:处理异常信息 存在的形式:try-except X-except T...-except-else-finally(其中X T为错误的类型) 表达意思:try语句是执行正常语句,如果 ...
- wc---计算字数。
Linux wc命令用于计算字数. 利用wc指令我们可以计算文件的Byte数.字数.或是列数,若不指定文件名称.或是所给予的文件名为"-",则wc指令会从标准输入设备读取数据. 语 ...
- 洛谷——P2446 [SDOI2010]大陆争霸
https://www.luogu.org/problem/show?pid=2446#sub 题目背景 在一个遥远的世界里有两个国家:位于大陆西端的杰森国和位于大陆东端的克里斯国.两个国家的人民分别 ...
- 如日中天的Uber到底是用什么开发语言做到的?
Uber将正在蓬勃发展的Go和Node.js这两个语言很好的融合到其系统上面来.Uber的站点可靠性project师Tom Croucher在近期于波兰举行的Node.js互动大会上详尽的对该公司所用 ...
- IOS学习之斯坦福大学IOS开发课程笔记(第六课)
转载请注明出处 http://blog.csdn.net/pony_maggie/article/details/28398697 作者:小马 这节课主要讲述多个MVC是怎样协同工作的.到眼下为止.全 ...
- 洛谷P2818 天使的起誓
题目描述 Tenshi非常幸运地被选为掌管智慧之匙的天使.在正式任职之前,她必须和其他新当选的天使一样要宣誓.宣誓仪式是每位天使各自表述自己的使命,他们的发言稿放在n个呈圆形排列的宝盒中.这些宝盒按顺 ...
- 判断浏览器是否支持某些新属性---placeholder兼容问题解决
function is_true(){ return 'placeholder' in document.createElement('input'); } 实例:placeholder在低版本IE浏 ...