调用方法:

static  CPSPackager * testObjc = NULL;

static char *pszBuffer;

testObjc = new CPSPackager();

pszBuffer = new char[1024*1024];

-(NSData *)EncodeDataChangeToPSWithData:(NSData *)encodeData andType:(int)type{

int size = (int)[encodeData length];

int iCount = 0;

char * encodeCharData = (char *)[encodeData bytes];

switch (type) {

case 1:{

testObjc->Packet_I_frame(encodeCharData, size, pszBuffer, iCount, 25);

}

break;

case 2:{

testObjc->Packet_P_frame(encodeCharData, size, pszBuffer, iCount);

}

break;

case 3:{

testObjc->Packet_Audio_frame(encodeCharData, size, pszBuffer,iCount,true);

}

break;

default:

break;

}

NSData *   PsData = [NSData dataWithBytes:pszBuffer length:iCount];

return PsData;

}

下面是.h文件

#pragma once

#define PS_Packet_Start_Code_Len       4

#define PS_Header_Len                  14      //≤ªøº¬«◊÷Ω⁄∂‘∆ÎPS_Header

#define PS_Header_Len_aligned          20      //øº¬«◊÷Ω⁄∂‘∆Μ¬µƒPS_Header

#define MAX_PSBUFFER_SIZE 5106

#define MUX_RATE 0

#define FRAME_BUFFER_MAX    1024*1024*2 // µ•∏ˆH264÷°µƒ◊Ó¥Û≥§∂»

//∑Ω∑®

#define OFFSET(x) (90000/x)

//¥ÌŒÛ∑µªÿ

#define  PS_Error_OK              0

#define  PS_Error_Param          -1

#define  PS_Error_Stream         -2

#define  PS_Error_Format         -3

#define  PS_Error_H264           -4

#define  PS_Error_Pes_Len        -5

#if (defined(WIN32))

#define CALLBACK  __stdcall

#else

#define CALLBACK

#endif

typedef void (CALLBACK * PSOutputCallBack)(char *pData, int size, unsigned long user);

class CFrameBuffer {

public:

CFrameBuffer() {

size = 0;

pBuffer = new char[FRAME_BUFFER_MAX];

pPSBuffer = new char[FRAME_BUFFER_MAX];

};

~CFrameBuffer() {

delete pBuffer;

delete pPSBuffer;

};

char *pBuffer;

char *pPSBuffer;

int size;

};

class CPSPackager {

public:

CPSPackager(void);

~CPSPackager(void);

bool create(PSOutputCallBack callback, unsigned long user);

void destroy();

PSOutputCallBack m_pFuncOutputCallBack;

unsigned long m_pUser;

public:

unsigned int m_nScrb;

unsigned int m_nDts;

unsigned int m_nVideoPts;

int m_nFrameRate;

bool m_bStarted;

CFrameBuffer m_buffer;

bool m_bFindFirstIFrame;

int Packet_I_frame(const char* pSrcBuf, int nSrcLen, char* pDestBuf, int& nDestLen, int nFrameRate);

int Packet_P_frame(const char* pSrcBuf, int nSrcLen, char* pDestBuf, int& nDestLen, bool addPSHeader = true);

int Packet_Audio_frame(const char* pSrcBuf, int nSrcLen, char* pDestBuf, int& nDestLen, bool addPSHeader = true);

int Packet_PS_header(char* pDestBuf, int& nLen, bool bAudio, bool bAligned = false);

int Packet_PS_map(char* pDestBuf, int& nLen);

int Packet_frame(const char* pSrcBuf , int nSrcLen , bool isVideo, char* pDestBuf, int& nLen);

int GeneratePacketsFromFrame(const char* pSrcBuf , int nSrcLen, bool isVideo , char* pDestBuf , int& nLen);

};

这里是cpp文件

#include "PSPackager.h"

#include "string.h"

#include <algorithm>

using namespace std;

static unsigned char DH_IDENTITY[4] = {0x64, 0x68, 0x61, 0x76};

