add api to getInitFrames

pull/296/head
mpromonet 2 years ago
parent a5c0762671
commit 0165defff3

@ -15,6 +15,7 @@
#include "V4L2DeviceSource.h"
#include "H264_V4l2DeviceSource.h"
#include "H265_V4l2DeviceSource.h"
class DeviceSourceFactory {
public:

@ -13,30 +13,7 @@
#pragma once
// project
#include "V4L2DeviceSource.h"
// ---------------------------------
// H264 V4L2 FramedSource
// ---------------------------------
const char H264marker[] = {0,0,0,1};
const char H264shortmarker[] = {0,0,1};
class H26X_V4L2DeviceSource : public V4L2DeviceSource
{
protected:
H26X_V4L2DeviceSource(UsageEnvironment& env, DeviceInterface * device, int outputFd, unsigned int queueSize, CaptureMode captureMode, bool repeatConfig, bool keepMarker)
: V4L2DeviceSource(env, device, outputFd, queueSize, captureMode), m_repeatConfig(repeatConfig), m_keepMarker(keepMarker) {}
virtual ~H26X_V4L2DeviceSource() {}
unsigned char* extractFrame(unsigned char* frame, size_t& size, size_t& outsize, int& frameType);
protected:
std::string m_sps;
std::string m_pps;
bool m_repeatConfig;
bool m_keepMarker;
};
#include "H26x_V4l2DeviceSource.h"
class H264_V4L2DeviceSource : public H26X_V4L2DeviceSource
{
@ -50,24 +27,6 @@ class H264_V4L2DeviceSource : public H26X_V4L2DeviceSource
: H26X_V4L2DeviceSource(env, device, outputFd, queueSize, captureMode, repeatConfig, keepMarker) {}
// overide V4L2DeviceSource
virtual std::list< std::pair<unsigned char*,size_t> > splitFrames(unsigned char* frame, unsigned frameSize);
virtual std::list< std::pair<unsigned char*,size_t> > splitFrames(unsigned char* frame, unsigned frameSize);
virtual std::list< std::string > getInitFrames();
};
class H265_V4L2DeviceSource : public H26X_V4L2DeviceSource
{
public:
static H265_V4L2DeviceSource* createNew(UsageEnvironment& env, DeviceInterface * device, int outputFd, unsigned int queueSize, CaptureMode captureMode, bool repeatConfig, bool keepMarker) {
return new H265_V4L2DeviceSource(env, device, outputFd, queueSize, captureMode, repeatConfig, keepMarker);
}
protected:
H265_V4L2DeviceSource(UsageEnvironment& env, DeviceInterface * device, int outputFd, unsigned int queueSize, CaptureMode captureMode, bool repeatConfig, bool keepMarker)
: H26X_V4L2DeviceSource(env, device, outputFd, queueSize, captureMode, repeatConfig, keepMarker) {}
// overide V4L2DeviceSource
virtual std::list< std::pair<unsigned char*,size_t> > splitFrames(unsigned char* frame, unsigned frameSize);
protected:
std::string m_vps;
};

@ -0,0 +1,36 @@
/* ---------------------------------------------------------------------------
** 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.
**
** H265_V4l2DeviceSource.h
**
** H265 V4L2 live555 source
**
** -------------------------------------------------------------------------*/
#pragma once
// project
#include "H26x_V4l2DeviceSource.h"
class H265_V4L2DeviceSource : public H26X_V4L2DeviceSource
{
public:
static H265_V4L2DeviceSource* createNew(UsageEnvironment& env, DeviceInterface * device, int outputFd, unsigned int queueSize, CaptureMode captureMode, bool repeatConfig, bool keepMarker) {
return new H265_V4L2DeviceSource(env, device, outputFd, queueSize, captureMode, repeatConfig, keepMarker);
}
protected:
H265_V4L2DeviceSource(UsageEnvironment& env, DeviceInterface * device, int outputFd, unsigned int queueSize, CaptureMode captureMode, bool repeatConfig, bool keepMarker)
: H26X_V4L2DeviceSource(env, device, outputFd, queueSize, captureMode, repeatConfig, keepMarker) {}
// overide V4L2DeviceSource
virtual std::list< std::pair<unsigned char*,size_t> > splitFrames(unsigned char* frame, unsigned frameSize);
virtual std::list< std::string > getInitFrames();
protected:
std::string m_vps;
};

@ -0,0 +1,40 @@
/* ---------------------------------------------------------------------------
** 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.
**
** H26x_V4l2DeviceSource.h
**
** H264/H265 V4L2 live555 source
**
** -------------------------------------------------------------------------*/
#pragma once
// project
#include "V4L2DeviceSource.h"
// ---------------------------------
// H264 V4L2 FramedSource
// ---------------------------------
const char H264marker[] = {0,0,0,1};
const char H264shortmarker[] = {0,0,1};
class H26X_V4L2DeviceSource : public V4L2DeviceSource
{
protected:
H26X_V4L2DeviceSource(UsageEnvironment& env, DeviceInterface * device, int outputFd, unsigned int queueSize, CaptureMode captureMode, bool repeatConfig, bool keepMarker)
: V4L2DeviceSource(env, device, outputFd, queueSize, captureMode), m_repeatConfig(repeatConfig), m_keepMarker(keepMarker) {}
virtual ~H26X_V4L2DeviceSource() {}
unsigned char* extractFrame(unsigned char* frame, size_t& size, size_t& outsize, int& frameType);
std::string getFrameWithMarker(const std::string & frame);
protected:
std::string m_sps;
std::string m_pps;
bool m_repeatConfig;
bool m_keepMarker;
};

@ -77,9 +77,9 @@ class V4L2DeviceSource: public FramedSource
public:
static V4L2DeviceSource* createNew(UsageEnvironment& env, DeviceInterface * device, int outputFd, unsigned int queueSize, CaptureMode captureMode) ;
std::string getAuxLine() { return m_auxLine; }
void setAuxLine(const std::string auxLine) { m_auxLine = auxLine; }
DeviceInterface* getDevice() { return m_device; }
void postFrame(char * frame, int frameSize, const timeval &ref);
virtual std::list< std::string > getInitFrames() { return std::list< std::string >(); }
protected:

@ -72,107 +72,9 @@ std::list< std::pair<unsigned char*,size_t> > H264_V4L2DeviceSource::splitFrames
return frameList;
}
// split packet in frames
std::list< std::pair<unsigned char*,size_t> > H265_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&0x7E)>>1)
{
case 32: LOG(INFO) << "VPS size:" << size << " bufSize:" << bufSize; m_vps.assign((char*)buffer,size); break;
case 33: LOG(INFO) << "SPS size:" << size << " bufSize:" << bufSize; m_sps.assign((char*)buffer,size); break;
case 34: LOG(INFO) << "PPS size:" << size << " bufSize:" << bufSize; m_pps.assign((char*)buffer,size); break;
case 19:
case 20: LOG(INFO) << "IDR size:" << size << " bufSize:" << bufSize;
if (m_repeatConfig && !m_vps.empty() && !m_sps.empty() && !m_pps.empty())
{
frameList.push_back(std::pair<unsigned char*,size_t>((unsigned char*)m_vps.c_str(), m_vps.size()));
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_vps.empty() && !m_sps.empty() && !m_pps.empty())
{
char* vps_base64 = base64Encode(m_vps.c_str(), m_vps.size());
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 << "sprop-vps=" << vps_base64;
os << ";sprop-sps=" << sps_base64;
os << ";sprop-pps=" << pps_base64;
m_auxLine.assign(os.str());
delete [] vps_base64;
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);
}
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;
}
// extract a frame
unsigned char* H26X_V4L2DeviceSource::extractFrame(unsigned char* frame, size_t& size, size_t& outsize, int& frameType)
{
unsigned char * outFrame = NULL;
outsize = 0;
unsigned int markerlength = 0;
frameType = 0;
unsigned char *startFrame = (unsigned char*)memmem(frame,size,H264marker,sizeof(H264marker));
if (startFrame != NULL) {
markerlength = sizeof(H264marker);
} else {
startFrame = (unsigned char*)memmem(frame,size,H264shortmarker,sizeof(H264shortmarker));
if (startFrame != NULL) {
markerlength = sizeof(H264shortmarker);
}
}
if (startFrame != NULL) {
frameType = startFrame[markerlength];
int remainingSize = size-(startFrame-frame+markerlength);
unsigned char *endFrame = (unsigned char*)memmem(&startFrame[markerlength], remainingSize, H264marker, sizeof(H264marker));
if (endFrame == NULL) {
endFrame = (unsigned char*)memmem(&startFrame[markerlength], remainingSize, H264shortmarker, sizeof(H264shortmarker));
}
if (m_keepMarker)
{
size -= startFrame-frame;
outFrame = startFrame;
}
else
{
size -= startFrame-frame+markerlength;
outFrame = &startFrame[markerlength];
}
if (endFrame != NULL)
{
outsize = endFrame - outFrame;
}
else
{
outsize = size;
}
size -= outsize;
} else if (size>= sizeof(H264shortmarker)) {
LOG(INFO) << "No marker found";
}
return outFrame;
}

