You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
v4l2rtspserver/src/H264_V4l2DeviceSource.cpp

90 lines
2.8 KiB
C++

/* ---------------------------------------------------------------------------
** This software is in the public domain, furnished "as is", without technical
** support, and with no warranty, express or implied, as to its usefulness for
** any purpose.
**
** H264_V4l2DeviceSource.cpp
**
** H264 V4L2 Live555 source
**
** -------------------------------------------------------------------------*/
#include <sstream>
// live555
#include <Base64.hh>
// project
#include "logger.h"
#include "H264_V4l2DeviceSource.h"
// ---------------------------------
// H264 V4L2 FramedSource
// ---------------------------------
// split packet in frames
std::list< std::pair<unsigned char*,size_t> > H264_V4L2DeviceSource::splitFrames(unsigned char* frame, unsigned frameSize)
{
std::list< std::pair<unsigned char*,size_t> > frameList;
size_t bufSize = frameSize;
size_t size = 0;
int frameType = 0;
unsigned char* buffer = this->extractFrame(frame, bufSize, size, frameType);
while (buffer != NULL)
{
switch (frameType&0x1F)
{
case 7: LOG(INFO) << "SPS size:" << size << " bufSize:" << bufSize; m_sps.assign((char*)buffer,size); break;
case 8: LOG(INFO) << "PPS size:" << size << " bufSize:" << bufSize; m_pps.assign((char*)buffer,size); break;
case 5: LOG(INFO) << "IDR size:" << size << " bufSize:" << bufSize;
if (m_repeatConfig && !m_sps.empty() && !m_pps.empty())
{
frameList.push_back(std::pair<unsigned char*,size_t>((unsigned char*)m_sps.c_str(), m_sps.size()));
frameList.push_back(std::pair<unsigned char*,size_t>((unsigned char*)m_pps.c_str(), m_pps.size()));
}
break;
default:
break;
}
if (!m_sps.empty() && !m_pps.empty())
{
u_int32_t profile_level_id = 0;
if (m_sps.size() >= 4) profile_level_id = (((unsigned char)m_sps[1])<<16)|(((unsigned char)m_sps[2])<<8)|((unsigned char)m_sps[3]);
char* sps_base64 = base64Encode(m_sps.c_str(), m_sps.size());
char* pps_base64 = base64Encode(m_pps.c_str(), m_pps.size());
std::ostringstream os;
os << "profile-level-id=" << std::hex << std::setw(6) << std::setfill('0') << profile_level_id;
os << ";sprop-parameter-sets=" << sps_base64 <<"," << pps_base64;
m_auxLine.assign(os.str());
delete [] sps_base64;
delete [] pps_base64;
}
frameList.push_back(std::pair<unsigned char*,size_t>(buffer, size));
buffer = this->extractFrame(&buffer[size], bufSize, size, frameType);
}
return frameList;
}
std::list< std::string > H264_V4L2DeviceSource::getInitFrames() {
std::list< std::string > frameList;
frameList.push_back(this->getFrameWithMarker(m_sps));
frameList.push_back(this->getFrameWithMarker(m_pps));
return frameList;
}
bool H264_V4L2DeviceSource::isKeyFrame(const char* buffer, int size) {
bool res = false;
if (size > 4)
{
int frameType = buffer[4]&0x1F;
res = (frameType == 5);
}
return res;
}