static unsigned char H264_IDENTITY[4] = {0x00, 0x00, 0x00, 0x01};

static unsigned char H264_IDENTITY_IDR[5] = {0x00, 0x00, 0x00, 0x01, 0x67};

static unsigned char PS_header[PS_Packet_Start_Code_Len] = {0x00 , 0x00 , 0x01 , 0xBA};

// static unsigned char PS_System_Header[PS_Packet_Start_Code_Len] = {0x00 , 0x00 , 0x01 , 0xBB};

static unsigned char PS_Map_Header[PS_Packet_Start_Code_Len] = {0x00 , 0x00 , 0x01 , 0xBC};

static unsigned char PS_Audio_Pes_Header[PS_Packet_Start_Code_Len] = {0x00 , 0x00 , 0x01 , 0xC0};

static unsigned char PS_Video_Pes_Header[PS_Packet_Start_Code_Len] = {0x00 , 0x00 , 0x01 , 0xE0};

CPSPackager::CPSPackager(void) {

m_nScrb = 60000;

m_nDts = 0;

m_nVideoPts = 60000;

m_nFrameRate = 25;

m_bStarted = false;

m_bFindFirstIFrame = false;

m_pFuncOutputCallBack = NULL;

m_pUser = NULL;

}

CPSPackager::~CPSPackager(void) {

destroy();

}

bool CPSPackager::create(PSOutputCallBack callback, unsigned long user) {

if (callback == NULL)

return false;

m_pFuncOutputCallBack = callback;

m_pUser = user;

return false;

}

void CPSPackager::destroy() {

m_pFuncOutputCallBack = NULL;

m_pUser = NULL;

}

int CPSPackager::Packet_I_frame(const char* pSrcBuf, int nSrcLen, char* pDestBuf, int& nDestLen, int nFrameRate) {

if (NULL == pSrcBuf || NULL == pDestBuf)

return PS_Error_Param;

int nTempLen = 0;

int nTotalLen = 0;

if (m_nFrameRate != nFrameRate)

m_nFrameRate = nFrameRate ;

Packet_PS_header(pDestBuf, nTempLen, true, true);

nTotalLen += nTempLen;

Packet_PS_map(pDestBuf+nTotalLen, nTempLen);

nTotalLen += nTempLen;

GeneratePacketsFromFrame(pSrcBuf, nSrcLen, true, pDestBuf+nTotalLen, nTempLen);

nTotalLen += nTempLen;

nDestLen = nTotalLen;

return PS_Error_OK;

}

int CPSPackager::Packet_P_frame(const char* pSrcBuf , int nSrcLen, char* pDestBuf , int& nDestLen, bool addPSHeader) {

if ( NULL == pSrcBuf || NULL == pDestBuf )

return PS_Error_Param;

int nTempLen = 0;

int nTotalLen = 0;

if (addPSHeader) {

Packet_PS_header(pDestBuf , nTempLen , true, true);

nTotalLen += nTempLen;

}

GeneratePacketsFromFrame(pSrcBuf , nSrcLen , true, pDestBuf + nTotalLen , nTempLen);

nTotalLen += nTempLen;

nDestLen = nTotalLen;

return PS_Error_OK ;

}

int CPSPackager::Packet_Audio_frame(const char* pSrcBuf , int nSrcLen, char* pDestBuf , int& nDestLen, bool addPSHeader) {

if ( NULL == pSrcBuf || NULL == pDestBuf )

return PS_Error_Param;

int nTempLen = 0;

int nTotalLen = 0;

if (addPSHeader) {

Packet_PS_header(pDestBuf , nTempLen , true, true);

nTotalLen += nTempLen;

}

GeneratePacketsFromFrame(pSrcBuf , nSrcLen , false, pDestBuf + nTotalLen , nTempLen);

nTotalLen += nTempLen;

nDestLen = nTotalLen;

return PS_Error_OK ;

}

