live555 rtsp推流pcm和h264(内存获取视音频数据)

一:下载live555

        第一种方式:下载官方源码Index of /liveMedia/public

        第二种方式:下载我适配好的live555(解决编译报错,同时推流pcm和h264,解决第二次拉流无音频的bug)live555rtsp推流h264和pcm资源-CSDN文库

二:编译安装live555(官方源码)

        1:进入源码目录,新增config.mc6670,内容如下:

CROSS_COMPILE?=		aarch64-linux-gnu-
COMPILE_OPTS =		$(INCLUDES) -I. -O2 -DSOCKLEN_T=socklen_t -DNO_SSTREAM=1 -D_LARGEFILE_SOURCE=1 -D_FILE_OFFSET_BITS=64 -DNO_OPENSSL=1 -DNO_STD_LIB
C =			c
C_COMPILER =		$(CROSS_COMPILE)gcc
C_FLAGS =		$(COMPILE_OPTS)
CPP =			cpp
CPLUSPLUS_COMPILER =	$(CROSS_COMPILE)g++
CPLUSPLUS_FLAGS =	$(COMPILE_OPTS) -Wall -DBSD=1
OBJ =			o
LINK =			$(CROSS_COMPILE)g++ -o
LINK_OPTS =		
CONSOLE_LINK_OPTS =	$(LINK_OPTS)
LIBRARY_LINK =		$(CROSS_COMPILE)ar cr 
LIBRARY_LINK_OPTS =	$(LINK_OPTS)
LIB_SUFFIX =			a
LIBS_FOR_CONSOLE_APPLICATION =
LIBS_FOR_GUI_APPLICATION =
EXE =
PREFIX = /home/hfzuo/work/live555/_install

        2:适配C++库版本:如果嵌入式系统的C++库版本低于C++20,您需要在config.mc6670文件的COMPILE_OPTS项中追加-DNO_STD_LIB。以避免因版本不兼容导致的语法报错。

         3:处理openssl库依赖:如果嵌入式系统中没有安装openssl库,您需要在config.mc6670文件的COMPILE_OPTS项中追加-DNO_OPENSSL=1。这样做可以防止因缺少openssl库而导致的编译错误。

        4:运行genMakefiles生成makefile,根据后缀名匹配对应的config文件。

        ./genMakefiles mc6670

        5:修改源码   

              5.1:设置pcm和h264推流到同一个地                                      址/home/hfzuo/work/live555/live/testProgs/testOnDemandRTSPServer.cpp             

  // A H.264 video elementary stream:
  {
    OutPacketBuffer::maxSize = 1000000;//防止单帧数据过大
    char const* streamName = "h264ESVideoTest";
    char const* inputFileName = "/usr/local/app/datatest.264";
    char const* inputFileName1 = "/tmp/pcm.wav";
    //char const* inputFileName1 = "/tmp/pcm.aac";
    ServerMediaSession* sms
      = ServerMediaSession::createNew(*env, streamName, streamName,
				      descriptionString);
    sms->addSubsession(H264VideoFileServerMediaSubsession
		       ::createNew(*env, inputFileName, reuseFirstSource));

    Boolean convertToULaw = 1;
    sms->addSubsession(WAVAudioFileServerMediaSubsession
	       ::createNew(*env, inputFileName1, reuseFirstSource, convertToULaw));


    // sms->addSubsession(ADTSAudioFileServerMediaSubsession
	// 	       ::createNew(*env, inputFileName1, reuseFirstSource));




    rtspServer->addServerMediaSession(sms);

    announceStream(rtspServer, sms, streamName, inputFileName);
  }

          5.2:固定wav头数据,因为我们实际传输是pcm裸流,并没有wav头信息,所以需要手动填写相关音频格式,如果内存里的音频数据存在变化的,可以以传参的方式固定,下面是48K 16BIT 2CH的代码修改      

