style and performance improvements reported by cppcheck
This commit is contained in:
parent
01834d4ddc
commit
3cd9bdccd5
|
@ -41,10 +41,9 @@ void Fifo::file_create_if_missing(
|
||||||
Debug(5, "Supposed to be a fifo pipe but isn't, unlinking: %s", path);
|
Debug(5, "Supposed to be a fifo pipe but isn't, unlinking: %s", path);
|
||||||
unlink(path);
|
unlink(path);
|
||||||
}
|
}
|
||||||
int fd;
|
|
||||||
if (!is_fifo) {
|
if (!is_fifo) {
|
||||||
Debug(5, "Creating non fifo file as requested: %s", path);
|
Debug(5, "Creating non fifo file as requested: %s", path);
|
||||||
fd = ::open(path, O_CREAT|O_WRONLY, S_IRUSR|S_IWUSR);
|
int fd = ::open(path, O_CREAT|O_WRONLY, S_IRUSR|S_IWUSR);
|
||||||
::close(fd);
|
::close(fd);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2381,7 +2381,7 @@ void Monitor::ReloadLinkedMonitors(const char *p_linked_monitors) {
|
||||||
} // end if p_linked_monitors
|
} // end if p_linked_monitors
|
||||||
} // end void Monitor::ReloadLinkedMonitors(const char *p_linked_monitors)
|
} // end void Monitor::ReloadLinkedMonitors(const char *p_linked_monitors)
|
||||||
|
|
||||||
std::vector<std::shared_ptr<Monitor>> Monitor::LoadMonitors(std::string &where, Purpose purpose) {
|
std::vector<std::shared_ptr<Monitor>> Monitor::LoadMonitors(const std::string &where, Purpose purpose) {
|
||||||
std::string sql = load_monitor_sql + " WHERE " + where;
|
std::string sql = load_monitor_sql + " WHERE " + where;
|
||||||
Debug(1, "Loading Monitors with %s", sql.c_str());
|
Debug(1, "Loading Monitors with %s", sql.c_str());
|
||||||
|
|
||||||
|
@ -2974,7 +2974,7 @@ bool Monitor::DumpSettings(char *output, bool verbose) {
|
||||||
function==MOCORD?"Continuous Record with Motion Detection":(
|
function==MOCORD?"Continuous Record with Motion Detection":(
|
||||||
function==NODECT?"Externally Triggered only, no Motion Detection":"Unknown"
|
function==NODECT?"Externally Triggered only, no Motion Detection":"Unknown"
|
||||||
))))));
|
))))));
|
||||||
sprintf(output+strlen(output), "Zones : %lu\n", zones.size());
|
sprintf(output+strlen(output), "Zones : %zu\n", zones.size());
|
||||||
for (const Zone &zone : zones) {
|
for (const Zone &zone : zones) {
|
||||||
zone.DumpSettings(output+strlen(output), verbose);
|
zone.DumpSettings(output+strlen(output), verbose);
|
||||||
}
|
}
|
||||||
|
@ -3145,21 +3145,22 @@ void Monitor::get_ref_image() {
|
||||||
|
|
||||||
std::vector<Group *> Monitor::Groups() {
|
std::vector<Group *> Monitor::Groups() {
|
||||||
// At the moment, only load groups once.
|
// At the moment, only load groups once.
|
||||||
if ( !groups.size() ) {
|
if (!groups.size()) {
|
||||||
std::string sql = stringtf(
|
std::string sql = stringtf(
|
||||||
"SELECT `Id`, `ParentId`, `Name` FROM `Groups` WHERE `Groups.Id` IN "
|
"SELECT `Id`, `ParentId`, `Name` FROM `Groups` WHERE `Groups.Id` IN "
|
||||||
"(SELECT `GroupId` FROM `Groups_Monitors` WHERE `MonitorId`=%d)", id);
|
"(SELECT `GroupId` FROM `Groups_Monitors` WHERE `MonitorId`=%d)", id);
|
||||||
MYSQL_RES *result = zmDbFetch(sql.c_str());
|
MYSQL_RES *result = zmDbFetch(sql.c_str());
|
||||||
if ( !result ) {
|
if (!result) {
|
||||||
Error("Can't load groups: %s", mysql_error(&dbconn));
|
Error("Can't load groups: %s", mysql_error(&dbconn));
|
||||||
return groups;
|
return groups;
|
||||||
}
|
}
|
||||||
int n_groups = mysql_num_rows(result);
|
int n_groups = mysql_num_rows(result);
|
||||||
Debug(1, "Got %d groups", n_groups);
|
Debug(1, "Got %d groups", n_groups);
|
||||||
while ( MYSQL_ROW dbrow = mysql_fetch_row(result) ) {
|
groups.reserve(n_groups);
|
||||||
|
while (MYSQL_ROW dbrow = mysql_fetch_row(result)) {
|
||||||
groups.push_back(new Group(dbrow));
|
groups.push_back(new Group(dbrow));
|
||||||
}
|
}
|
||||||
if ( mysql_errno(&dbconn) ) {
|
if (mysql_errno(&dbconn)) {
|
||||||
Error("Can't fetch row: %s", mysql_error(&dbconn));
|
Error("Can't fetch row: %s", mysql_error(&dbconn));
|
||||||
}
|
}
|
||||||
mysql_free_result(result);
|
mysql_free_result(result);
|
||||||
|
|
|
@ -594,7 +594,7 @@ public:
|
||||||
std::vector<Group *> Groups();
|
std::vector<Group *> Groups();
|
||||||
StringVector GroupNames();
|
StringVector GroupNames();
|
||||||
|
|
||||||
static std::vector<std::shared_ptr<Monitor>> LoadMonitors(std::string &sql, Purpose purpose); // Returns # of Monitors loaded, 0 on failure.
|
static std::vector<std::shared_ptr<Monitor>> LoadMonitors(const std::string &sql, Purpose purpose); // Returns # of Monitors loaded, 0 on failure.
|
||||||
#if ZM_HAS_V4L
|
#if ZM_HAS_V4L
|
||||||
static std::vector<std::shared_ptr<Monitor>> LoadLocalMonitors(const char *device, Purpose purpose);
|
static std::vector<std::shared_ptr<Monitor>> LoadLocalMonitors(const char *device, Purpose purpose);
|
||||||
#endif // ZM_HAS_V4L
|
#endif // ZM_HAS_V4L
|
||||||
|
|
|
@ -282,7 +282,7 @@ AVFrame *ZMPacket::get_out_frame(int width, int height, AVPixelFormat format) {
|
||||||
codec_imgsize = avpicture_get_size(
|
codec_imgsize = avpicture_get_size(
|
||||||
format,
|
format,
|
||||||
width,
|
width,
|
||||||
>height);
|
height);
|
||||||
buffer = (uint8_t *)av_malloc(codec_imgsize);
|
buffer = (uint8_t *)av_malloc(codec_imgsize);
|
||||||
avpicture_fill(
|
avpicture_fill(
|
||||||
(AVPicture *)out_frame,
|
(AVPicture *)out_frame,
|
||||||
|
|
|
@ -236,7 +236,6 @@ void PacketQueue::clearPackets(const std::shared_ptr<ZMPacket> &add_packet) {
|
||||||
|
|
||||||
packetqueue_iterator it = pktQueue.begin();
|
packetqueue_iterator it = pktQueue.begin();
|
||||||
packetqueue_iterator next_front = pktQueue.begin();
|
packetqueue_iterator next_front = pktQueue.begin();
|
||||||
int video_packets_to_delete = 0; // This is a count of how many packets we will delete so we know when to stop looking
|
|
||||||
|
|
||||||
// First packet is special because we know it is a video keyframe and only need to check for lock
|
// First packet is special because we know it is a video keyframe and only need to check for lock
|
||||||
std::shared_ptr<ZMPacket> zm_packet = *it;
|
std::shared_ptr<ZMPacket> zm_packet = *it;
|
||||||
|
@ -247,6 +246,7 @@ void PacketQueue::clearPackets(const std::shared_ptr<ZMPacket> &add_packet) {
|
||||||
Debug(1, "trying lock on first packet");
|
Debug(1, "trying lock on first packet");
|
||||||
ZMLockedPacket *lp = new ZMLockedPacket(zm_packet);
|
ZMLockedPacket *lp = new ZMLockedPacket(zm_packet);
|
||||||
if (lp->trylock()) {
|
if (lp->trylock()) {
|
||||||
|
int video_packets_to_delete = 0; // This is a count of how many packets we will delete so we know when to stop looking
|
||||||
Debug(1, "Have lock on first packet");
|
Debug(1, "Have lock on first packet");
|
||||||
++it;
|
++it;
|
||||||
delete lp;
|
delete lp;
|
||||||
|
@ -282,7 +282,7 @@ void PacketQueue::clearPackets(const std::shared_ptr<ZMPacket> &add_packet) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
it++;
|
++it;
|
||||||
} // end while
|
} // end while
|
||||||
}
|
}
|
||||||
} // end if first packet not locked
|
} // end if first packet not locked
|
||||||
|
@ -292,7 +292,7 @@ void PacketQueue::clearPackets(const std::shared_ptr<ZMPacket> &add_packet) {
|
||||||
);
|
);
|
||||||
if (next_front != pktQueue.begin()) {
|
if (next_front != pktQueue.begin()) {
|
||||||
while (pktQueue.begin() != next_front) {
|
while (pktQueue.begin() != next_front) {
|
||||||
std::shared_ptr<ZMPacket> zm_packet = *pktQueue.begin();
|
zm_packet = *pktQueue.begin();
|
||||||
if (!zm_packet) {
|
if (!zm_packet) {
|
||||||
Error("NULL zm_packet in queue");
|
Error("NULL zm_packet in queue");
|
||||||
continue;
|
continue;
|
||||||
|
@ -478,10 +478,10 @@ packetqueue_iterator *PacketQueue::get_event_start_packet_it(
|
||||||
}
|
}
|
||||||
(*it)--;
|
(*it)--;
|
||||||
}
|
}
|
||||||
|
packet = *(*it);
|
||||||
}
|
}
|
||||||
// it either points to beginning or we have seen pre_event_count video packets.
|
// it either points to beginning or we have seen pre_event_count video packets.
|
||||||
|
|
||||||
packet = *(*it);
|
|
||||||
if (pre_event_count) {
|
if (pre_event_count) {
|
||||||
if (packet->image_index < (int)pre_event_count) {
|
if (packet->image_index < (int)pre_event_count) {
|
||||||
// probably just starting up
|
// probably just starting up
|
||||||
|
|
|
@ -95,7 +95,7 @@ std::string Authenticator::quote( const std::string &src ) {
|
||||||
return ReplaceAll(ReplaceAll(src, "\\", "\\\\"), "\"", "\\\"");
|
return ReplaceAll(ReplaceAll(src, "\\", "\\\\"), "\"", "\\\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Authenticator::getAuthHeader(std::string method, std::string uri) {
|
std::string Authenticator::getAuthHeader(const std::string &method, const std::string &uri) {
|
||||||
std::string result = "Authorization: ";
|
std::string result = "Authorization: ";
|
||||||
if ( fAuthMethod == AUTH_BASIC ) {
|
if ( fAuthMethod == AUTH_BASIC ) {
|
||||||
result += "Basic " + Base64Encode(username() + ":" + password());
|
result += "Basic " + Base64Encode(username() + ":" + password());
|
||||||
|
|
|
@ -47,8 +47,8 @@ public:
|
||||||
AuthMethod auth_method() const { return fAuthMethod; }
|
AuthMethod auth_method() const { return fAuthMethod; }
|
||||||
|
|
||||||
std::string computeDigestResponse(const std::string &cmd, const std::string &url);
|
std::string computeDigestResponse(const std::string &cmd, const std::string &url);
|
||||||
void authHandleHeader( std::string headerData );
|
void authHandleHeader(std::string headerData);
|
||||||
std::string getAuthHeader( std::string method, std::string path );
|
std::string getAuthHeader(const std::string &method, const std::string &path);
|
||||||
void checkAuthResponse(const std::string &response);
|
void checkAuthResponse(const std::string &response);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -23,13 +23,13 @@ ZoneMinderDeviceSource::ZoneMinderDeviceSource(
|
||||||
unsigned int queueSize
|
unsigned int queueSize
|
||||||
) :
|
) :
|
||||||
FramedSource(env),
|
FramedSource(env),
|
||||||
|
m_eventTriggerId(envir().taskScheduler().createEventTrigger(ZoneMinderDeviceSource::deliverFrameStub)),
|
||||||
m_stream(stream),
|
m_stream(stream),
|
||||||
m_monitor(std::move(monitor)),
|
m_monitor(std::move(monitor)),
|
||||||
m_packetqueue(nullptr),
|
m_packetqueue(nullptr),
|
||||||
m_packetqueue_it(nullptr),
|
m_packetqueue_it(nullptr),
|
||||||
m_queueSize(queueSize)
|
m_queueSize(queueSize)
|
||||||
{
|
{
|
||||||
m_eventTriggerId = envir().taskScheduler().createEventTrigger(ZoneMinderDeviceSource::deliverFrameStub);
|
|
||||||
memset(&m_thid, 0, sizeof(m_thid));
|
memset(&m_thid, 0, sizeof(m_thid));
|
||||||
memset(&m_mutex, 0, sizeof(m_mutex));
|
memset(&m_mutex, 0, sizeof(m_mutex));
|
||||||
if ( m_monitor ) {
|
if ( m_monitor ) {
|
||||||
|
|
|
@ -22,7 +22,7 @@ ADTS_ZoneMinderFifoSource::ADTS_ZoneMinderFifoSource(
|
||||||
std::shared_ptr<xop::RtspServer>& rtspServer,
|
std::shared_ptr<xop::RtspServer>& rtspServer,
|
||||||
xop::MediaSessionId sessionId,
|
xop::MediaSessionId sessionId,
|
||||||
xop::MediaChannelId channelId,
|
xop::MediaChannelId channelId,
|
||||||
std::string fifo
|
const std::string &fifo
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
ZoneMinderFifoAudioSource(rtspServer, sessionId, channelId, fifo)
|
ZoneMinderFifoAudioSource(rtspServer, sessionId, channelId, fifo)
|
||||||
|
|
|
@ -26,7 +26,7 @@ class ADTS_ZoneMinderFifoSource : public ZoneMinderFifoAudioSource {
|
||||||
std::shared_ptr<xop::RtspServer>& rtspServer,
|
std::shared_ptr<xop::RtspServer>& rtspServer,
|
||||||
xop::MediaSessionId sessionId,
|
xop::MediaSessionId sessionId,
|
||||||
xop::MediaChannelId channelId,
|
xop::MediaChannelId channelId,
|
||||||
std::string fifo
|
const std::string &fifo
|
||||||
);
|
);
|
||||||
|
|
||||||
virtual ~ADTS_ZoneMinderFifoSource() {}
|
virtual ~ADTS_ZoneMinderFifoSource() {}
|
||||||
|
|
|
@ -23,7 +23,7 @@ H264_ZoneMinderFifoSource::H264_ZoneMinderFifoSource(
|
||||||
std::shared_ptr<xop::RtspServer>& rtspServer,
|
std::shared_ptr<xop::RtspServer>& rtspServer,
|
||||||
xop::MediaSessionId sessionId,
|
xop::MediaSessionId sessionId,
|
||||||
xop::MediaChannelId channelId,
|
xop::MediaChannelId channelId,
|
||||||
std::string fifo
|
const std::string &fifo
|
||||||
)
|
)
|
||||||
: H26X_ZoneMinderFifoSource(rtspServer, sessionId, channelId, fifo)
|
: H26X_ZoneMinderFifoSource(rtspServer, sessionId, channelId, fifo)
|
||||||
{
|
{
|
||||||
|
@ -96,7 +96,7 @@ H265_ZoneMinderFifoSource::H265_ZoneMinderFifoSource(
|
||||||
std::shared_ptr<xop::RtspServer>& rtspServer,
|
std::shared_ptr<xop::RtspServer>& rtspServer,
|
||||||
xop::MediaSessionId sessionId,
|
xop::MediaSessionId sessionId,
|
||||||
xop::MediaChannelId channelId,
|
xop::MediaChannelId channelId,
|
||||||
std::string fifo
|
const std::string &fifo
|
||||||
)
|
)
|
||||||
: H26X_ZoneMinderFifoSource(rtspServer, sessionId, channelId, fifo)
|
: H26X_ZoneMinderFifoSource(rtspServer, sessionId, channelId, fifo)
|
||||||
{
|
{
|
||||||
|
@ -199,12 +199,12 @@ unsigned char* H26X_ZoneMinderFifoSource::extractFrame(unsigned char* frame, si
|
||||||
Debug(4, "ExtractFrame: %p %zu", frame, size);
|
Debug(4, "ExtractFrame: %p %zu", frame, size);
|
||||||
outsize = 0;
|
outsize = 0;
|
||||||
size_t markerLength = 0;
|
size_t markerLength = 0;
|
||||||
size_t endMarkerLength = 0;
|
|
||||||
m_frameType = 0;
|
m_frameType = 0;
|
||||||
unsigned char *startFrame = nullptr;
|
unsigned char *startFrame = nullptr;
|
||||||
if ( size >= 3 )
|
if (size >= 3)
|
||||||
startFrame = this->findMarker(frame, size, markerLength);
|
startFrame = this->findMarker(frame, size, markerLength);
|
||||||
if ( startFrame != nullptr ) {
|
if (startFrame != nullptr) {
|
||||||
|
size_t endMarkerLength = 0;
|
||||||
Debug(4, "startFrame: %p marker Length %zu", startFrame, markerLength);
|
Debug(4, "startFrame: %p marker Length %zu", startFrame, markerLength);
|
||||||
m_frameType = startFrame[markerLength];
|
m_frameType = startFrame[markerLength];
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,7 @@ class H264_ZoneMinderFifoSource : public H26X_ZoneMinderFifoSource {
|
||||||
std::shared_ptr<xop::RtspServer>& rtspServer,
|
std::shared_ptr<xop::RtspServer>& rtspServer,
|
||||||
xop::MediaSessionId sessionId,
|
xop::MediaSessionId sessionId,
|
||||||
xop::MediaChannelId channelId,
|
xop::MediaChannelId channelId,
|
||||||
std::string fifo
|
const std::string &fifo
|
||||||
);
|
);
|
||||||
|
|
||||||
// overide ZoneMinderFifoSource
|
// overide ZoneMinderFifoSource
|
||||||
|
@ -63,7 +63,7 @@ class H265_ZoneMinderFifoSource : public H26X_ZoneMinderFifoSource {
|
||||||
std::shared_ptr<xop::RtspServer>& rtspServer,
|
std::shared_ptr<xop::RtspServer>& rtspServer,
|
||||||
xop::MediaSessionId sessionId,
|
xop::MediaSessionId sessionId,
|
||||||
xop::MediaChannelId channelId,
|
xop::MediaChannelId channelId,
|
||||||
std::string fifo
|
const std::string &fifo
|
||||||
);
|
);
|
||||||
|
|
||||||
// overide ZoneMinderFifoSource
|
// overide ZoneMinderFifoSource
|
||||||
|
|
|
@ -24,7 +24,7 @@ ZoneMinderFifoSource::ZoneMinderFifoSource(
|
||||||
std::shared_ptr<xop::RtspServer>& rtspServer,
|
std::shared_ptr<xop::RtspServer>& rtspServer,
|
||||||
xop::MediaSessionId sessionId,
|
xop::MediaSessionId sessionId,
|
||||||
xop::MediaChannelId channelId,
|
xop::MediaChannelId channelId,
|
||||||
std::string fifo
|
const std::string &fifo
|
||||||
) :
|
) :
|
||||||
stop_(false),
|
stop_(false),
|
||||||
m_rtspServer(rtspServer),
|
m_rtspServer(rtspServer),
|
||||||
|
@ -225,7 +225,7 @@ int ZoneMinderFifoSource::getNextFrame() {
|
||||||
if (bytes_needed > 0) {
|
if (bytes_needed > 0) {
|
||||||
Debug(4, "Need another %d bytes. Trying to read them", bytes_needed);
|
Debug(4, "Need another %d bytes. Trying to read them", bytes_needed);
|
||||||
while (bytes_needed) {
|
while (bytes_needed) {
|
||||||
int bytes_read = m_buffer.read_into(m_fd, bytes_needed);
|
bytes_read = m_buffer.read_into(m_fd, bytes_needed);
|
||||||
if (bytes_read <= 0) {
|
if (bytes_read <= 0) {
|
||||||
Debug(1, "Failed to read another %d bytes, got %d.", bytes_needed, bytes_read);
|
Debug(1, "Failed to read another %d bytes, got %d.", bytes_needed, bytes_read);
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -35,7 +35,7 @@ class ZoneMinderFifoSource {
|
||||||
std::shared_ptr<xop::RtspServer>& rtspServer,
|
std::shared_ptr<xop::RtspServer>& rtspServer,
|
||||||
xop::MediaSessionId sessionId,
|
xop::MediaSessionId sessionId,
|
||||||
xop::MediaChannelId channelId,
|
xop::MediaChannelId channelId,
|
||||||
std::string fifo
|
const std::string &fifo
|
||||||
);
|
);
|
||||||
virtual ~ZoneMinderFifoSource();
|
virtual ~ZoneMinderFifoSource();
|
||||||
|
|
||||||
|
|
|
@ -15,9 +15,11 @@ ZoneMinderFifoVideoSource::ZoneMinderFifoVideoSource(
|
||||||
std::shared_ptr<xop::RtspServer>& rtspServer,
|
std::shared_ptr<xop::RtspServer>& rtspServer,
|
||||||
xop::MediaSessionId sessionId,
|
xop::MediaSessionId sessionId,
|
||||||
xop::MediaChannelId channelId,
|
xop::MediaChannelId channelId,
|
||||||
std::string fifo
|
const std::string &fifo
|
||||||
) :
|
) :
|
||||||
ZoneMinderFifoSource(rtspServer, sessionId, channelId, fifo)
|
ZoneMinderFifoSource(rtspServer, sessionId, channelId, fifo),
|
||||||
|
m_width(0),
|
||||||
|
m_height(0)
|
||||||
{
|
{
|
||||||
m_timeBase = {1, 90000};
|
m_timeBase = {1, 90000};
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ class ZoneMinderFifoVideoSource: public ZoneMinderFifoSource {
|
||||||
std::shared_ptr<xop::RtspServer>& rtspServer,
|
std::shared_ptr<xop::RtspServer>& rtspServer,
|
||||||
xop::MediaSessionId sessionId,
|
xop::MediaSessionId sessionId,
|
||||||
xop::MediaChannelId channelId,
|
xop::MediaChannelId channelId,
|
||||||
std::string fifo
|
const std::string &fifo
|
||||||
);
|
);
|
||||||
protected:
|
protected:
|
||||||
void PushFrame(const uint8_t *data, size_t size, int64_t pts) override;
|
void PushFrame(const uint8_t *data, size_t size, int64_t pts) override;
|
||||||
|
|
|
@ -1,241 +0,0 @@
|
||||||
/* ---------------------------------------------------------------------------
|
|
||||||
**
|
|
||||||
** H264_DeviceSource.cpp
|
|
||||||
**
|
|
||||||
** H264 Live555 source
|
|
||||||
**
|
|
||||||
** -------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "zm_rtsp_server_h264_device_source.h"
|
|
||||||
|
|
||||||
#include "zm_config.h"
|
|
||||||
#include "zm_logger.h"
|
|
||||||
#include "zm_rtsp_server_frame.h"
|
|
||||||
#include <iomanip>
|
|
||||||
#include <sstream>
|
|
||||||
|
|
||||||
#if HAVE_RTSP_SERVER
|
|
||||||
// live555
|
|
||||||
#include <Base64.hh>
|
|
||||||
|
|
||||||
// ---------------------------------
|
|
||||||
// H264 ZoneMinder FramedSource
|
|
||||||
// ---------------------------------
|
|
||||||
//
|
|
||||||
H264_ZoneMinderDeviceSource::H264_ZoneMinderDeviceSource(
|
|
||||||
UsageEnvironment& env,
|
|
||||||
std::shared_ptr<Monitor> monitor,
|
|
||||||
AVStream *stream,
|
|
||||||
unsigned int queueSize,
|
|
||||||
bool repeatConfig,
|
|
||||||
bool keepMarker)
|
|
||||||
: H26X_ZoneMinderDeviceSource(env, std::move(monitor), stream, queueSize, repeatConfig, keepMarker)
|
|
||||||
{
|
|
||||||
// extradata appears to simply be the SPS and PPS NAL's
|
|
||||||
this->splitFrames(
|
|
||||||
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
|
|
||||||
m_stream->codecpar->extradata, m_stream->codecpar->extradata_size
|
|
||||||
#else
|
|
||||||
m_stream->codec->extradata, m_stream->codec->extradata_size
|
|
||||||
#endif
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// split packet into frames
|
|
||||||
std::list< std::pair<unsigned char*, size_t> > H264_ZoneMinderDeviceSource::splitFrames(unsigned char* frame, unsigned frameSize) {
|
|
||||||
std::list< std::pair<unsigned char*, size_t> > frameList;
|
|
||||||
|
|
||||||
size_t bufSize = frameSize;
|
|
||||||
size_t size = 0;
|
|
||||||
unsigned char* buffer = this->extractFrame(frame, bufSize, size);
|
|
||||||
while ( buffer != nullptr ) {
|
|
||||||
switch ( m_frameType & 0x1F ) {
|
|
||||||
case 7:
|
|
||||||
Debug(1, "SPS_Size: %d bufSize %d", size, bufSize);
|
|
||||||
m_sps.assign((char*)buffer, size);
|
|
||||||
break;
|
|
||||||
case 8:
|
|
||||||
Debug(1, "PPS_Size: %d bufSize %d", size, bufSize);
|
|
||||||
m_pps.assign((char*)buffer, size);
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
Debug(1, "IDR_Size: %d bufSize %d", size, 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:
|
|
||||||
Debug(1, "Unknown frametype!? %d %d", m_frameType, m_frameType & 0x1F);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( !m_sps.empty() && !m_pps.empty() ) {
|
|
||||||
u_int32_t profile_level_id = 0;
|
|
||||||
if ( m_sps.size() >= 4 ) profile_level_id = (m_sps[1]<<16)|(m_sps[2]<<8)|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());
|
|
||||||
Debug(1, "auxLine: %s", m_auxLine.c_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);
|
|
||||||
} // end while buffer
|
|
||||||
return frameList;
|
|
||||||
}
|
|
||||||
|
|
||||||
H265_ZoneMinderDeviceSource::H265_ZoneMinderDeviceSource(
|
|
||||||
UsageEnvironment& env,
|
|
||||||
std::shared_ptr<Monitor> monitor,
|
|
||||||
AVStream *stream,
|
|
||||||
unsigned int queueSize,
|
|
||||||
bool repeatConfig,
|
|
||||||
bool keepMarker)
|
|
||||||
: H26X_ZoneMinderDeviceSource(env, std::move(monitor), stream, queueSize, repeatConfig, keepMarker)
|
|
||||||
{
|
|
||||||
// extradata appears to simply be the SPS and PPS NAL's
|
|
||||||
this->splitFrames(
|
|
||||||
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
|
|
||||||
m_stream->codecpar->extradata, m_stream->codecpar->extradata_size
|
|
||||||
#else
|
|
||||||
m_stream->codec->extradata, m_stream->codec->extradata_size
|
|
||||||
#endif
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// split packet in frames
|
|
||||||
std::list< std::pair<unsigned char*,size_t> >
|
|
||||||
H265_ZoneMinderDeviceSource::splitFrames(unsigned char* frame, unsigned frameSize) {
|
|
||||||
std::list< std::pair<unsigned char*,size_t> > frameList;
|
|
||||||
|
|
||||||
size_t bufSize = frameSize;
|
|
||||||
size_t size = 0;
|
|
||||||
unsigned char* buffer = this->extractFrame(frame, bufSize, size);
|
|
||||||
while ( buffer != nullptr ) {
|
|
||||||
switch ((m_frameType&0x7E)>>1) {
|
|
||||||
case 32:
|
|
||||||
Debug(1, "VPS_Size: %d bufSize %d", size, bufSize);
|
|
||||||
m_vps.assign((char*)buffer,size);
|
|
||||||
break;
|
|
||||||
case 33:
|
|
||||||
Debug(1, "SPS_Size: %d bufSize %d", size, bufSize);
|
|
||||||
m_sps.assign((char*)buffer,size);
|
|
||||||
break;
|
|
||||||
case 34:
|
|
||||||
Debug(1, "PPS_Size: %d bufSize %d", size, bufSize);
|
|
||||||
m_pps.assign((char*)buffer,size);
|
|
||||||
break;
|
|
||||||
case 19:
|
|
||||||
case 20:
|
|
||||||
Debug(1, "IDR_Size: %d bufSize %d", size, 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:
|
|
||||||
Debug(1, "Unknown frametype!? %d %d", m_frameType, ((m_frameType & 0x7E) >> 1));
|
|
||||||
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());
|
|
||||||
Debug(1, "Assigned auxLine to %s", m_auxLine.c_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);
|
|
||||||
} // end while buffer
|
|
||||||
if ( bufSize ) {
|
|
||||||
Debug(1, "%d bytes remaining", bufSize);
|
|
||||||
}
|
|
||||||
return frameList;
|
|
||||||
} // end H265_ZoneMinderDeviceSource::splitFrames(unsigned char* frame, unsigned frameSize)
|
|
||||||
|
|
||||||
unsigned char * H26X_ZoneMinderDeviceSource::findMarker(
|
|
||||||
unsigned char *frame, size_t size, size_t &length
|
|
||||||
) {
|
|
||||||
//Debug(1, "findMarker %p %d", frame, size);
|
|
||||||
unsigned char *start = nullptr;
|
|
||||||
for ( size_t i = 0; i < size-2; i += 1 ) {
|
|
||||||
//Debug(1, "%d: %d %d %d", i, frame[i], frame[i+1], frame[i+2]);
|
|
||||||
if ( (frame[i] == 0) and (frame[i+1]) == 0 and (frame[i+2] == 1) ) {
|
|
||||||
if ( i and (frame[i-1] == 0) ) {
|
|
||||||
start = frame + i - 1;
|
|
||||||
length = sizeof(H264marker);
|
|
||||||
} else {
|
|
||||||
start = frame + i;
|
|
||||||
length = sizeof(H264shortmarker);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return start;
|
|
||||||
}
|
|
||||||
|
|
||||||
// extract a frame
|
|
||||||
unsigned char* H26X_ZoneMinderDeviceSource::extractFrame(unsigned char* frame, size_t& size, size_t& outsize) {
|
|
||||||
unsigned char *outFrame = nullptr;
|
|
||||||
Debug(1, "ExtractFrame: %p %d", frame, size);
|
|
||||||
outsize = 0;
|
|
||||||
size_t markerLength = 0;
|
|
||||||
size_t endMarkerLength = 0;
|
|
||||||
m_frameType = 0;
|
|
||||||
unsigned char *startFrame = nullptr;
|
|
||||||
if ( size >= 3 )
|
|
||||||
startFrame = this->findMarker(frame, size, markerLength);
|
|
||||||
if ( startFrame != nullptr ) {
|
|
||||||
Debug(1, "startFrame: %p marker Length %d", startFrame, markerLength);
|
|
||||||
m_frameType = startFrame[markerLength];
|
|
||||||
|
|
||||||
int remainingSize = size-(startFrame-frame+markerLength);
|
|
||||||
unsigned char *endFrame = nullptr;
|
|
||||||
if ( remainingSize > 3 ) {
|
|
||||||
endFrame = this->findMarker(startFrame+markerLength, remainingSize, endMarkerLength);
|
|
||||||
}
|
|
||||||
Debug(1, "endFrame: %p marker Length %d, remaining size %d", endFrame, endMarkerLength, remainingSize);
|
|
||||||
|
|
||||||
if ( m_keepMarker ) {
|
|
||||||
size -= startFrame-frame;
|
|
||||||
outFrame = startFrame;
|
|
||||||
} else {
|
|
||||||
size -= startFrame-frame+markerLength;
|
|
||||||
outFrame = &startFrame[markerLength];
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( endFrame != nullptr ) {
|
|
||||||
outsize = endFrame - outFrame;
|
|
||||||
} else {
|
|
||||||
outsize = size;
|
|
||||||
}
|
|
||||||
size -= outsize;
|
|
||||||
Debug(1, "Have frame type: %d size %d, keepmarker %d", m_frameType, outsize, m_keepMarker);
|
|
||||||
} else if ( size >= sizeof(H264shortmarker) ) {
|
|
||||||
Info("No marker found");
|
|
||||||
}
|
|
||||||
|
|
||||||
return outFrame;
|
|
||||||
}
|
|
||||||
#endif // HAVE_RTSP_SERVER
|
|
|
@ -1,104 +0,0 @@
|
||||||
/* ---------------------------------------------------------------------------
|
|
||||||
** 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_ZoneMinderDeviceSource.h
|
|
||||||
**
|
|
||||||
** H264 ZoneMinder live555 source
|
|
||||||
**
|
|
||||||
** -------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifndef ZM_RTSP_H264_DEVICE_SOURCE_H
|
|
||||||
#define ZM_RTSP_H264_DEVICE_SOURCE_H
|
|
||||||
|
|
||||||
#include "zm_config.h"
|
|
||||||
#include "zm_rtsp_server_device_source.h"
|
|
||||||
|
|
||||||
// ---------------------------------
|
|
||||||
// H264 ZoneMinder FramedSource
|
|
||||||
// ---------------------------------
|
|
||||||
#if HAVE_RTSP_SERVER
|
|
||||||
class H26X_ZoneMinderDeviceSource : public ZoneMinderDeviceSource {
|
|
||||||
protected:
|
|
||||||
H26X_ZoneMinderDeviceSource(
|
|
||||||
UsageEnvironment& env,
|
|
||||||
std::shared_ptr<Monitor> monitor,
|
|
||||||
AVStream *stream,
|
|
||||||
unsigned int queueSize,
|
|
||||||
bool repeatConfig,
|
|
||||||
bool keepMarker)
|
|
||||||
:
|
|
||||||
ZoneMinderDeviceSource(env, std::move(monitor), stream, queueSize),
|
|
||||||
m_repeatConfig(repeatConfig),
|
|
||||||
m_keepMarker(keepMarker),
|
|
||||||
m_frameType(0) { }
|
|
||||||
|
|
||||||
virtual ~H26X_ZoneMinderDeviceSource() {}
|
|
||||||
|
|
||||||
virtual unsigned char* extractFrame(unsigned char* frame, size_t& size, size_t& outsize);
|
|
||||||
virtual unsigned char* findMarker(unsigned char *frame, size_t size, size_t &length);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
std::string m_sps;
|
|
||||||
std::string m_pps;
|
|
||||||
bool m_repeatConfig;
|
|
||||||
bool m_keepMarker;
|
|
||||||
int m_frameType;
|
|
||||||
};
|
|
||||||
|
|
||||||
class H264_ZoneMinderDeviceSource : public H26X_ZoneMinderDeviceSource {
|
|
||||||
public:
|
|
||||||
static H264_ZoneMinderDeviceSource* createNew(
|
|
||||||
UsageEnvironment& env,
|
|
||||||
std::shared_ptr<Monitor> monitor,
|
|
||||||
AVStream *stream,
|
|
||||||
unsigned int queueSize,
|
|
||||||
bool repeatConfig,
|
|
||||||
bool keepMarker) {
|
|
||||||
return new H264_ZoneMinderDeviceSource(env, std::move(monitor), stream, queueSize, repeatConfig, keepMarker);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
H264_ZoneMinderDeviceSource(
|
|
||||||
UsageEnvironment& env,
|
|
||||||
std::shared_ptr<Monitor> monitor,
|
|
||||||
AVStream *stream,
|
|
||||||
unsigned int queueSize,
|
|
||||||
bool repeatConfig,
|
|
||||||
bool keepMarker);
|
|
||||||
|
|
||||||
// overide ZoneMinderDeviceSource
|
|
||||||
virtual std::list< std::pair<unsigned char*,size_t> > splitFrames(unsigned char* frame, unsigned frameSize);
|
|
||||||
};
|
|
||||||
|
|
||||||
class H265_ZoneMinderDeviceSource : public H26X_ZoneMinderDeviceSource {
|
|
||||||
public:
|
|
||||||
static H265_ZoneMinderDeviceSource* createNew(
|
|
||||||
UsageEnvironment& env,
|
|
||||||
std::shared_ptr<Monitor> monitor,
|
|
||||||
AVStream *stream,
|
|
||||||
unsigned int queueSize,
|
|
||||||
bool repeatConfig,
|
|
||||||
bool keepMarker) {
|
|
||||||
return new H265_ZoneMinderDeviceSource(env, std::move(monitor), stream, queueSize, repeatConfig, keepMarker);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
H265_ZoneMinderDeviceSource(
|
|
||||||
UsageEnvironment& env,
|
|
||||||
std::shared_ptr<Monitor> monitor,
|
|
||||||
AVStream *stream,
|
|
||||||
unsigned int queueSize,
|
|
||||||
bool repeatConfig,
|
|
||||||
bool keepMarker);
|
|
||||||
|
|
||||||
// overide ZoneMinderDeviceSource
|
|
||||||
virtual std::list< std::pair<unsigned char*,size_t> > splitFrames(unsigned char* frame, unsigned frameSize);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
std::string m_vps;
|
|
||||||
};
|
|
||||||
#endif // HAVE_RTSP_SERVER
|
|
||||||
|
|
||||||
#endif // ZM_RTSP_H264_DEVICE_SOURCE_H
|
|
|
@ -66,8 +66,9 @@ RTPSink* BaseServerMediaSubsession::createSink(
|
||||||
sink = VP9VideoRTPSink::createNew(env, rtpGroupsock, rtpPayloadTypeIfDynamic);
|
sink = VP9VideoRTPSink::createNew(env, rtpGroupsock, rtpPayloadTypeIfDynamic);
|
||||||
} else if (format == "video/H265") {
|
} else if (format == "video/H265") {
|
||||||
sink = H265VideoRTPSink::createNew(env, rtpGroupsock, rtpPayloadTypeIfDynamic);
|
sink = H265VideoRTPSink::createNew(env, rtpGroupsock, rtpPayloadTypeIfDynamic);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
} else if (format == "audio/AAC") {
|
else if (format == "audio/AAC") {
|
||||||
ADTS_ZoneMinderFifoSource *adts_source = (ADTS_ZoneMinderFifoSource *)(m_replicator->inputSource());
|
ADTS_ZoneMinderFifoSource *adts_source = (ADTS_ZoneMinderFifoSource *)(m_replicator->inputSource());
|
||||||
sink = MPEG4GenericRTPSink::createNew(env, rtpGroupsock,
|
sink = MPEG4GenericRTPSink::createNew(env, rtpGroupsock,
|
||||||
rtpPayloadTypeIfDynamic,
|
rtpPayloadTypeIfDynamic,
|
||||||
|
|
|
@ -252,13 +252,17 @@ bool VideoStore::open() {
|
||||||
ret = av_hwdevice_ctx_create(&hw_device_ctx,
|
ret = av_hwdevice_ctx_create(&hw_device_ctx,
|
||||||
codec_data[i].hwdevice_type,
|
codec_data[i].hwdevice_type,
|
||||||
nullptr, nullptr, 0);
|
nullptr, nullptr, 0);
|
||||||
|
if (0>ret) {
|
||||||
|
Error("Failed to create hwdevice_ctx");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
AVBufferRef *hw_frames_ref;
|
AVBufferRef *hw_frames_ref;
|
||||||
AVHWFramesContext *frames_ctx = nullptr;
|
AVHWFramesContext *frames_ctx = nullptr;
|
||||||
|
|
||||||
if (!(hw_frames_ref = av_hwframe_ctx_alloc(hw_device_ctx))) {
|
if (!(hw_frames_ref = av_hwframe_ctx_alloc(hw_device_ctx))) {
|
||||||
Error("Failed to create hwaccel frame context.");
|
Error("Failed to create hwaccel frame context.");
|
||||||
return -1;
|
continue;
|
||||||
}
|
}
|
||||||
frames_ctx = (AVHWFramesContext *)(hw_frames_ref->data);
|
frames_ctx = (AVHWFramesContext *)(hw_frames_ref->data);
|
||||||
frames_ctx->format = codec_data[i].hw_pix_fmt;
|
frames_ctx->format = codec_data[i].hw_pix_fmt;
|
||||||
|
@ -537,7 +541,6 @@ bool VideoStore::open() {
|
||||||
} // end bool VideoStore::open()
|
} // end bool VideoStore::open()
|
||||||
|
|
||||||
void VideoStore::flush_codecs() {
|
void VideoStore::flush_codecs() {
|
||||||
int ret;
|
|
||||||
// The codec queues data. We need to send a flush command and out
|
// The codec queues data. We need to send a flush command and out
|
||||||
// whatever we get. Failures are not fatal.
|
// whatever we get. Failures are not fatal.
|
||||||
AVPacket pkt;
|
AVPacket pkt;
|
||||||
|
@ -555,7 +558,7 @@ void VideoStore::flush_codecs() {
|
||||||
#endif
|
#endif
|
||||||
) ) {
|
) ) {
|
||||||
// Put encoder into flushing mode
|
// Put encoder into flushing mode
|
||||||
while ( (ret = zm_send_frame_receive_packet(video_out_ctx, nullptr, pkt) ) > 0 ) {
|
while ((zm_send_frame_receive_packet(video_out_ctx, nullptr, pkt)) > 0) {
|
||||||
av_packet_rescale_ts(&pkt,
|
av_packet_rescale_ts(&pkt,
|
||||||
video_out_ctx->time_base,
|
video_out_ctx->time_base,
|
||||||
video_out_stream->time_base);
|
video_out_stream->time_base);
|
||||||
|
@ -1013,7 +1016,6 @@ int VideoStore::writePacket(const std::shared_ptr<ZMPacket> &ipkt) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int VideoStore::writeVideoFramePacket(const std::shared_ptr<ZMPacket> &zm_packet) {
|
int VideoStore::writeVideoFramePacket(const std::shared_ptr<ZMPacket> &zm_packet) {
|
||||||
int ret;
|
|
||||||
frame_count += 1;
|
frame_count += 1;
|
||||||
|
|
||||||
// if we have to transcode
|
// if we have to transcode
|
||||||
|
@ -1070,6 +1072,7 @@ int VideoStore::writeVideoFramePacket(const std::shared_ptr<ZMPacket> &zm_packet
|
||||||
|
|
||||||
#if HAVE_LIBAVUTIL_HWCONTEXT_H
|
#if HAVE_LIBAVUTIL_HWCONTEXT_H
|
||||||
if (video_out_ctx->hw_frames_ctx) {
|
if (video_out_ctx->hw_frames_ctx) {
|
||||||
|
int ret;
|
||||||
if (!(hw_frame = av_frame_alloc())) {
|
if (!(hw_frame = av_frame_alloc())) {
|
||||||
ret = AVERROR(ENOMEM);
|
ret = AVERROR(ENOMEM);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1131,7 +1134,7 @@ int VideoStore::writeVideoFramePacket(const std::shared_ptr<ZMPacket> &zm_packet
|
||||||
opkt.data = nullptr;
|
opkt.data = nullptr;
|
||||||
opkt.size = 0;
|
opkt.size = 0;
|
||||||
|
|
||||||
ret = zm_send_frame_receive_packet(video_out_ctx, frame, opkt);
|
int ret = zm_send_frame_receive_packet(video_out_ctx, frame, opkt);
|
||||||
if (ret <= 0) {
|
if (ret <= 0) {
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
Error("Could not send frame (error '%s')", av_make_error_string(ret).c_str());
|
Error("Could not send frame (error '%s')", av_make_error_string(ret).c_str());
|
||||||
|
|
Loading…
Reference in New Issue