rockchip camera+v4l2+mpp+live555推流demo
demo下载链接:libcamPusher.zip-嵌入式文档类资源-CSDN下载
地址
流程框图:
编译:
mma external/libcamPusher,生成libcamPusher
测试过程:
libcamPusher ,logcat可查看rtsp url地址,用VLC软件打开网络串流
源码简介
demo移植了live555并新增了H264LiveVideoServerMediaSubsession会话类与H264LiveVideoSource获取帧类
main.cpp主程序,创建RTSP server,配置编码器参数,onDoGetNextFrame为帧回调
CamCaptureHelper.cpp camera取数据封装类,通过V4L2获取数据
H264LiveVideoServerMediaSubsession.cpp 创建对话类
H264LiveVideoSource.cpp 获取帧类
QMediaBuffer.cpp buffer封装类
RKHWEncApi.cpp 编码封装类
RtspServer.cpp RTSP封装类
常见修改:
1.StreamParser internal error (0 + 204800 > 150000)报错;
需要在liveMedia文件夹下的StreamParser.cpp文件中修改宏 #define BANK_SIZE 2400000
2.修改输入分辨率
main.cpp
g_width = 1920;
g_height = 1080;
3.修改camera节点
main.cpp
g_stream_dev_name = "/dev/video5";
4.OutPacketBuffer修改live555使得超大I帧不再丢包
RtspServer.cpp
OutPacketBuffer::maxSize = 1920 * 1080 * 2;
OutPacketBuffer
:RTP输出的Buffer,OutPacketBuffer
中的静态变量maxSize
用于定义输出buffer
的最大值,即OutPacketBuffer的最大值。
MediaSink.cpp
unsigned OutPacketBuffer::maxSize = 60000; // by default
也可自己进行手动设置,使用方法:
// Increase the maximum size of video frames that we can 'proxy' without truncation.
// (Such frames are unreasonably large; the back-end servers should really not be sending frames this large!)
OutPacketBuffer::maxSize = (1024*1024); // bytes
// Begin by setting up our usage environment:
TaskScheduler* scheduler = BasicTaskScheduler::createNew();
env = BasicUsageEnvironment::createNew(*scheduler);
RTP输出,判断是否超过上限:
liveMedia\include\MultiFramedRTPSink.hh
class MultiFramedRTPSink: public RTPSink {
...
private:
OutPacketBuffer* fOutBuf;
...
}
live555\liveMedia\MultiFramedRTPSink.cpp
void MultiFramedRTPSink::afterGettingFrame1(unsigned frameSize,
unsigned numTruncatedBytes,
struct timeval presentationTime,
unsigned durationInMicroseconds)
{
if (fIsFirstPacket)
{
// Record the fact that we're starting to play now:
gettimeofday(&fNextSendTime, NULL);
}
fMostRecentPresentationTime = presentationTime;
if (fInitialPresentationTime.tv_sec == 0 && fInitialPresentationTime.tv_usec == 0)
{
fInitialPresentationTime = presentationTime;
}
if (numTruncatedBytes > 0)
{
unsigned const bufferSize = fOutBuf->totalBytesAvailable();
envir() << "MultiFramedRTPSink::afterGettingFrame1(): The input frame data was too large for our buffer size ("
<< bufferSize << "). "
<< numTruncatedBytes
<< " bytes of trailing data was dropped! Correct this by increasing \"OutPacketBuffer::maxSize\" to at least "
<< OutPacketBuffer::maxSize + numTruncatedBytes
<< ", *before* creating this 'RTPSink'. (Current value is "
<< OutPacketBuffer::maxSize
<< ".)\n";
}
...
}
5.MAX_PACKET_SIZE
BufferedPacket
:RTP输入的Buffer
MAX_PACKET_SIZE
用于定义输入Buffer
的上限值,即BufferedPacket
的最大值.
MultiFramedRTPSource.cpp
#define MAX_PACKET_SIZE 65536
BufferedPacket::BufferedPacket()
: fPacketSize(MAX_PACKET_SIZE),
fBuf(new unsigned char[MAX_PACKET_SIZE]),
fNextPacket(NULL)
{
}
在哪里判断输入数据的大小是否超过MAX_PACKET_SIZE
呢? void MultiFramedRTPSource::networkReadHandler1()
具体代码:
void MultiFramedRTPSource::networkReadHandler1()
{
BufferedPacket* bPacket = fPacketReadInProgress;
if (bPacket == NULL)
{
// Normal case: Get a free BufferedPacket descriptor to hold the new network packet:
bPacket = fReorderingBuffer->getFreePacket(this);
}
// Read the network packet, and perform sanity checks on the RTP header:
Boolean readSuccess = False;
do
{
struct sockaddr_in fromAddress;
Boolean packetReadWasIncomplete = fPacketReadInProgress != NULL;
if (!bPacket->fillInData(fRTPInterface, fromAddress, packetReadWasIncomplete))
{
if (bPacket->bytesAvailable() == 0)
{ // should not happen??
envir() << "MultiFramedRTPSource internal error: Hit limit when reading incoming packet over TCP\n";
NsLogNotifyA_Add_file(0, 0,
"Live555: MultiFramedRTPSource internal error: Hit limit when reading incoming packet over TCP");
}
fPacketReadInProgress = NULL;
break;
}
...
} while (0);
if (!readSuccess) fReorderingBuffer->freePacket(bPacket);
doGetNextFrame1();
// If we didn't get proper data this time, we'll get another chance
}
6.maxRTCPPacketSize
用于定义RTCP
数据包的最大值。
liveMedia\RTCP.cpp
static unsigned const maxRTCPPacketSize = 2048;
在哪里判断RTCP
数据包是否超过maxRTCPPacketSize
呢?
liveMedia\RTCP.cpp
void RTCPInstance::incomingReportHandler1()
{
do
{
if (fNumBytesAlreadyRead >= maxRTCPPacketSize)
{
envir() << "RTCPInstance error: Hit limit when reading incoming packet over TCP. Increase \"maxRTCPPacketSize:\""
<< maxRTCPPacketSize << "; fNumBytesAlreadyRead:"
<< fNumBytesAlreadyRead << " >= maxRTCPPacketSize. \n";
break;
}
...
} while (0);
}
7.Hit limit when reading incoming packet over TCP
长时间拉取拉取RTSP流,有时会报以下错误:
RTCPInstance error: Hit limit when reading incoming packet over TCP. Increase "maxRTCPPacketSize"
可考虑提高maxRTCPPacketSize
的值,比如:
static unsigned const maxRTCPPacketSize = (512 * 1024);