#ifndef _PSUNPACKET_H_
#define _PSUNPACKET_H_
#include "streamdef.h"
#include <tuple>
using namespace std::tr1;
#ifndef AV_RB16
# define AV_RB16(x) \
((((const unsigned char*)(x))[0] << 8) | \
((const unsigned char*)(x))[1])
#endif
static inline unsigned __int64 ff_parse_pes_pts(const unsigned char* buf) {
return (unsigned __int64)(*buf & 0x0e) << 29 |
(AV_RB16(buf+1) >> 1) << 15 |
AV_RB16(buf+3) >> 1;
}
static unsigned __int64 get_pts(optional_pes_header* option)
{
if(option->PTS_DTS_flags != 2 && option->PTS_DTS_flags != 3 && option->PTS_DTS_flags != 0)
{
return 0;
}
if((option->PTS_DTS_flags & 2) == 2)
{
unsigned char* pts = (unsigned char*)option + sizeof(optional_pes_header);
return ff_parse_pes_pts(pts);
}
return 0;
}
static unsigned __int64 get_dts(optional_pes_header* option)
{
if(option->PTS_DTS_flags != 2 && option->PTS_DTS_flags != 3 && option->PTS_DTS_flags != 0)
{
return 0;
}
if((option->PTS_DTS_flags & 3) == 3)
{
unsigned char* dts = (unsigned char*)option + sizeof(optional_pes_header) + 5;
return ff_parse_pes_pts(dts);
}
return 0;
}
bool inline is_ps_header(ps_header_t* ps)
{
if(ps->pack_start_code[0] == 0 && ps->pack_start_code[1] == 0 && ps->pack_start_code[2] == 1 && ps->pack_start_code[3] == 0xBA)
return true;
return false;
}
bool inline is_sh_header(sh_header_t* sh)
{
if(sh->system_header_start_code[0] == 0 && sh->system_header_start_code[1] == 0 && sh->system_header_start_code[2] == 1 && sh->system_header_start_code[3] == 0xBB)
return true;
return false;
}
bool inline is_psm_header(psm_header_t* psm)
{
if(psm->promgram_stream_map_start_code[0] == 0 && psm->promgram_stream_map_start_code[1] == 0 && psm->promgram_stream_map_start_code[2] == 1 && psm->promgram_stream_map_start_code[3] == 0xBC)
return true;
return false;
}
bool inline is_pes_video_header(pes_header_t* pes)
{
if(pes->pes_start_code_prefix[0]==0 && pes->pes_start_code_prefix[1] == 0 && pes->pes_start_code_prefix[2] == 1 && pes->stream_id == 0xE0)
return true;
return false;
}
bool inline is_pes_audio_header(pes_header_t* pes)
{
if(pes->pes_start_code_prefix[0]==0 && pes->pes_start_code_prefix[1] == 0 && pes->pes_start_code_prefix[2] == 1 && pes->stream_id == 0xC0)
return true;
return false;
}
bool inline is_pes_header(pes_header_t* pes)
{
if(pes->pes_start_code_prefix[0]==0 && pes->pes_start_code_prefix[1] == 0 && pes->pes_start_code_prefix[2] == 1)
{
if(pes->stream_id == 0xC0 || pes->stream_id == 0xE0)
{
return true;
}
}
return false;
}
PSStatus inline pes_type(pes_header_t* pes)
{
if(pes->pes_start_code_prefix[0]==0 && pes->pes_start_code_prefix[1] == 0 && pes->pes_start_code_prefix[2] == 1)
{
if(pes->stream_id == 0xC0)
{
return ps_pes_audio;
}
else if(pes->stream_id == 0xE0)
{
return ps_pes_video;
}
}
return ps_padding;
}
/*
_1 是否包含数据
_2 下一个PS状态
_3 数据指针
_4 数据长度
*/
typedef std::tr1::tuple<bool, PSStatus, pes_header_t*> pes_tuple;
/*
_1 是否包含数据
_2 数据类型
_3 PTS时间戳
_4 DTS时间戳
_5 数据指针
_6 数据长度
*/
typedef std::tr1::tuple<bool, unsigned char, unsigned __int64, unsigned __int64, char*, unsigned int> naked_tuple;
class PSPacket
{
public:
PSPacket()
{
m_status = ps_padding;
m_nESLength = m_nPESIndicator = m_nPSWrtiePos = m_nPESLength = 0;
}
void PSWrite(char* pBuffer, unsigned int sz)
{
if(m_nPSWrtiePos + sz < MAX_PS_LENGTH)
{
memcpy((m_pPSBuffer + m_nPSWrtiePos), pBuffer, sz);
m_nPSWrtiePos += sz;
}
else
{
m_status = ps_padding;
m_nESLength = m_nPESIndicator = m_nPSWrtiePos = m_nPESLength = 0;
}
}
void RTPWrite(char* pBuffer, unsigned int sz)
{
char* data = (pBuffer + sizeof(RTP_header_t));
unsigned int length = sz - sizeof(RTP_header_t);
if(m_nPSWrtiePos + length < MAX_PS_LENGTH)
{
memcpy((m_pPSBuffer + m_nPSWrtiePos), data, length);
m_nPSWrtiePos += length;
}
else
{
m_status = ps_padding;
m_nESLength = m_nPESIndicator = m_nPSWrtiePos = m_nPESLength = 0;
}
}
pes_tuple pes_payload()
{
if(m_status == ps_padding)
{
for(; m_nPESIndicator<m_nPSWrtiePos; m_nPESIndicator++)
{
m_ps = (ps_header_t*)(m_pPSBuffer + m_nPESIndicator);
if(is_ps_header(m_ps))
{
m_status = ps_ps;
break;
}
}
}
if(m_status == ps_ps)
{
for(; m_nPESIndicator<m_nPSWrtiePos; m_nPESIndicator++)
{
m_sh = (sh_header_t*)(m_pPSBuffer + m_nPESIndicator);
m_pes = (pes_header_t*)(m_pPSBuffer + m_nPESIndicator);
if(is_sh_header(m_sh))
{
m_status = ps_sh;
break;
}
else if (is_pes_header(m_pes))
{
m_status = ps_pes;
break;
}
}
}
if(m_status == ps_sh)
{
for(; m_nPESIndicator<m_nPSWrtiePos; m_nPESIndicator++)
{
m_psm = (psm_header_t*)(m_pPSBuffer + m_nPESIndicator);
m_pes = (pes_header_t*)(m_pPSBuffer + m_nPESIndicator);
if(is_psm_header(m_psm))
{
m_status = ps_psm;//冲掉s_sh状态
break;
}
if(is_pes_header(m_pes))
{
m_status = ps_pes;
break;
}
}
}
if(m_status == ps_psm)
{
for(; m_nPESIndicator<m_nPSWrtiePos; m_nPESIndicator++)
{
m_pes = (pes_header_t*)(m_pPSBuffer + m_nPESIndicator);
if(is_pes_header(m_pes))
{
m_status = ps_pes;
break;
}
}
}
if(m_status == ps_pes)
{
//寻找下一个pes 或者 ps
unsigned short PES_packet_length = ntohs(m_pes->PES_packet_length);
if((m_nPESIndicator + PES_packet_length + sizeof(pes_header_t)) < m_nPSWrtiePos)
{
char* next = (m_pPSBuffer + m_nPESIndicator + sizeof(pes_header_t) + PES_packet_length);
pes_header_t* pes = (pes_header_t*)next;
ps_header_t* ps = (ps_header_t*)next;
m_nPESLength = PES_packet_length + sizeof(pes_header_t);
memcpy(m_pPESBuffer, m_pes, m_nPESLength);
if(is_pes_header(pes) || is_ps_header(ps))
{
PSStatus status = ps_padding;
if(is_ps_header(ps))
{
status = m_status = ps_ps;
}
else
{
status = pes_type(pes);
}
int remain = m_nPSWrtiePos - (next - m_pPSBuffer);
memcpy(m_pPSBuffer, next, remain);
m_nPSWrtiePos = remain; m_nPESIndicator = 0;
m_ps = (ps_header_t*)m_pPSBuffer;
m_pes = (pes_header_t*)m_pPSBuffer;
return pes_tuple(t
PSExtractor.zip_h264 ps_ps h264_ps 提取 h264_ps流_从ps流提取h264
版权申诉
5星 · 超过95%的资源 10 浏览量
2022-07-14
09:01:11
上传
评论
收藏 4KB ZIP 举报
邓凌佳
- 粉丝: 65
- 资源: 1万+
最新资源
- HITK0203MP-VB一款N-Channel沟道SOT23的MOSFET晶体管参数介绍与应用说明
- HITK0202MP-VB一款N-Channel沟道SOT23的MOSFET晶体管参数介绍与应用说
- 电子电气工程师使用的单位和符号
- HITK0201MP-VB一款N-Channel沟道SOT23的MOSFET晶体管参数介绍与应用说明
- MyBatis动态SQL:构建灵活查询的利器.md
- HITJ0303MP-VB一款P-Channel沟道SOT23的MOSFET晶体管参数介绍与应用说明
- tesseract安装包
- 1_32陀螺仪舵机.zip
- HITJ0302MP-VB一款P-Channel沟道SOT23的MOSFET晶体管参数介绍与应用说明
- XILINXFPGA源码PCIExpress标准概述
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
评论1