WAVAudioFileSource::WAVAudioFileSource(UsageEnvironment& env, FILE* fid)
  : AudioInputDevice(env, 0, 0, 0, 0)/* set the real parameters later */,
    fFid(fid), fFidIsSeekable(False), fLastPlayTime(0), fHaveStartedReading(False), fWAVHeaderSize(0), fFileSize(0),
    fScaleFactor(1), fLimitNumBytesToStream(False), fNumBytesToStream(0), fAudioFormat(WA_UNKNOWN) {
Boolean success = False; // until we learn otherwise
  do {
    printf("hfzuo wav head\r\n");//hfzuodebug
    fAudioFormat = 1;
    printf("fAudioFormat=%d\r\n",fAudioFormat);//hfzuodebug
    if (fAudioFormat != WA_PCM && fAudioFormat != WA_PCMA && fAudioFormat != WA_PCMU && fAudioFormat != WA_IMA_ADPCM) {
      // It's a format that we don't (yet) understand
      env.setResultMsg("Audio format is not one that we handle (PCM/PCMU/PCMA or IMA ADPCM)");
      break;
    }
    fNumChannels = 2;
    printf("fNumChannels=%d\r\n",fNumChannels);//hfzuodebug
    if (fNumChannels < 1 || fNumChannels > 2) { // invalid # channels
      char errMsg[100];
      sprintf(errMsg, "Bad # channels: %d", fNumChannels);
      env.setResultMsg(errMsg);
      break;
    }
    fSamplingFrequency=48000;
    printf("fSamplingFrequency=%d\r\n",fSamplingFrequency);//hfzuodebug
    if (fSamplingFrequency == 0) {
      env.setResultMsg("Bad sampling frequency: 0");
      break;
    }
    fBitsPerSample = 16;
    printf("fBitsPerSample=%d\r\n",fBitsPerSample);//hfzuodebug
    if (fBitsPerSample == 0) {
      env.setResultMsg("Bad bits-per-sample: 0");
      break;
    }
    fWAVHeaderSize = 4294967295;//(unsigned)TellFile64(fid);
    printf("fWAVHeaderSize=%u\r\n",fWAVHeaderSize);//hfzuodebug
    success = True;
  } while (0);

  if (!success) {
    env.setResultMsg("Bad WAV file format");
    // Set "fBitsPerSample" to zero, to indicate failure:
    fBitsPerSample = 0;
    return;
  }

  fPlayTimePerSample = 1e6/(double)fSamplingFrequency;
  printf("fPlayTimePerSample=%d\r\n",fPlayTimePerSample);//hfzuodebug

  unsigned maxSamplesPerFrame = (1400*8)/(fNumChannels*fBitsPerSample);
  unsigned desiredSamplesPerFrame = (unsigned)(0.02*fSamplingFrequency);
  unsigned samplesPerFrame = desiredSamplesPerFrame < maxSamplesPerFrame ? desiredSamplesPerFrame : maxSamplesPerFrame;
  fPreferredFrameSize = (samplesPerFrame*fNumChannels*fBitsPerSample)/8;
  printf("maxSamplesPerFrame=%d\r\n",maxSamplesPerFrame);//hfzuodebug
  printf("desiredSamplesPerFrame=%d\r\n",desiredSamplesPerFrame);//hfzuodebug  
  printf("samplesPerFrame=%d\r\n",samplesPerFrame);//hfzuodebug
  printf("fPreferredFrameSize=%d\r\n",fPreferredFrameSize);//hfzuodebug
  fFidIsSeekable = FileIsSeekable(fFid);
  printf("fFidIsSeekable=%d\r\n",fFidIsSeekable);//hfzuodebug

#ifndef READ_FROM_FILES_SYNCHRONOUSLY
    printf("synchronously\r\n");//hfzuodebug
    makeSocketNonBlocking(fileno(fFid));
#endif
}

        6:解决MultiFramedRTPSink::afterGettingFrame1(): The input frame data was too large for our buffer size (300552).  25411 bytes of trailing data was dropped! 
 Correct this by increasing "OutPacketBuffer::maxSize" to at least 325411, *before* creating this 'RTPSink'.  (Current value is 300000.)报错

        解决办法:

            a:live/liveMedia/MultiFramedRTPSource.cpp :increaseReceiveBufferTo(env, RTPgs-> socketNUm(), 2000000)
            b:live/liveMedia/StreamParser.cpp:#define BANK_SIZE 1200000//150000
            c: live/liveMedia/MediaSink.cpp : unsigned OutPacketBuffer::maxSize = 600000;
            d:mediaServer/DynamicRTSPServer.cpp:OutPacketBuffer::maxSize = 600000; 
            e:testH264VideoStreamer.cpp : OutPacketBuffer::maxSize =  600000;
            f:testProgs/playCommon.cpp: unsigned fileSinkBufferSize = 600000;

        7:编译安装

                make   make install PREFIX=/home/hfzuo/work/live555/_install  

                将 testOnDemandRTSPServer 拷贝到开发板运行即可及

三:开发板从内存获取pcm和h264通过fifo发送给live555

        get_h264_frame:获取h264接口

        get_pcm_frame:获取pcm接口

h264:
mkfifo("/usr/local/app/datatest.264", 0666);
int fd = open("/usr/local/app/datatest.264", O_WRONLY);
for(;;)
{
    uint8_t buff[1024*1024*8]
    int size=get_h264_frame(buff);
    write(fd, (buff),size);
}


pcm:
mkfifo("/tmp/pcm.wav", 0666);
int fd = open("/tmp/pcm.wav", O_WRONLY);
for(;;)
{
    uint8_t buff[2048]
    int size=get_pcm_frame(buff);
    write(fd, (buff),size);
}

四:VLC拉流

        拉流地址:rtsp://192.168.1.218:8554/h264ESVideoTest,打开播放器如VLC输入拉流地址即可得到视音频

      实际测试效果:延迟大概1-2秒,不存在视音频不同步的问题,只要视音频数据写入fifo及时(按音频采样率和视频帧率)live会自动给视音频流打上时间戳。如果出现视音频不同步问题,一定会是视音频写入fifo时存在延迟情况

  • 17
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值