@ -0,0 +1,78 @@
/* ---------------------------------------------------------------------------
** 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.
**
** H265_V4l2DeviceSource.cpp
**
** H265 V4L2 Live555 source
**
** -------------------------------------------------------------------------*/
#include <sstream>
// live555
#include <Base64.hh>
// project
#include "logger.h"
#include "H265_V4l2DeviceSource.h"
// split packet in frames
std::list< std::pair<unsigned char*,size_t> > H265_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&0x7E)>>1)
{
case 32: LOG(INFO) << "VPS size:" << size << " bufSize:" << bufSize; m_vps.assign((char*)buffer,size); break;
case 33: LOG(INFO) << "SPS size:" << size << " bufSize:" << bufSize; m_sps.assign((char*)buffer,size); break;
case 34: LOG(INFO) << "PPS size:" << size << " bufSize:" << bufSize; m_pps.assign((char*)buffer,size); break;
case 19:
case 20: LOG(INFO) << "IDR size:" << size << " bufSize:" << bufSize;
if (m_repeatConfig && !m_vps.empty() && !m_sps.empty() && !m_pps.empty())
{
frameList.push_back(std::pair<unsigned char*,size_t>((unsigned char*)m_vps.c_str(), m_vps.size()));
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_vps.empty() && !m_sps.empty() && !m_pps.empty())
{
char* vps_base64 = base64Encode(m_vps.c_str(), m_vps.size());
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 << "sprop-vps=" << vps_base64;
os << ";sprop-sps=" << sps_base64;
os << ";sprop-pps=" << pps_base64;
m_auxLine.assign(os.str());
delete [] vps_base64;
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 > H265_V4L2DeviceSource::getInitFrames() {
std::list< std::string > frameList;
frameList.push_back(this->getFrameWithMarker(m_vps));
frameList.push_back(this->getFrameWithMarker(m_sps));
frameList.push_back(this->getFrameWithMarker(m_pps));
return frameList;
}

@ -0,0 +1,79 @@
/* ---------------------------------------------------------------------------
** 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.
**
** H26x_V4l2DeviceSource.cpp
**
** H264/H265 V4L2 Live555 source
**
** -------------------------------------------------------------------------*/
#include <sstream>
// live555
#include <Base64.hh>
// project
#include "logger.h"
#include "H26x_V4l2DeviceSource.h"
// extract a frame
unsigned char* H26X_V4L2DeviceSource::extractFrame(unsigned char* frame, size_t& size, size_t& outsize, int& frameType)
{
unsigned char * outFrame = NULL;
outsize = 0;
unsigned int markerlength = 0;
frameType = 0;
unsigned char *startFrame = (unsigned char*)memmem(frame,size,H264marker,sizeof(H264marker));
if (startFrame != NULL) {
markerlength = sizeof(H264marker);
} else {
startFrame = (unsigned char*)memmem(frame,size,H264shortmarker,sizeof(H264shortmarker));
if (startFrame != NULL) {
markerlength = sizeof(H264shortmarker);
}
}
if (startFrame != NULL) {
frameType = startFrame[markerlength];
int remainingSize = size-(startFrame-frame+markerlength);
unsigned char *endFrame = (unsigned char*)memmem(&startFrame[markerlength], remainingSize, H264marker, sizeof(H264marker));
if (endFrame == NULL) {
endFrame = (unsigned char*)memmem(&startFrame[markerlength], remainingSize, H264shortmarker, sizeof(H264shortmarker));
}
if (m_keepMarker)
{
size -= startFrame-frame;
outFrame = startFrame;
}
else
{
size -= startFrame-frame+markerlength;
outFrame = &startFrame[markerlength];
}
if (endFrame != NULL)
{
outsize = endFrame - outFrame;
}
else
{
outsize = size;
}
size -= outsize;
} else if (size>= sizeof(H264shortmarker)) {
LOG(INFO) << "No marker found";
}
return outFrame;
}
std::string H26X_V4L2DeviceSource::getFrameWithMarker(const std::string & frame) {
std::string frameWithMarker(H264marker);
frameWithMarker.append(frame);
return frameWithMarker;
}
Loading…
Cancel
Save