wip
This commit is contained in:
parent
279e0d8bcf
commit
448294f593
|
@ -241,7 +241,7 @@ int FfmpegCamera::OpenFfmpeg() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ret < 0 ) {
|
if ( ret < 0 ) {
|
||||||
Warning("Could not set rtsp_transport method '%s'\n", method.c_str());
|
Warning("Could not set rtsp_transport method '%s'", method.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
Debug(1, "Calling avformat_open_input for %s", mPath.c_str());
|
Debug(1, "Calling avformat_open_input for %s", mPath.c_str());
|
||||||
|
|
|
@ -2082,6 +2082,10 @@ int LocalCamera::Capture( ZMPacket &zm_packet ) {
|
||||||
|
|
||||||
} /* prime capture */
|
} /* prime capture */
|
||||||
|
|
||||||
|
if ( ! zm_packet.image ) {
|
||||||
|
zm_packet.image = new Image(width, height, colours, subpixelorder);
|
||||||
|
}
|
||||||
|
|
||||||
if ( conversion_type != 0 ) {
|
if ( conversion_type != 0 ) {
|
||||||
|
|
||||||
Debug(3, "Performing format conversion");
|
Debug(3, "Performing format conversion");
|
||||||
|
|
|
@ -1630,6 +1630,7 @@ bool Monitor::Analyse() {
|
||||||
|
|
||||||
ZMPacket *snap;
|
ZMPacket *snap;
|
||||||
// Is it possible for snap->score to be ! -1?
|
// Is it possible for snap->score to be ! -1?
|
||||||
|
// get_analysis_packet will lock the packet
|
||||||
while ( ( snap = packetqueue->get_analysis_packet() ) && ( snap->score == -1 ) ) {
|
while ( ( snap = packetqueue->get_analysis_packet() ) && ( snap->score == -1 ) ) {
|
||||||
unsigned int index = snap->image_index;
|
unsigned int index = snap->image_index;
|
||||||
Debug(2, "Analysis index (%d), last_Write(%d)", index, shared_data->last_write_index);
|
Debug(2, "Analysis index (%d), last_Write(%d)", index, shared_data->last_write_index);
|
||||||
|
@ -1638,7 +1639,6 @@ bool Monitor::Analyse() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
snap->lock();
|
|
||||||
packets_processed += 1;
|
packets_processed += 1;
|
||||||
|
|
||||||
if ( snap->image_index == -1 ) {
|
if ( snap->image_index == -1 ) {
|
||||||
|
@ -2069,7 +2069,6 @@ void Monitor::ReloadLinkedMonitors(const char *p_linked_monitors) {
|
||||||
|
|
||||||
db_mutex.lock();
|
db_mutex.lock();
|
||||||
static char sql[ZM_SQL_SML_BUFSIZ];
|
static char sql[ZM_SQL_SML_BUFSIZ];
|
||||||
db_mutex.lock();
|
|
||||||
snprintf(sql, sizeof(sql), "SELECT Id, Name FROM Monitors WHERE Id = %d AND Function != 'None' AND Function != 'Monitor' AND Enabled = 1", link_ids[i] );
|
snprintf(sql, sizeof(sql), "SELECT Id, Name FROM Monitors WHERE Id = %d AND Function != 'None' AND Function != 'Monitor' AND Enabled = 1", link_ids[i] );
|
||||||
if ( mysql_query(&dbconn, sql) ) {
|
if ( mysql_query(&dbconn, sql) ) {
|
||||||
db_mutex.unlock();
|
db_mutex.unlock();
|
||||||
|
@ -2177,7 +2176,8 @@ int Monitor::LoadFfmpegMonitors(const char *file, Monitor **&monitors, Purpose p
|
||||||
int Monitor::Capture() {
|
int Monitor::Capture() {
|
||||||
static int FirstCapture = 1; // Used in de-interlacing to indicate whether this is the even or odd image
|
static int FirstCapture = 1; // Used in de-interlacing to indicate whether this is the even or odd image
|
||||||
|
|
||||||
unsigned int index = image_count % image_buffer_count;
|
unsigned int index = 0;
|
||||||
|
//image_count % image_buffer_count;
|
||||||
|
|
||||||
if ( (index == shared_data->last_read_index) && (function > MONITOR) ) {
|
if ( (index == shared_data->last_read_index) && (function > MONITOR) ) {
|
||||||
Warning("Buffer overrun at index %d, image %d, slow down capture, speed up analysis or increase ring buffer size", index, image_count);
|
Warning("Buffer overrun at index %d, image %d, slow down capture, speed up analysis or increase ring buffer size", index, image_count);
|
||||||
|
@ -2189,13 +2189,14 @@ int Monitor::Capture() {
|
||||||
shared_data->last_read_index = image_buffer_count;
|
shared_data->last_read_index = image_buffer_count;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Debug(2,"Capture: Current write index %d, last read index %d, current (%d)", shared_data->last_write_index, shared_data->last_read_index, index );
|
Debug(2,"Capture: Last write(capture) index %d, last read(analysis) index %d, current (%d)",
|
||||||
|
shared_data->last_write_index, shared_data->last_read_index, index );
|
||||||
}
|
}
|
||||||
|
|
||||||
ZMPacket *packet = &image_buffer[index];
|
ZMPacket *packet = new ZMPacket();
|
||||||
Debug(2,"before lock");
|
//&image_buffer[index];
|
||||||
|
Debug(2,"before packet lock");
|
||||||
packet->lock();
|
packet->lock();
|
||||||
Debug(2,"before reset");
|
|
||||||
packet->reset();
|
packet->reset();
|
||||||
Image* capture_image = packet->image;
|
Image* capture_image = packet->image;
|
||||||
int captureResult = 0;
|
int captureResult = 0;
|
||||||
|
@ -2243,23 +2244,23 @@ int Monitor::Capture() {
|
||||||
if ( packet->packet.stream_index != video_stream_id ) {
|
if ( packet->packet.stream_index != video_stream_id ) {
|
||||||
Debug(2, "Have audio packet (%d) != videostream_id:(%d) q.vpktcount(%d) event?(%d) ",
|
Debug(2, "Have audio packet (%d) != videostream_id:(%d) q.vpktcount(%d) event?(%d) ",
|
||||||
packet->packet.stream_index, video_stream_id, packetqueue->video_packet_count, ( event ? 1 : 0 ) );
|
packet->packet.stream_index, video_stream_id, packetqueue->video_packet_count, ( event ? 1 : 0 ) );
|
||||||
// Only queue if we have some video packets in there.
|
// Only queue if we have some video packets in there. Should push this logic into packetqueue
|
||||||
mutex.lock();
|
//mutex.lock();
|
||||||
if ( packetqueue->video_packet_count || event ) {
|
if ( packetqueue->video_packet_count || event ) {
|
||||||
// Need to copy it into another ZMPacket.
|
// Need to copy it into another ZMPacket.
|
||||||
ZMPacket *audio_packet = new ZMPacket(*packet);
|
//ZMPacket *audio_packet = new ZMPacket(*packet);
|
||||||
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
|
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
|
||||||
audio_packet->codec_type = camera->get_AudioStream()->codecpar->codec_type;
|
packet->codec_type = camera->get_AudioStream()->codecpar->codec_type;
|
||||||
#else
|
#else
|
||||||
audio_packet->codec_type = camera->get_AudioStream()->codec->codec_type;
|
packet->codec_type = camera->get_AudioStream()->codec->codec_type;
|
||||||
#endif
|
#endif
|
||||||
Debug(2, "Queueing packet");
|
Debug(2, "Queueing packet");
|
||||||
packetqueue->queuePacket(audio_packet);
|
packetqueue->queuePacket(packet);
|
||||||
}
|
}
|
||||||
// Don't update last_write_index because that is used for live streaming
|
// Don't update last_write_index because that is used for live streaming
|
||||||
//shared_data->last_write_time = image_buffer[index].timestamp->tv_sec;
|
//shared_data->last_write_time = image_buffer[index].timestamp->tv_sec;
|
||||||
|
|
||||||
mutex.unlock();
|
//mutex.unlock();
|
||||||
packet->unlock();
|
packet->unlock();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -2274,20 +2275,21 @@ int Monitor::Capture() {
|
||||||
//Debug(2,"About to decode");
|
//Debug(2,"About to decode");
|
||||||
if ( packet->decode(camera->get_VideoCodecContext()) ) {
|
if ( packet->decode(camera->get_VideoCodecContext()) ) {
|
||||||
//Debug(2,"Getimage");
|
//Debug(2,"Getimage");
|
||||||
packet->get_image();
|
packet->get_image( image_buffer[index].image );
|
||||||
}
|
}
|
||||||
// Have an av_packet,
|
// Have an av_packet,
|
||||||
}
|
}
|
||||||
|
|
||||||
Debug(2,"Before mutex lock");
|
//Debug(2,"Before mutex lock");
|
||||||
mutex.lock();
|
// FIXME this mutex is useless, packetqueue has it's own
|
||||||
|
//mutex.lock();
|
||||||
if ( packetqueue->video_packet_count || packet->keyframe || event ) {
|
if ( packetqueue->video_packet_count || packet->keyframe || event ) {
|
||||||
Debug(2, "Have video packet for index (%d)", index);
|
Debug(2, "Have video packet for index (%d)", index);
|
||||||
packetqueue->queuePacket(packet);
|
packetqueue->queuePacket(packet);
|
||||||
} else {
|
} else {
|
||||||
Debug(2, "Not queuing video packet for index (%d)", index);
|
Debug(2, "Not queuing video packet for index (%d)", index);
|
||||||
}
|
}
|
||||||
mutex.unlock();
|
//mutex.unlock();
|
||||||
|
|
||||||
/* Deinterlacing */
|
/* Deinterlacing */
|
||||||
if ( deinterlacing_value ) {
|
if ( deinterlacing_value ) {
|
||||||
|
@ -2355,7 +2357,7 @@ int Monitor::Capture() {
|
||||||
// assume that we are connected
|
// assume that we are connected
|
||||||
snprintf(sql, sizeof(sql),
|
snprintf(sql, sizeof(sql),
|
||||||
"INSERT INTO Monitor_Status (MonitorId,CaptureFPS,CaptureBandwidth,Status) "
|
"INSERT INTO Monitor_Status (MonitorId,CaptureFPS,CaptureBandwidth,Status) "
|
||||||
"VALUES (%d, %.2lf,%u) ON DUPLICATE KEY UPDATE "
|
"VALUES (%d, %.2lf, %u, 'Connected') ON DUPLICATE KEY UPDATE "
|
||||||
"CaptureFPS = %.2lf, CaptureBandwidth=%u, Status='Connected'",
|
"CaptureFPS = %.2lf, CaptureBandwidth=%u, Status='Connected'",
|
||||||
id, capture_fps, new_capture_bandwidth, capture_fps, new_capture_bandwidth);
|
id, capture_fps, new_capture_bandwidth, capture_fps, new_capture_bandwidth);
|
||||||
if ( mysql_query(&dbconn, sql) ) {
|
if ( mysql_query(&dbconn, sql) ) {
|
||||||
|
@ -2701,24 +2703,18 @@ Monitor::Orientation Monitor::getOrientation() const { return orientation; }
|
||||||
|
|
||||||
// Wait for camera to get an image, and then assign it as the base reference image. So this should be done as the first task in the analysis thread startup.
|
// Wait for camera to get an image, and then assign it as the base reference image. So this should be done as the first task in the analysis thread startup.
|
||||||
void Monitor::get_ref_image() {
|
void Monitor::get_ref_image() {
|
||||||
while (
|
ZMPacket * snap;
|
||||||
( shared_data->last_write_index == (unsigned int)image_buffer_count )
|
while ( ((!( snap = packetqueue->get_analysis_packet())) || ( snap->image_index == -1 )) && !zm_terminate) {
|
||||||
&&
|
Debug(1, "Waiting for capture daemon lastwriteindex(%d) lastwritetime(%d)",
|
||||||
( shared_data->last_write_time == 0 )
|
|
||||||
&& ! zm_terminate
|
|
||||||
) {
|
|
||||||
Info("Waiting for capture daemon lastwriteindex(%d) lastwritetime(%d)",
|
|
||||||
shared_data->last_write_index, shared_data->last_write_time);
|
shared_data->last_write_index, shared_data->last_write_time);
|
||||||
usleep(10000);
|
//usleep(10000);
|
||||||
}
|
}
|
||||||
if ( zm_terminate )
|
if ( zm_terminate )
|
||||||
return;
|
return;
|
||||||
int last_write_index = shared_data->last_write_index ;
|
|
||||||
|
|
||||||
Debug(2,"Waiting for capture daemon unlock");
|
ref_image.Assign(width, height, camera->Colours(), camera->SubpixelOrder(), snap->image->Buffer(), camera->ImageSize());
|
||||||
image_buffer[last_write_index].mutex.lock();
|
Debug(2,"Have image about to unlock");
|
||||||
ref_image.Assign(width, height, camera->Colours(), camera->SubpixelOrder(), image_buffer[last_write_index].image->Buffer(), camera->ImageSize());
|
snap->unlock();
|
||||||
image_buffer[last_write_index].mutex.unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Group *> Monitor::Groups() {
|
std::vector<Group *> Monitor::Groups() {
|
||||||
|
|
|
@ -426,7 +426,7 @@ bool MonitorStream::sendFrame(Image *image, struct timeval *timestamp) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
last_frame_sent = TV_2_FLOAT(now);
|
last_frame_sent = TV_2_FLOAT(now);
|
||||||
return( true );
|
return true;
|
||||||
} // end bool MonitorStream::sendFrame( Image *image, struct timeval *timestamp )
|
} // end bool MonitorStream::sendFrame( Image *image, struct timeval *timestamp )
|
||||||
|
|
||||||
void MonitorStream::runStream() {
|
void MonitorStream::runStream() {
|
||||||
|
|
|
@ -120,6 +120,7 @@ int ZMPacket::decode( AVCodecContext *ctx ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
|
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
|
||||||
|
Debug(4,"send_packet");
|
||||||
int ret = avcodec_send_packet(ctx, &packet);
|
int ret = avcodec_send_packet(ctx, &packet);
|
||||||
if ( ret < 0 ) {
|
if ( ret < 0 ) {
|
||||||
Error("Unable to send packet: %s", av_make_error_string(ret).c_str());
|
Error("Unable to send packet: %s", av_make_error_string(ret).c_str());
|
||||||
|
@ -143,6 +144,7 @@ int ZMPacket::decode( AVCodecContext *ctx ) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
#endif
|
#endif
|
||||||
|
Debug(4,"receive_frame");
|
||||||
ret = avcodec_receive_frame(ctx, in_frame);
|
ret = avcodec_receive_frame(ctx, in_frame);
|
||||||
if ( ret < 0 ) {
|
if ( ret < 0 ) {
|
||||||
Error("Unable to receive frame: %s", av_make_error_string(ret).c_str());
|
Error("Unable to receive frame: %s", av_make_error_string(ret).c_str());
|
||||||
|
|
|
@ -62,8 +62,12 @@ class ZMPacket {
|
||||||
explicit ZMPacket( ZMPacket &packet );
|
explicit ZMPacket( ZMPacket &packet );
|
||||||
ZMPacket();
|
ZMPacket();
|
||||||
~ZMPacket();
|
~ZMPacket();
|
||||||
void lock() { mutex.lock(); };
|
void lock() {
|
||||||
void unlock() { mutex.unlock(); };
|
Debug(2,"Locking packet %d", this->image_index);
|
||||||
|
mutex.lock();
|
||||||
|
Debug(2,"packet %d locked", this->image_index);
|
||||||
|
};
|
||||||
|
void unlock() { Debug(2,"packet %d unlocked", this->image_index);mutex.unlock(); };
|
||||||
AVFrame *get_out_frame( const AVCodecContext *ctx );
|
AVFrame *get_out_frame( const AVCodecContext *ctx );
|
||||||
int get_codec_imgsize() { return codec_imgsize; };
|
int get_codec_imgsize() { return codec_imgsize; };
|
||||||
};
|
};
|
||||||
|
|
|
@ -33,12 +33,15 @@ zm_packetqueue::zm_packetqueue( int video_image_count, int p_video_stream_id, in
|
||||||
packet_counts = new int[max_stream_id+1];
|
packet_counts = new int[max_stream_id+1];
|
||||||
for ( int i=0; i <= max_stream_id; ++i )
|
for ( int i=0; i <= max_stream_id; ++i )
|
||||||
packet_counts[i] = 0;
|
packet_counts[i] = 0;
|
||||||
|
condition = new Condition(mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
zm_packetqueue::~zm_packetqueue() {
|
zm_packetqueue::~zm_packetqueue() {
|
||||||
clearQueue();
|
clearQueue();
|
||||||
delete[] packet_counts;
|
delete[] packet_counts;
|
||||||
packet_counts = NULL;
|
packet_counts = NULL;
|
||||||
|
delete condition;
|
||||||
|
condition = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Enqueues the given packet. Will maintain the analysis_it pointer and image packet counts.
|
/* Enqueues the given packet. Will maintain the analysis_it pointer and image packet counts.
|
||||||
|
@ -48,6 +51,7 @@ zm_packetqueue::~zm_packetqueue() {
|
||||||
|
|
||||||
bool zm_packetqueue::queuePacket( ZMPacket* zm_packet ) {
|
bool zm_packetqueue::queuePacket( ZMPacket* zm_packet ) {
|
||||||
Debug(4, "packetqueue queuepacket, first_video_packet_index is %d", first_video_packet_index);
|
Debug(4, "packetqueue queuepacket, first_video_packet_index is %d", first_video_packet_index);
|
||||||
|
mutex.lock();
|
||||||
|
|
||||||
if ( zm_packet->image_index != -1 ) {
|
if ( zm_packet->image_index != -1 ) {
|
||||||
// It's a video packet
|
// It's a video packet
|
||||||
|
@ -55,51 +59,33 @@ bool zm_packetqueue::queuePacket( ZMPacket* zm_packet ) {
|
||||||
// If we can never queue the same packet, then they can never go past
|
// If we can never queue the same packet, then they can never go past
|
||||||
if ( zm_packet->image_index == first_video_packet_index ) {
|
if ( zm_packet->image_index == first_video_packet_index ) {
|
||||||
Debug(2, "queuing packet that is already on the queue(%d)", zm_packet->image_index);
|
Debug(2, "queuing packet that is already on the queue(%d)", zm_packet->image_index);
|
||||||
ZMPacket *p = NULL;;
|
while ( pktQueue.size() ) {
|
||||||
while ( pktQueue.size() && (p = pktQueue.front()) && ( p->image_index != zm_packet->image_index ) ) {
|
mutex.unlock();
|
||||||
if ( ( analysis_it != pktQueue.end() ) && ( *analysis_it == p ) ) {
|
ZMPacket *p = popPacket();
|
||||||
Debug(2, "Increasing analysis_it, meaning analysis is not keeping up");
|
Debug(2,"Front packet index: %d", p->image_index);
|
||||||
++analysis_it;
|
mutex.lock();
|
||||||
}
|
|
||||||
|
|
||||||
pktQueue.pop_front();
|
if ( p->codec_type != AVMEDIA_TYPE_VIDEO ) {
|
||||||
if ( p->codec_type == AVMEDIA_TYPE_VIDEO ) {
|
Debug(2, "Deleting audio frame(%d)", p->image_index);
|
||||||
Debug(2, "Decreasing video_packet_count (%d), popped (%d)",
|
|
||||||
video_packet_count, p->image_index);
|
|
||||||
video_packet_count -= 1;
|
|
||||||
first_video_packet_index += 1;
|
|
||||||
first_video_packet_index %= max_video_packet_count;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
Debug(2, "Deleteing audio frame(%d)", p->image_index);
|
|
||||||
delete p;
|
delete p;
|
||||||
p = NULL;
|
p = NULL;
|
||||||
}
|
}
|
||||||
Debug(2,"pktQueue.size(%d)", pktQueue.size());
|
Debug(2,"pktQueue.size(%d)", pktQueue.size());
|
||||||
|
if ( p->image_index == zm_packet->image_index )
|
||||||
|
break;
|
||||||
} // end while there are packets at the head of the queue that are not this one
|
} // end while there are packets at the head of the queue that are not this one
|
||||||
|
|
||||||
if ( p && ( p->image_index == zm_packet->image_index ) ) {
|
|
||||||
// it should
|
|
||||||
video_packet_count -= 1;
|
|
||||||
pktQueue.pop_front();
|
|
||||||
first_video_packet_index += 1;
|
|
||||||
first_video_packet_index %= max_video_packet_count;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
Error("SHould have found the packet! front packet index was %d, new packet index is %d ",
|
|
||||||
p->image_index, zm_packet->image_index
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if ( analysis_it == pktQueue.end() ) {
|
if ( analysis_it == pktQueue.end() ) {
|
||||||
// Analsys_it should only point to end when queue is empty
|
// Analsys_it should only point to end when queue is empty
|
||||||
Debug(2,"pointing analysis_it to begining");
|
Debug(2,"pointing analysis_it to begining");
|
||||||
analysis_it = pktQueue.begin();
|
analysis_it = pktQueue.begin();
|
||||||
}
|
}
|
||||||
} else if ( first_video_packet_index == -1 ) {
|
}
|
||||||
|
if ( first_video_packet_index == -1 ) {
|
||||||
// Initialize the first_video_packet indicator
|
// Initialize the first_video_packet indicator
|
||||||
first_video_packet_index = zm_packet->image_index;
|
first_video_packet_index = zm_packet->image_index;
|
||||||
video_packet_count += 1;
|
|
||||||
} // end if
|
} // end if
|
||||||
|
video_packet_count += 1;
|
||||||
} // end if queuing a video packet
|
} // end if queuing a video packet
|
||||||
|
|
||||||
pktQueue.push_back(zm_packet);
|
pktQueue.push_back(zm_packet);
|
||||||
|
@ -114,6 +100,10 @@ bool zm_packetqueue::queuePacket( ZMPacket* zm_packet ) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// We signal on every packet because someday we may analyze sound
|
||||||
|
Debug(2,"Signalling");
|
||||||
|
condition->signal();
|
||||||
|
mutex.unlock();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} // end bool zm_packetqueue::queuePacket(ZMPacket* zm_packet)
|
} // end bool zm_packetqueue::queuePacket(ZMPacket* zm_packet)
|
||||||
|
@ -122,6 +112,9 @@ ZMPacket* zm_packetqueue::popPacket( ) {
|
||||||
if ( pktQueue.empty() ) {
|
if ( pktQueue.empty() ) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
Debug(2,"Mutex locking");
|
||||||
|
mutex.lock();
|
||||||
|
Debug(2,"Have Mutex lock");
|
||||||
|
|
||||||
ZMPacket *packet = pktQueue.front();
|
ZMPacket *packet = pktQueue.front();
|
||||||
if ( *analysis_it == packet )
|
if ( *analysis_it == packet )
|
||||||
|
@ -140,7 +133,9 @@ ZMPacket* zm_packetqueue::popPacket( ) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
packet_counts[packet->packet.stream_index] -= 1;
|
packet_counts[packet->packet.stream_index] -= 1;
|
||||||
|
mutex.unlock();
|
||||||
|
|
||||||
|
// Should we lock the packet?
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,6 +150,7 @@ unsigned int zm_packetqueue::clearQueue(unsigned int frames_to_keep, int stream_
|
||||||
if ( pktQueue.size() <= frames_to_keep ) {
|
if ( pktQueue.size() <= frames_to_keep ) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
mutex.lock();
|
||||||
int packets_to_delete = pktQueue.size();
|
int packets_to_delete = pktQueue.size();
|
||||||
|
|
||||||
std::list<ZMPacket *>::reverse_iterator it;
|
std::list<ZMPacket *>::reverse_iterator it;
|
||||||
|
@ -241,6 +237,7 @@ unsigned int zm_packetqueue::clearQueue(unsigned int frames_to_keep, int stream_
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Debug(3, "Deleted packets, resulting size is %d", pktQueue.size());
|
Debug(3, "Deleted packets, resulting size is %d", pktQueue.size());
|
||||||
|
mutex.unlock();
|
||||||
return delete_count;
|
return delete_count;
|
||||||
} // end unsigned int zm_packetqueue::clearQueue( unsigned int frames_to_keep, int stream_id )
|
} // end unsigned int zm_packetqueue::clearQueue( unsigned int frames_to_keep, int stream_id )
|
||||||
|
|
||||||
|
@ -278,15 +275,22 @@ int zm_packetqueue::packet_count( int stream_id ) {
|
||||||
// Returns a packet to analyse or NULL
|
// Returns a packet to analyse or NULL
|
||||||
ZMPacket *zm_packetqueue::get_analysis_packet() {
|
ZMPacket *zm_packetqueue::get_analysis_packet() {
|
||||||
|
|
||||||
if ( ! pktQueue.size() )
|
mutex.lock();
|
||||||
return NULL;
|
while ( (! pktQueue.size()) || ( analysis_it == pktQueue.end() ) ) {
|
||||||
if ( analysis_it == pktQueue.end() )
|
Debug(2,"waiting. Queue size %d analysis_it == end? %d", pktQueue.size(), ( analysis_it == pktQueue.end() ) );
|
||||||
return NULL;
|
|
||||||
|
condition->wait();
|
||||||
|
}
|
||||||
|
|
||||||
//Debug(2, "Distance from head: (%d)", std::distance( pktQueue.begin(), analysis_it ) );
|
//Debug(2, "Distance from head: (%d)", std::distance( pktQueue.begin(), analysis_it ) );
|
||||||
//Debug(2, "Distance from end: (%d)", std::distance( analysis_it, pktQueue.end() ) );
|
//Debug(2, "Distance from end: (%d)", std::distance( analysis_it, pktQueue.end() ) );
|
||||||
|
ZMPacket *p = *analysis_it;
|
||||||
|
Debug(2,"analysis_packet image_index: %d, about to lock packet", p->image_index);
|
||||||
|
p->lock();
|
||||||
|
Debug(2, "Locked packet, unlocking mutex");
|
||||||
|
mutex.unlock();
|
||||||
|
|
||||||
return *analysis_it;
|
return p;
|
||||||
} // end ZMPacket *zm_packetqueue::get_analysis_packet()
|
} // end ZMPacket *zm_packetqueue::get_analysis_packet()
|
||||||
|
|
||||||
// The idea is that analsys_it will only be == end() if the queue is empty
|
// The idea is that analsys_it will only be == end() if the queue is empty
|
||||||
|
@ -301,3 +305,44 @@ bool zm_packetqueue::increment_analysis_it( ) {
|
||||||
analysis_it = next_it;
|
analysis_it = next_it;
|
||||||
return true;
|
return true;
|
||||||
} // end bool zm_packetqueue::increment_analysis_it( )
|
} // end bool zm_packetqueue::increment_analysis_it( )
|
||||||
|
|
||||||
|
// Locks the packet, but also removes it from the queue including analysis_it
|
||||||
|
void zm_packetqueue::lock_packet( ZMPacket &packet ) {
|
||||||
|
mutex.lock();
|
||||||
|
if ( packet.image_index != -1 ) {
|
||||||
|
// It's a video packet
|
||||||
|
|
||||||
|
// If we can never queue the same packet, then they can never go past
|
||||||
|
if ( packet.image_index == first_video_packet_index ) {
|
||||||
|
Debug(2, "queuing packet that is already on the queue(%d)", packet.image_index);
|
||||||
|
while ( pktQueue.size() ) {
|
||||||
|
mutex.unlock();
|
||||||
|
ZMPacket *p = popPacket();
|
||||||
|
Debug(2,"Front packet index: %d", p->image_index);
|
||||||
|
mutex.lock();
|
||||||
|
|
||||||
|
if ( p->codec_type != AVMEDIA_TYPE_VIDEO ) {
|
||||||
|
Debug(2, "Deleting audio frame(%d)", p->image_index);
|
||||||
|
delete p;
|
||||||
|
p = NULL;
|
||||||
|
}
|
||||||
|
Debug(2,"pktQueue.size(%d)", pktQueue.size());
|
||||||
|
if ( p->image_index == packet.image_index )
|
||||||
|
break;
|
||||||
|
} // end while there are packets at the head of the queue that are not this one
|
||||||
|
|
||||||
|
if ( analysis_it == pktQueue.end() ) {
|
||||||
|
// Analsys_it should only point to end when queue is empty
|
||||||
|
Debug(2,"pointing analysis_it to begining");
|
||||||
|
analysis_it = pktQueue.begin();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( first_video_packet_index == -1 ) {
|
||||||
|
// Initialize the first_video_packet indicator
|
||||||
|
first_video_packet_index = packet.image_index;
|
||||||
|
} // end if
|
||||||
|
video_packet_count += 1;
|
||||||
|
} // end if queuing a video packet
|
||||||
|
packet.lock();
|
||||||
|
mutex.unlock();
|
||||||
|
}
|
||||||
|
|
|
@ -42,7 +42,8 @@ class zm_packetqueue {
|
||||||
int max_stream_id;
|
int max_stream_id;
|
||||||
int *packet_counts; /* packet count for each stream_id, to keep track of how many video vs audio packets are in the queue */
|
int *packet_counts; /* packet count for each stream_id, to keep track of how many video vs audio packets are in the queue */
|
||||||
|
|
||||||
Mutex mutex;
|
RecursiveMutex mutex;
|
||||||
|
Condition *condition;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
zm_packetqueue(int p_max_video_packet_count, int p_video_stream_id, int p_audio_stream_id);
|
zm_packetqueue(int p_max_video_packet_count, int p_video_stream_id, int p_audio_stream_id);
|
||||||
|
@ -60,6 +61,7 @@ class zm_packetqueue {
|
||||||
// Functions to manage the analysis frame logic
|
// Functions to manage the analysis frame logic
|
||||||
bool increment_analysis_it();
|
bool increment_analysis_it();
|
||||||
ZMPacket *get_analysis_packet();
|
ZMPacket *get_analysis_packet();
|
||||||
|
void lock_packet( ZMPacket &packet );
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* ZM_PACKETQUEUE_H */
|
#endif /* ZM_PACKETQUEUE_H */
|
||||||
|
|
|
@ -215,8 +215,9 @@ if ( $action ) {
|
||||||
# If I put this here, it protects all views and popups, but it has to go after actions.php because actions.php does the actual logging in.
|
# If I put this here, it protects all views and popups, but it has to go after actions.php because actions.php does the actual logging in.
|
||||||
if ( ZM_OPT_USE_AUTH and !isset($user) and ($view != 'login') ) {
|
if ( ZM_OPT_USE_AUTH and !isset($user) and ($view != 'login') ) {
|
||||||
Logger::Debug('Redirecting to login');
|
Logger::Debug('Redirecting to login');
|
||||||
$view = 'none';
|
# We adjust the view instead of redirecting so that we can store the original url and just to it after logging in
|
||||||
$redirect = ZM_BASE_URL.$_SERVER['PHP_SELF'].'?view=login';
|
$view = 'login';
|
||||||
|
#$redirect = ZM_BASE_URL.$_SERVER['PHP_SELF'].'?view=login';
|
||||||
$request = null;
|
$request = null;
|
||||||
} else if ( ZM_SHOW_PRIVACY && ($view != 'privacy') && ($view != 'options') && (!$request) && canEdit('System') ) {
|
} else if ( ZM_SHOW_PRIVACY && ($view != 'privacy') && ($view != 'options') && (!$request) && canEdit('System') ) {
|
||||||
$view = 'none';
|
$view = 'none';
|
||||||
|
|
|
@ -172,8 +172,8 @@ if ( canEdit('Events') ) {
|
||||||
} // end if Event->DefaultVideo
|
} // end if Event->DefaultVideo
|
||||||
?>
|
?>
|
||||||
<div id="exportEvent"><button type="button" data-on-click="exportEvent"><?php echo translate('Export') ?></button></div>
|
<div id="exportEvent"><button type="button" data-on-click="exportEvent"><?php echo translate('Export') ?></button></div>
|
||||||
<div id="replayControl"><label for="replayMode"><?php echo translate('Replay') ?></label><?php echo buildSelect( "replayMode", $replayModes, "changeReplayMode();" ); ?></div>
|
<div id="replayControl"><label for="replayMode"><?php echo translate('Replay') ?></label><?php echo buildSelect('replayMode', $replayModes, 'changeReplayMode();'); ?></div>
|
||||||
<div id="scaleControl"><label for="scale"><?php echo translate('Scale') ?></label><?php echo buildSelect( "scale", $scales, "changeScale();" ); ?></div>
|
<div id="scaleControl"><label for="scale"><?php echo translate('Scale') ?></label><?php echo buildSelect('scale', $scales, 'changeScale();'); ?></div>
|
||||||
<div id="codecControl"><label for="codec"><?php echo translate('Codec') ?></label><?php echo htmlSelect('codec', $codecs, $codec, array('onchange'=>'changeCodec(this);') ); ?></div>
|
<div id="codecControl"><label for="codec"><?php echo translate('Codec') ?></label><?php echo htmlSelect('codec', $codecs, $codec, array('onchange'=>'changeCodec(this);') ); ?></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -192,7 +192,6 @@ if ( $video_tag ) {
|
||||||
<?php
|
<?php
|
||||||
} else {
|
} else {
|
||||||
?>
|
?>
|
||||||
<?php if ( !$video_tag ) { ?>
|
|
||||||
<div id="imageFeed">
|
<div id="imageFeed">
|
||||||
<?php
|
<?php
|
||||||
if ( ZM_WEB_STREAM_METHOD == 'mpeg' && ZM_MPEG_LIVE_FORMAT ) {
|
if ( ZM_WEB_STREAM_METHOD == 'mpeg' && ZM_MPEG_LIVE_FORMAT ) {
|
||||||
|
@ -212,7 +211,9 @@ if ( ZM_WEB_STREAM_METHOD == 'mpeg' && ZM_MPEG_LIVE_FORMAT ) {
|
||||||
<div class="progressBox" id="progressBox" title="" style="width: 0%;"></div>
|
<div class="progressBox" id="progressBox" title="" style="width: 0%;"></div>
|
||||||
</div><!--progressBar-->
|
</div><!--progressBar-->
|
||||||
</div><!--imageFeed-->
|
</div><!--imageFeed-->
|
||||||
<?php } /*end if !DefaultVideo*/ ?>
|
<?php
|
||||||
|
} /*end if !DefaultVideo*/
|
||||||
|
?>
|
||||||
<p id="dvrControls">
|
<p id="dvrControls">
|
||||||
<input type="button" value="<+" id="prevBtn" title="<?php echo translate('Prev') ?>" class="inactive" data-on-click-true="streamPrev"/>
|
<input type="button" value="<+" id="prevBtn" title="<?php echo translate('Prev') ?>" class="inactive" data-on-click-true="streamPrev"/>
|
||||||
<input type="button" value="<<" id="fastRevBtn" title="<?php echo translate('Rewind') ?>" class="inactive" data-on-click-true="streamFastRev"/>
|
<input type="button" value="<<" id="fastRevBtn" title="<?php echo translate('Rewind') ?>" class="inactive" data-on-click-true="streamFastRev"/>
|
||||||
|
|
|
@ -18,8 +18,11 @@
|
||||||
}
|
}
|
||||||
?>";
|
?>";
|
||||||
|
|
||||||
//var newUrl = thisUrl + querySuffix;
|
if ( querySuffix == '?view=login' ) {
|
||||||
var newUrl = '<?php echo $_SERVER['PHP_SELF'] ?>' + querySuffix;
|
querySuffix = '?view=console';
|
||||||
|
}
|
||||||
|
var newUrl = querySuffix;
|
||||||
|
console.log("Redirecting to" + newUrl + ' ' + thisUrl);
|
||||||
window.location.replace(newUrl);
|
window.location.replace(newUrl);
|
||||||
}
|
}
|
||||||
).delay( 500 );
|
).delay( 500 );
|
||||||
|
|
Loading…
Reference in New Issue