live555 二次开发 接收RTP PS流(支持udp,tcp主动,被动) 转发rtsp裸流,支持H264,H265

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

经过一个多月的努力,终于完成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)
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值