int CPSPackager::Packet_PS_header(char* pDestBuf, int& nLen , bool bVideo, bool bAligned /* = false */) {

if ( NULL == pDestBuf)

return PS_Error_Param;

char temp = 0x00;

memcpy( pDestBuf, PS_header , PS_Packet_Start_Code_Len);

if (bVideo)

m_nScrb = m_nVideoPts;

pDestBuf[4]=((0x38&(m_nScrb>>26))|0x44);

pDestBuf[4]=(pDestBuf[4]|((m_nScrb>>28)&0x03));

pDestBuf[5]=((m_nScrb>>20)&(0xFF));

temp = ((m_nScrb>>12)&(0xF8));

pDestBuf[6]=(temp|0x04|((m_nScrb>>13)&0x03));

pDestBuf[7]=((m_nScrb>>5)&(0xFF));

temp=((((m_nScrb&0x1f)<<3)&0xf8)|0x04);

//system_clock_reference_extension …ËŒ™0  9∏ˆbit∂º÷√ŒªŒ™0

pDestBuf[8]=(temp|0x03);

pDestBuf[9]=0x01;

pDestBuf[10]=(MUX_RATE>>14)&0xff;

pDestBuf[11]=(MUX_RATE>>6)&0xff;

pDestBuf[12]=(((MUX_RATE<<2)&0xfc)|0x03);

if ( !bAligned ) {

pDestBuf[13] = 0xF8;

nLen = PS_Header_Len;

} else {

pDestBuf[13] = 0xFE;

pDestBuf[14] = 0xFF;

pDestBuf[15] = 0xFF;

pDestBuf[16] = 0x00;

pDestBuf[17] = 0x00;

pDestBuf[18] = 0x00;

pDestBuf[19] = 0x00;

nLen = PS_Header_Len_aligned;

}

return PS_Error_OK;

}

int CPSPackager::Packet_PS_map(char* pDestBuf, int& nLen) {

if ( NULL == pDestBuf)

return PS_Error_Param;

memcpy( pDestBuf, PS_Map_Header , PS_Packet_Start_Code_Len);

pDestBuf[4] = 0x00;

pDestBuf[5] = 0x18;

pDestBuf[6] = 0xE1;

pDestBuf[7] = 0xFF;

pDestBuf[8] = 0x00;

pDestBuf[9] = 0x00;

pDestBuf[10] = 0x00;

pDestBuf[11] = 0x08;

//element_info

pDestBuf[12] = 0x1B;   //H.264

pDestBuf[13] = 0xE0;

pDestBuf[14] = 0x00;

pDestBuf[15] = 0x06;

//avc timming and hrd descriptor

pDestBuf[16] = 0x0a;

pDestBuf[17] = 0x04;

pDestBuf[18] = 0x65;

pDestBuf[19] = 0x6e;

pDestBuf[20] = 0x67;

pDestBuf[21] = 0x00;

pDestBuf[22] = 0x90;

pDestBuf[23] = 0xc0;

pDestBuf[24] = 0x00;

pDestBuf[25] = 0x00;

pDestBuf[26] = 0x00;

pDestBuf[27] = 0x00;

pDestBuf[28] = 0x00;

pDestBuf[29] = 0x00;

nLen = 30;

return PS_Error_OK;

}

