经过一个多月的努力,终于完成rtp PS流转rtsp裸流的开发。大部分时间都花在了理解live555的框架,几乎翻遍了关于live555博客,加上自己的调试跟踪,算是有了些浅薄理解,在这里分享给大家,关于live555框架理解(后续有时间补上),网上有很多优秀的博客,大家可以查查,在这里只分享rtp PS流转rtsp裸流大概流程。
1.首先需要扩展FramedFilter类专门用来解封装PS流,即输入一帧PS rtp数据,输出一帧裸流数据,h264或者h265
class MP2PVideoToRawLiveSource: public FramedFilter{
public:
static MP2PVideoToRawLiveSource* createNew(UsageEnvironment& env, FramedSource* inputSource);
//static MP2PVideoToRawLiveSource* createNew(UsageEnvironment& env, FramedSource* inputSource, MP2PAudioToRawLiveSource *audioSource);
FramedSource *getInputSource(){
return fInputSource;}
protected:
virtual ~MP2PVideoToRawLiveSource();
public:
MP2PVideoToRawLiveSource(UsageEnvironment& env, FramedSource* inputSource);
//MP2PVideoToRawLiveSource(UsageEnvironment& env, FramedSource* inputSource, MP2PAudioToRawLiveSource *audioSource);
bool isH264(){
if(fVideoCodec == H264_CODEC){
return true;
}
else{
return false;
}
}
bool isH265(){
if(fVideoCodec == H265_CODEC){
return true;
}
else{
return false;
}
}
public:
bool fRtp_receiving;
bool fVideoCodecChange;
protected:
// redefined virtual functions:
virtual void doGetNextFrame();
static void afterGettingFrame(void* clientData, unsigned frameSize,
unsigned numTruncatedBytes,
struct timeval presentationTime,
unsigned durationInMicroseconds);
void afterGettingFrame1(unsigned frameSize,
unsigned numTruncatedBytes,
struct timeval presentationTime,
unsigned durationInMicroseconds);
protected:
VIDEO_CODEC fVideoCodec;
private:
//FramedSource* fInputSource;
unsigned int fIframegop;
unsigned char *fMP2P_frame_data;
unsigned int fMP2P_frame_data_size;
unsigned char *fMp2p_next_start_slice;
unsigned int fMp2p_next_start_size;
unsigned fPacketSize;
unsigned fNumBitsSeenSoFar; // used by the getNextFrameBit*() routines
unsigned char* fRaw_buf;
RawFrameCache fRawFrameCache[RAW_CACHE_NUM];
int fRawFrameCount;
int64_t fLastPesTime;
unsigned int fTimestamp;
struct timeval fMP2PPreTime;
struct timeval fMP2PPreVideoTime;
private:
void pushRawCache(unsigned char *data, unsigned int size, unsigned int numTruncatedBytes, struct timeval presentationTime,
unsigned int durationInMicroseconds);
void createRawCache();
RawFrameCache * popRawCache();
void destroyRawCache();
};
这个类可以看成一个管道,进去一个source出去一个source, 其中doGetNextFrame是继承来的虚函数,live555框架会去调用这个接口,并且把afterGettingFrame函数注册进去。
void MP2PVideoToRawLiveSource::doGetNextFrame() {
if(fInputSource != NULL) {
RawFrameCache* frame_cache = popRawCache();
if(frame_cache){
memcpy(fTo, frame_cache->frame_data, frame_cache->frame_size);
delete[] frame_cache->frame_data;
frame_cache->frame_data = NULL;
fFrameSize = frame_cache->frame_size;
fNumTruncatedBytes = frame_cache->numTruncatedBytes;
fPresentationTime = frame_cache->presentationTime;
fDurationInMicroseconds = frame_cache->durationInMicroseconds;
fMP2PPreVideoTime = fPresentationTime;
//printf("######### video time %u\n", fPresentationTime.tv_sec);
afterGetting(this)

本文分享了使用live555库进行RTP PS流转RTSP裸流的二次开发经验,详细介绍了如何扩展FramedFilter类解封装PS流,包括关键函数doGetNextFrame和afterGettingFrame1的作用,以及处理无mark标志的RTP包策略。同时,文章提及了解析PES包获取PTS、去除NALU起始码和处理SPS、PPS等视频参数的方法。

3904

被折叠的 条评论
为什么被折叠?