int CPSPackager::Packet_frame(const char* pSrcBuf, int nSrcLen, bool isVideo, char* pDestBuf, int& nLen) {

if ( NULL == pSrcBuf || NULL == pDestBuf )

return PS_Error_Param;

int nTempLen = 0;

bool bIncreasePTS = false;

if (pSrcBuf[0] == 0x00 &&

pSrcBuf[1] == 0x00 &&

pSrcBuf[2] == 0x00 &&

pSrcBuf[3] == 0x01) {

unsigned char c5=pSrcBuf[4];

unsigned char c6=pSrcBuf[5];

if (((c5 & 0x1F) == 8) || ((c5 & 0x1F) == 5) || (c6 == 0x88 && (c5 & 0x1F) == 1))

bIncreasePTS = false;

else

bIncreasePTS = true;

}

if (isVideo)

memcpy( pDestBuf , PS_Video_Pes_Header , PS_Packet_Start_Code_Len);

else

memcpy( pDestBuf , PS_Audio_Pes_Header , PS_Packet_Start_Code_Len);

nTempLen = 8 + nSrcLen;

//PES∞¸µƒ≥§∂»

pDestBuf[4] = (nTempLen >> 8) & 0xFF;

pDestBuf[5] = nTempLen & 0xFF;

pDestBuf[6] = 0x88;

pDestBuf[8] = 0x05;

if (bIncreasePTS) {

m_nVideoPts += OFFSET(m_nFrameRate);

//PTS_DTS_flag = '10';

pDestBuf[7] = 0x80;

pDestBuf[9] = ((m_nVideoPts>>29)|0x21);

pDestBuf[10] = (m_nVideoPts>>22);

pDestBuf[11] = ((m_nVideoPts>>14)|0x01);

pDestBuf[12] = (m_nVideoPts>>7);

pDestBuf[13] = (((m_nVideoPts<<1)&0xFE)|0x01);

} else {

//PTS_DTS_flag = '00';

pDestBuf[7] = 0x00;

pDestBuf[9]  = 0xFF;

pDestBuf[10] = 0xFF;

pDestBuf[11] = 0xFF;

pDestBuf[12] = 0xFF;

pDestBuf[13] = 0xFE;

}

nTempLen = 14 ;

memcpy(pDestBuf + nTempLen , pSrcBuf , nSrcLen);

nLen = nTempLen + nSrcLen;

return PS_Error_OK;

}

int CPSPackager::GeneratePacketsFromFrame(const char* pSrcBuf, int nSrcLen, bool isVideo, char* pDestBuf, int& nLen) {

int nTotalLen = 0;

int nPacketNalLen = 0;

int rest_len = nSrcLen;

int nNalCount = 0;

int nOldIndex = 0;

int nPacketCount = 0;

while( nSrcLen - nOldIndex > MAX_PSBUFFER_SIZE) {

Packet_frame(pSrcBuf + nOldIndex , MAX_PSBUFFER_SIZE , isVideo, pDestBuf + nTotalLen , nPacketNalLen );

nOldIndex += MAX_PSBUFFER_SIZE;

nTotalLen += nPacketNalLen;

nPacketCount++;

}

Packet_frame(pSrcBuf + nOldIndex , nSrcLen - nOldIndex , isVideo, pDestBuf + nTotalLen , nPacketNalLen);

nTotalLen += nPacketNalLen;

nPacketCount++;

nLen = nTotalLen;

return PS_Error_OK;

}

iOS 将视频流(h264)和音频流封装成PS流的更多相关文章

  1. H264编码 封装成MP4格式 视频流 RTP封包

    H264编码 封装成MP4格式 视频流 RTP封包         分类:             多媒体编程              2013-02-20 21:31     3067人阅读    ...

  2. 通过摄像机视频设备或者流媒体服务器SDK获取到数据转换成RTMP流实现网页/手机微信播放

    写这篇博客主要是为了给新入门的流媒体开发者解惑,现在看到各种开发者的需求:网页播放RTSP摄像机.微信播放RTSP摄像机.网页播放摄像机SDK输出的视频流.网页播放第三方流媒体平台输出的视频流.包括G ...

  3. 使用Cordova框架把Webapp封装成Hybrid App实践——Android篇

    公司没有IOS和没有安卓开发人员,前端后端都是需要自己玩前几天技术经理说有一个需求要把webapp封装成Hybrid App,现已完成.记录一下从中遇到的问题和需要用到的开发环境的配置 将Webapp ...

  4. .NET 同步与异步之封装成Task(五)

    本随笔续接:.NET 实现并行的几种方式(四) 前篇随笔已经介绍了几种可以实现并发的方式,其中异步方法.是最简便的方式.而 异步方式是基于 Task 和 async修饰符和await运算符实现的. 换 ...

  5. 将HTML5封装成android应用APK文件的几种方法

    越来越多的开发者热衷于使用html5+JavaScript开发移动Web App.不过,HTML5 Web APP的出现能否在未来取代移动应用,就目前来说,还是个未知数.一方面,用户在使用习惯上,不喜 ...

  6. 将HTML5封装成android应用APK文件的几种方法(转载)

    越来越多的开发者热衷于使用html5+JavaScript开发移动Web App.不过,HTML5 Web APP的出现能否在未来取代移动应用,就目前来说,还是个未知数.一方面,用户在使用习惯上,不喜 ...

  7. 如何将Js代码封装成Jquery插件

    很多相同的Jquery代码会在很多页面使用,每次都复制粘贴太麻烦了,不如封装成一个Jquery插件就方便了,至于影响网页的速度不,我就没有测试了哈. 代码如下 这是一个自定闪烁打印文字的Jquery特 ...

  8. 将Python脚本封装成exe可执行文件 转

    将Python脚本封装成exe可执行文件 http://www.cnblogs.com/renzo/archive/2012/01/01/2309260.html  cx_freeze是用来将 Pyt ...

  9. Asp.net Core中使用NLog,并封装成公共的日志方法

    1.安装NLog "NLog.Extensions.Logging": "1.0.0-rtm-alpha4" 2.配置NLog public void Conf ...

随机推荐

  1. JavaScript 的使用基础总结②DOM

    HTML DOM 通过 HTML DOM,可访问 JavaScript HTML 文档的所有元素. 当网页被加载时,浏览器会创建页面的文档对象模型(Document Object Model). HT ...

  2. 201521123097《Java程序设计》第四周学习总结

    1. 本周学习总结 1.1 尝试使用思维导图总结有关继承的知识点. 1.2 使用常规方法总结其他上课内容. 在本周的学习中,我知道了在类的定义里,还学习到了抽象类以及抽象方法的使用格式. 2. 书面作 ...

  3. 201521123114《Java程序设计》第1周学习总结

    1. 本周学习总结 java语言具有:简约且简单,平台无关性,面向对象,多线程.分布性.高性能.健壮性等特点. 2. 书面作业 1.为什么java程序可以跨平台运行?执行java程序的步骤是什么? J ...

  4. 201521123100《Java程序设计》 第10周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常与多线程相关内容. A: 2. 书面作业 本次PTA作业题集异常.多线程 1.finally 题目4-2 1.1 截图你的提交结 ...

  5. 201521123030 《Java程序设计》 第11周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容. 2. 书面作业 本次PTA作业题集多线程 1.互斥访问与同步访问 完成题集4-4(互斥访问)与4-5(同步访问) ...

  6. 使用C#编写SqlHelper类

    无聊的周末,学习.编码无力.想找点事干但又不知道干点什么,猛然发现自己学过的SqlHelper快忘记了.于是乎虎躯一震心想怎能如此堕落下去,立马打开电脑,双手摸上键盘.写下此文作为学习过程中的复习,并 ...

  7. Spring第八篇【XML、注解实现事务控制】

    前言 本博文主要讲解Spring的事务控制,如何使用Spring来对程序进行事务控制-. 一般地,我们事务控制都是在service层做的..为什么是在service层而不是在dao层呢??有没有这样的 ...

  8. Ajax【介绍、入门、解决Ajax中文、跨域、缓存】

    什么是Ajax Ajax(Asynchronous JavaScript and XML) 异步JavaScript和XML Ajax实际上是下面这几种技术的融合: (1)XHTML和CSS的基于标准 ...

  9. Spring-java-模板设计模式

    1,模板设计模式指的是将相应的模板方法提取出来在专门的位置定义,然后把相同调用过程操作,通过模板来实现对于模板设计模式而言,一般有两种实现方式 1)基于继承的实现 2)基于组合的实现 Spring的J ...

  10. Linux下Birt、JTreeChart中文乱码问题解决办法

    Linux下JTreeChart,Birt等报表工具显示中文乱码解决 1) 现象: 在Windows上生成的报表图片展示正常,但是在Linux上显示(怪异的小方块“口”): 2)问题定位: 这是lin ...