wip
This commit is contained in:
parent
279e0d8bcf
commit
448294f593
|
@ -241,7 +241,7 @@ int FfmpegCamera::OpenFfmpeg() {
|
|||
}
|
||||
|
||||
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());
|
||||
|
|
|
@ -2082,6 +2082,10 @@ int LocalCamera::Capture( ZMPacket &zm_packet ) {
|
|||
|
||||
} /* prime capture */
|
||||
|
||||
if ( ! zm_packet.image ) {
|
||||
zm_packet.image = new Image(width, height, colours, subpixelorder);
|
||||
}
|
||||
|
||||
if ( conversion_type != 0 ) {
|
||||
|
||||
Debug(3, "Performing format conversion");
|
||||
|
|
|
@ -1630,6 +1630,7 @@ bool Monitor::Analyse() {
|
|||
|
||||
ZMPacket *snap;
|
||||
// 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 ) ) {
|
||||
unsigned int index = snap->image_index;
|
||||
Debug(2, "Analysis index (%d), last_Write(%d)", index, shared_data->last_write_index);
|
||||
|
@ -1638,7 +1639,6 @@ bool Monitor::Analyse() {
|
|||
return 0;
|
||||
}
|
||||
|
||||
snap->lock();
|
||||
packets_processed += 1;
|
||||
|
||||
if ( snap->image_index == -1 ) {
|
||||
|
@ -2069,7 +2069,6 @@ void Monitor::ReloadLinkedMonitors(const char *p_linked_monitors) {
|
|||
|
||||
db_mutex.lock();
|
||||
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] );
|
||||
if ( mysql_query(&dbconn, sql) ) {
|
||||
db_mutex.unlock();
|
||||
|
@ -2177,25 +2176,27 @@ int Monitor::LoadFfmpegMonitors(const char *file, Monitor **&monitors, Purpose p
|
|||
int Monitor::Capture() {
|
||||
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) ) {
|
||||
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);
|
||||
time_t now = time(0);
|
||||
double approxFps = double(image_buffer_count)/double(now-image_buffer[index].timestamp->tv_sec);
|
||||
time_t last_read_delta = now - shared_data->last_read_time;
|
||||
if ( last_read_delta > (image_buffer_count/approxFps) ) {
|
||||
Warning( "Last image read from shared memory %ld seconds ago, zma may have gone away", last_read_delta )
|
||||
Warning("Last image read from shared memory %ld seconds ago, zma may have gone away", last_read_delta)
|
||||
shared_data->last_read_index = image_buffer_count;
|
||||
}
|
||||
} 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];
|
||||
Debug(2,"before lock");
|
||||
ZMPacket *packet = new ZMPacket();
|
||||
//&image_buffer[index];
|
||||
Debug(2,"before packet lock");
|
||||
packet->lock();
|
||||
Debug(2,"before reset");
|
||||
packet->reset();
|
||||
Image* capture_image = packet->image;
|
||||
int captureResult = 0;
|
||||
|
@ -2243,23 +2244,23 @@ int Monitor::Capture() {
|
|||
if ( packet->packet.stream_index != video_stream_id ) {
|
||||
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 ) );
|
||||
// Only queue if we have some video packets in there.
|
||||
mutex.lock();
|
||||
// Only queue if we have some video packets in there. Should push this logic into packetqueue
|
||||
//mutex.lock();
|
||||
if ( packetqueue->video_packet_count || event ) {
|
||||
// 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)
|
||||
audio_packet->codec_type = camera->get_AudioStream()->codecpar->codec_type;
|
||||
packet->codec_type = camera->get_AudioStream()->codecpar->codec_type;
|
||||
#else
|
||||
audio_packet->codec_type = camera->get_AudioStream()->codec->codec_type;
|
||||
packet->codec_type = camera->get_AudioStream()->codec->codec_type;
|
||||
#endif
|
||||
Debug(2, "Queueing packet");
|
||||
packetqueue->queuePacket(audio_packet);
|
||||
packetqueue->queuePacket(packet);
|
||||
}
|
||||
// Don't update last_write_index because that is used for live streaming
|
||||
//shared_data->last_write_time = image_buffer[index].timestamp->tv_sec;
|
||||
|
||||
mutex.unlock();
|
||||
//mutex.unlock();
|
||||
packet->unlock();
|
||||
return 1;
|
||||
}
|
||||
|
@ -2274,20 +2275,21 @@ int Monitor::Capture() {
|
|||
//Debug(2,"About to decode");
|
||||
if ( packet->decode(camera->get_VideoCodecContext()) ) {
|
||||
//Debug(2,"Getimage");
|
||||
packet->get_image();
|
||||
packet->get_image( image_buffer[index].image );
|
||||
}
|
||||
// Have an av_packet,
|
||||
}
|
||||
|
||||
Debug(2,"Before mutex lock");
|
||||
mutex.lock();
|
||||
//Debug(2,"Before mutex lock");
|
||||
// FIXME this mutex is useless, packetqueue has it's own
|
||||
//mutex.lock();
|
||||
if ( packetqueue->video_packet_count || packet->keyframe || event ) {
|
||||
Debug(2, "Have video packet for index (%d)", index);
|
||||
packetqueue->queuePacket(packet);
|
||||
} else {
|
||||
Debug(2, "Not queuing video packet for index (%d)", index);
|
||||
}
|
||||
mutex.unlock();
|
||||
//mutex.unlock();
|
||||
|
||||
/* Deinterlacing */
|
||||
if ( deinterlacing_value ) {
|
||||
|
@ -2355,7 +2357,7 @@ int Monitor::Capture() {
|
|||
// assume that we are connected
|
||||
snprintf(sql, sizeof(sql),
|
||||
"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'",
|
||||
id, capture_fps, new_capture_bandwidth, capture_fps, new_capture_bandwidth);
|
||||
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.
|
||||
void Monitor::get_ref_image() {
|
||||
while (
|
||||
( shared_data->last_write_index == (unsigned int)image_buffer_count )
|
||||
&&
|
||||
( shared_data->last_write_time == 0 )
|
||||
&& ! zm_terminate
|
||||
) {
|
||||
Info("Waiting for capture daemon lastwriteindex(%d) lastwritetime(%d)",
|
||||
ZMPacket * snap;
|
||||
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_index, shared_data->last_write_time);
|
||||
usleep(10000);
|
||||
//usleep(10000);
|
||||
}
|
||||
if ( zm_terminate )
|
||||
return;
|
||||
int last_write_index = shared_data->last_write_index ;
|
||||
|
||||
Debug(2,"Waiting for capture daemon unlock");
|
||||
image_buffer[last_write_index].mutex.lock();
|
||||
ref_image.Assign(width, height, camera->Colours(), camera->SubpixelOrder(), image_buffer[last_write_index].image->Buffer(), camera->ImageSize());
|
||||
image_buffer[last_write_index].mutex.unlock();
|
||||
ref_image.Assign(width, height, camera->Colours(), camera->SubpixelOrder(), snap->image->Buffer(), camera->ImageSize());
|
||||
Debug(2,"Have image about to unlock");
|
||||
snap->unlock();
|
||||
}
|
||||
|
||||
std::vector<Group *> Monitor::Groups() {
|
||||
|
|
|
@ -74,9 +74,9 @@ bool MonitorStream::checkSwapPath(const char *path, bool create_path) {
|
|||
} // end bool MonitorStream::checkSwapPath( const char *path, bool create_path )
|
||||
|
||||
void MonitorStream::processCommand(const CmdMsg *msg) {
|
||||
Debug( 2, "Got message, type %d, msg %d", msg->msg_type, msg->msg_data[0] );
|
||||
Debug(2, "Got message, type %d, msg %d", msg->msg_type, msg->msg_data[0]);
|
||||
// Check for incoming command
|
||||
switch( (MsgCommand)msg->msg_data[0] ) {
|
||||
switch ( (MsgCommand)msg->msg_data[0] ) {
|
||||
case CMD_PAUSE :
|
||||
Debug(1, "Got PAUSE command");
|
||||
paused = true;
|
||||
|
@ -414,19 +414,19 @@ bool MonitorStream::sendFrame(Image *image, struct timeval *timestamp) {
|
|||
return false;
|
||||
}
|
||||
fputs("\r\n\r\n",stdout);
|
||||
fflush( stdout );
|
||||
fflush(stdout);
|
||||
|
||||
struct timeval frameEndTime;
|
||||
gettimeofday( &frameEndTime, NULL );
|
||||
gettimeofday(&frameEndTime, NULL);
|
||||
|
||||
int frameSendTime = tvDiffMsec( frameStartTime, frameEndTime );
|
||||
int frameSendTime = tvDiffMsec(frameStartTime, frameEndTime);
|
||||
if ( frameSendTime > 1000/maxfps ) {
|
||||
maxfps /= 1.5;
|
||||
Error( "Frame send time %d msec too slow, throttling maxfps to %.2f", frameSendTime, maxfps );
|
||||
Error("Frame send time %d msec too slow, throttling maxfps to %.2f", frameSendTime, maxfps);
|
||||
}
|
||||
}
|
||||
last_frame_sent = TV_2_FLOAT( now );
|
||||
return( true );
|
||||
last_frame_sent = TV_2_FLOAT(now);
|
||||
return true;
|
||||
} // end bool MonitorStream::sendFrame( Image *image, struct timeval *timestamp )
|
||||
|
||||
void MonitorStream::runStream() {
|
||||
|
@ -483,7 +483,7 @@ void MonitorStream::runStream() {
|
|||
} else {
|
||||
swap_path = staticConfig.PATH_SWAP;
|
||||
|
||||
Debug( 3, "Checking swap path folder: %s", swap_path.c_str() );
|
||||
Debug(3, "Checking swap path folder: %s", swap_path.c_str());
|
||||
if ( checkSwapPath(swap_path.c_str(), true) ) {
|
||||
swap_path += stringtf("/zmswap-m%d", monitor->Id());
|
||||
|
||||
|
@ -503,8 +503,8 @@ void MonitorStream::runStream() {
|
|||
} else {
|
||||
Debug(2, "Assigning temporary buffer");
|
||||
temp_image_buffer = new SwapImage[temp_image_buffer_count];
|
||||
memset( temp_image_buffer, 0, sizeof(*temp_image_buffer)*temp_image_buffer_count );
|
||||
Debug( 2, "Assigned temporary buffer" );
|
||||
memset(temp_image_buffer, 0, sizeof(*temp_image_buffer)*temp_image_buffer_count);
|
||||
Debug(2, "Assigned temporary buffer");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -31,7 +31,7 @@ ZMPacket::ZMPacket( ) {
|
|||
out_frame = NULL;
|
||||
image = NULL;
|
||||
buffer = NULL;
|
||||
av_init_packet( &packet );
|
||||
av_init_packet(&packet);
|
||||
packet.size = 0; // So we can detect whether it has been filled.
|
||||
timestamp = NULL;
|
||||
analysis_image = NULL;
|
||||
|
@ -47,8 +47,8 @@ ZMPacket::ZMPacket( ZMPacket &p ) {
|
|||
out_frame = NULL;
|
||||
image = NULL;
|
||||
buffer = NULL;
|
||||
av_init_packet( &packet );
|
||||
if ( zm_av_packet_ref( &packet, &p.packet ) < 0 ) {
|
||||
av_init_packet(&packet);
|
||||
if ( zm_av_packet_ref(&packet, &p.packet) < 0 ) {
|
||||
Error("error refing packet");
|
||||
}
|
||||
timestamp = new struct timeval;
|
||||
|
@ -59,17 +59,17 @@ ZMPacket::ZMPacket( ZMPacket &p ) {
|
|||
}
|
||||
|
||||
ZMPacket::~ZMPacket() {
|
||||
zm_av_packet_unref( &packet );
|
||||
zm_av_packet_unref(&packet);
|
||||
if ( in_frame ) {
|
||||
//av_free(frame->data);
|
||||
av_frame_free( &in_frame );
|
||||
av_frame_free(&in_frame);
|
||||
}
|
||||
if ( out_frame ) {
|
||||
//av_free(frame->data);
|
||||
av_frame_free( &out_frame );
|
||||
av_frame_free(&out_frame);
|
||||
}
|
||||
if ( buffer ) {
|
||||
av_freep( &buffer );
|
||||
av_freep(&buffer);
|
||||
}
|
||||
if ( analysis_image ) {
|
||||
delete analysis_image;
|
||||
|
@ -82,19 +82,19 @@ ZMPacket::~ZMPacket() {
|
|||
|
||||
void ZMPacket::reset() {
|
||||
//Debug(2,"reset");
|
||||
zm_av_packet_unref( &packet );
|
||||
zm_av_packet_unref(&packet);
|
||||
packet.size = 0;
|
||||
if ( in_frame ) {
|
||||
//Debug(4,"reset frame");
|
||||
av_frame_free( &in_frame );
|
||||
av_frame_free(&in_frame);
|
||||
}
|
||||
if ( out_frame ) {
|
||||
//Debug(4,"reset frame");
|
||||
av_frame_free( &out_frame );
|
||||
av_frame_free(&out_frame);
|
||||
}
|
||||
if ( buffer ) {
|
||||
//Debug(4,"freeing buffer");
|
||||
av_freep( &buffer );
|
||||
av_freep(&buffer);
|
||||
}
|
||||
if ( analysis_image ) {
|
||||
delete analysis_image;
|
||||
|
@ -111,42 +111,44 @@ void ZMPacket::reset() {
|
|||
}
|
||||
|
||||
int ZMPacket::decode( AVCodecContext *ctx ) {
|
||||
Debug(4, "about to decode video, image_index is (%d)", image_index );
|
||||
Debug(4, "about to decode video, image_index is (%d)", image_index);
|
||||
|
||||
if ( in_frame ) {
|
||||
Error("Already have a frame?");
|
||||
Error("Already have a frame?");
|
||||
} else {
|
||||
in_frame = zm_av_frame_alloc();
|
||||
in_frame = zm_av_frame_alloc();
|
||||
}
|
||||
|
||||
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
|
||||
int ret = avcodec_send_packet( ctx, &packet );
|
||||
Debug(4,"send_packet");
|
||||
int ret = avcodec_send_packet(ctx, &packet);
|
||||
if ( ret < 0 ) {
|
||||
Error( "Unable to send packet: %s", av_make_error_string(ret).c_str() );
|
||||
av_frame_free( &in_frame );
|
||||
Error("Unable to send packet: %s", av_make_error_string(ret).c_str());
|
||||
av_frame_free(&in_frame);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if HAVE_AVUTIL_HWCONTEXT_H
|
||||
if ( hwaccel ) {
|
||||
ret = avcodec_receive_frame( ctx, hwFrame );
|
||||
ret = avcodec_receive_frame(ctx, hwFrame);
|
||||
if ( ret < 0 ) {
|
||||
Error( "Unable to receive frame: %s", av_make_error_string(ret).c_str() );
|
||||
av_frame_free( &in_frame );
|
||||
Error("Unable to receive frame: %s", av_make_error_string(ret).c_str());
|
||||
av_frame_free(&in_frame);
|
||||
return 0;
|
||||
}
|
||||
ret = av_hwframe_transfer_data(frame, hwFrame, 0);
|
||||
if ( ret < 0 ) {
|
||||
Error( "Unable to transfer frame: %s", av_make_error_string(ret).c_str() );
|
||||
av_frame_free( &in_frame );
|
||||
Error("Unable to transfer frame: %s", av_make_error_string(ret).c_str());
|
||||
av_frame_free(&in_frame);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
#endif
|
||||
ret = avcodec_receive_frame( ctx, in_frame );
|
||||
Debug(4,"receive_frame");
|
||||
ret = avcodec_receive_frame(ctx, in_frame);
|
||||
if ( ret < 0 ) {
|
||||
Error( "Unable to receive frame: %s", av_make_error_string(ret).c_str() );
|
||||
av_frame_free( &in_frame );
|
||||
Error("Unable to receive frame: %s", av_make_error_string(ret).c_str());
|
||||
av_frame_free(&in_frame);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -156,38 +158,38 @@ int ZMPacket::decode( AVCodecContext *ctx ) {
|
|||
|
||||
# else
|
||||
int frameComplete = 0;
|
||||
int ret = zm_avcodec_decode_video( ctx, in_frame, &frameComplete, &packet );
|
||||
int ret = zm_avcodec_decode_video(ctx, in_frame, &frameComplete, &packet);
|
||||
if ( ret < 0 ) {
|
||||
Error( "Unable to decode frame at frame %s", av_make_error_string(ret).c_str() );
|
||||
av_frame_free( &in_frame );
|
||||
Error("Unable to decode frame at frame %s", av_make_error_string(ret).c_str());
|
||||
av_frame_free(&in_frame);
|
||||
return 0;
|
||||
}
|
||||
if ( ! frameComplete ) {
|
||||
if ( !frameComplete ) {
|
||||
Debug(1, "incomplete frame?");
|
||||
av_frame_free( &in_frame );
|
||||
av_frame_free(&in_frame);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
return 1;
|
||||
} // end ZMPacket::decode
|
||||
|
||||
Image * ZMPacket::get_image( Image *i ) {
|
||||
if ( ! in_frame ) {
|
||||
Image *ZMPacket::get_image(Image *i) {
|
||||
if ( !in_frame ) {
|
||||
Error("Can't get image without frame.. maybe need to decode first");
|
||||
return NULL;
|
||||
}
|
||||
if ( ! image ) {
|
||||
if ( ! i ) {
|
||||
if ( !image ) {
|
||||
if ( !i ) {
|
||||
Error("Need a pre-allocated image buffer");
|
||||
return NULL;
|
||||
}
|
||||
image = i;
|
||||
}
|
||||
image->Assign( in_frame );
|
||||
image->Assign(in_frame);
|
||||
return image;
|
||||
}
|
||||
|
||||
Image *ZMPacket::set_image( Image *i ) {
|
||||
Image *ZMPacket::set_image(Image *i) {
|
||||
image = i;
|
||||
return image;
|
||||
}
|
||||
|
|
|
@ -62,8 +62,12 @@ class ZMPacket {
|
|||
explicit ZMPacket( ZMPacket &packet );
|
||||
ZMPacket();
|
||||
~ZMPacket();
|
||||
void lock() { mutex.lock(); };
|
||||
void unlock() { mutex.unlock(); };
|
||||
void lock() {
|
||||
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 );
|
||||
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];
|
||||
for ( int i=0; i <= max_stream_id; ++i )
|
||||
packet_counts[i] = 0;
|
||||
condition = new Condition(mutex);
|
||||
}
|
||||
|
||||
zm_packetqueue::~zm_packetqueue() {
|
||||
clearQueue();
|
||||
delete[] packet_counts;
|
||||
packet_counts = NULL;
|
||||
delete condition;
|
||||
condition = NULL;
|
||||
}
|
||||
|
||||
/* 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 ) {
|
||||
Debug(4, "packetqueue queuepacket, first_video_packet_index is %d", first_video_packet_index);
|
||||
mutex.lock();
|
||||
|
||||
if ( zm_packet->image_index != -1 ) {
|
||||
// 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 ( zm_packet->image_index == first_video_packet_index ) {
|
||||
Debug(2, "queuing packet that is already on the queue(%d)", zm_packet->image_index);
|
||||
ZMPacket *p = NULL;;
|
||||
while ( pktQueue.size() && (p = pktQueue.front()) && ( p->image_index != zm_packet->image_index ) ) {
|
||||
if ( ( analysis_it != pktQueue.end() ) && ( *analysis_it == p ) ) {
|
||||
Debug(2, "Increasing analysis_it, meaning analysis is not keeping up");
|
||||
++analysis_it;
|
||||
}
|
||||
while ( pktQueue.size() ) {
|
||||
mutex.unlock();
|
||||
ZMPacket *p = popPacket();
|
||||
Debug(2,"Front packet index: %d", p->image_index);
|
||||
mutex.lock();
|
||||
|
||||
pktQueue.pop_front();
|
||||
if ( p->codec_type == AVMEDIA_TYPE_VIDEO ) {
|
||||
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);
|
||||
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() );
|
||||
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
|
||||
|
||||
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() ) {
|
||||
// Analsys_it should only point to end when queue is empty
|
||||
Debug(2,"pointing analysis_it to begining");
|
||||
analysis_it = pktQueue.begin();
|
||||
}
|
||||
} else if ( first_video_packet_index == -1 ) {
|
||||
}
|
||||
if ( first_video_packet_index == -1 ) {
|
||||
// Initialize the first_video_packet indicator
|
||||
first_video_packet_index = zm_packet->image_index;
|
||||
video_packet_count += 1;
|
||||
} // end if
|
||||
video_packet_count += 1;
|
||||
} // end if queuing a video packet
|
||||
|
||||
pktQueue.push_back(zm_packet);
|
||||
|
@ -114,6 +100,10 @@ bool zm_packetqueue::queuePacket( ZMPacket* zm_packet ) {
|
|||
}
|
||||
#endif
|
||||
|
||||
// We signal on every packet because someday we may analyze sound
|
||||
Debug(2,"Signalling");
|
||||
condition->signal();
|
||||
mutex.unlock();
|
||||
|
||||
return true;
|
||||
} // end bool zm_packetqueue::queuePacket(ZMPacket* zm_packet)
|
||||
|
@ -122,6 +112,9 @@ ZMPacket* zm_packetqueue::popPacket( ) {
|
|||
if ( pktQueue.empty() ) {
|
||||
return NULL;
|
||||
}
|
||||
Debug(2,"Mutex locking");
|
||||
mutex.lock();
|
||||
Debug(2,"Have Mutex lock");
|
||||
|
||||
ZMPacket *packet = pktQueue.front();
|
||||
if ( *analysis_it == packet )
|
||||
|
@ -140,7 +133,9 @@ ZMPacket* zm_packetqueue::popPacket( ) {
|
|||
}
|
||||
}
|
||||
packet_counts[packet->packet.stream_index] -= 1;
|
||||
mutex.unlock();
|
||||
|
||||
// Should we lock the 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 ) {
|
||||
return 0;
|
||||
}
|
||||
mutex.lock();
|
||||
int packets_to_delete = pktQueue.size();
|
||||
|
||||
std::list<ZMPacket *>::reverse_iterator it;
|
||||
|
@ -241,6 +237,7 @@ unsigned int zm_packetqueue::clearQueue(unsigned int frames_to_keep, int stream_
|
|||
#endif
|
||||
|
||||
Debug(3, "Deleted packets, resulting size is %d", pktQueue.size());
|
||||
mutex.unlock();
|
||||
return delete_count;
|
||||
} // 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
|
||||
ZMPacket *zm_packetqueue::get_analysis_packet() {
|
||||
|
||||
if ( ! pktQueue.size() )
|
||||
return NULL;
|
||||
if ( analysis_it == pktQueue.end() )
|
||||
return NULL;
|
||||
mutex.lock();
|
||||
while ( (! pktQueue.size()) || ( analysis_it == pktQueue.end() ) ) {
|
||||
Debug(2,"waiting. Queue size %d analysis_it == end? %d", pktQueue.size(), ( analysis_it == pktQueue.end() ) );
|
||||
|
||||
condition->wait();
|
||||
}
|
||||
|
||||
//Debug(2, "Distance from head: (%d)", std::distance( pktQueue.begin(), analysis_it ) );
|
||||
//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()
|
||||
|
||||
// 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;
|
||||
return true;
|
||||
} // 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 *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:
|
||||
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
|
||||
bool increment_analysis_it();
|
||||
ZMPacket *get_analysis_packet();
|
||||
void lock_packet( ZMPacket &packet );
|
||||
};
|
||||
|
||||
#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 ( ZM_OPT_USE_AUTH and !isset($user) and ($view != 'login') ) {
|
||||
Logger::Debug('Redirecting to login');
|
||||
$view = 'none';
|
||||
$redirect = ZM_BASE_URL.$_SERVER['PHP_SELF'].'?view=login';
|
||||
# We adjust the view instead of redirecting so that we can store the original url and just to it after logging in
|
||||
$view = 'login';
|
||||
#$redirect = ZM_BASE_URL.$_SERVER['PHP_SELF'].'?view=login';
|
||||
$request = null;
|
||||
} else if ( ZM_SHOW_PRIVACY && ($view != 'privacy') && ($view != 'options') && (!$request) && canEdit('System') ) {
|
||||
$view = 'none';
|
||||
|
|
|
@ -36,7 +36,7 @@ if ( $user['MonitorIds'] ) {
|
|||
}
|
||||
$Monitor = $Event->Monitor();
|
||||
|
||||
if (isset($_REQUEST['rate'])) {
|
||||
if ( isset($_REQUEST['rate']) ) {
|
||||
$rate = validInt($_REQUEST['rate']);
|
||||
} else if ( isset($_COOKIE['zmEventRate']) ) {
|
||||
$rate = $_COOKIE['zmEventRate'];
|
||||
|
@ -44,7 +44,7 @@ if (isset($_REQUEST['rate'])) {
|
|||
$rate = reScale(RATE_BASE, $Monitor->DefaultRate(), ZM_WEB_DEFAULT_RATE);
|
||||
}
|
||||
|
||||
if (isset($_REQUEST['scale'])) {
|
||||
if ( isset($_REQUEST['scale']) ) {
|
||||
$scale = validInt($_REQUEST['scale']);
|
||||
} else if ( isset( $_COOKIE['zmEventScaleAuto'] ) ) {
|
||||
// If we're using scale to fit use it on all monitors
|
||||
|
@ -56,12 +56,12 @@ if (isset($_REQUEST['scale'])) {
|
|||
}
|
||||
|
||||
$codec = 'auto';
|
||||
if (isset($_REQUEST['codec'])) {
|
||||
if ( isset($_REQUEST['codec']) ) {
|
||||
$codec = $_REQUEST['codec'];
|
||||
session_start();
|
||||
$_SESSION['zmEventCodec'.$Event->MonitorId()] = $codec;
|
||||
session_write_close();
|
||||
} else if ( isset( $_SESSION['zmEventCodec'.$Event->MonitorId()] ) ) {
|
||||
} else if ( isset($_SESSION['zmEventCodec'.$Event->MonitorId()]) ) {
|
||||
$codec = $_SESSION['zmEventCodec'.$Event->MonitorId()];
|
||||
} else {
|
||||
$codec = $Monitor->DefaultCodec();
|
||||
|
@ -91,7 +91,7 @@ if ( isset( $_REQUEST['replayMode'] ) )
|
|||
if ( isset( $_COOKIE['replayMode']) && preg_match('#^[a-z]+$#', $_COOKIE['replayMode']) )
|
||||
$replayMode = validHtmlStr($_COOKIE['replayMode']);
|
||||
|
||||
if ( ( ! $replayMode ) or ( ! $replayModes[$replayMode] ) ) {
|
||||
if ( ( !$replayMode ) or ( !$replayModes[$replayMode] ) ) {
|
||||
$replayMode = 'none';
|
||||
}
|
||||
|
||||
|
@ -145,7 +145,7 @@ if ( ! $Event->Id() ) {
|
|||
<div id="nameControl">
|
||||
<input type="text" id="eventName" name="eventName" value="<?php echo validHtmlStr($Event->Name()) ?>" />
|
||||
<button value="Rename" type="button" data-on-click="renameEvent"<?php if ( !canEdit('Events') ) { ?> disabled="disabled"<?php } ?>>
|
||||
<?php echo translate('Rename') ?></button>
|
||||
<?php echo translate('Rename') ?></button>
|
||||
</div>
|
||||
<?php
|
||||
if ( canEdit('Events') ) {
|
||||
|
@ -172,8 +172,8 @@ if ( canEdit('Events') ) {
|
|||
} // end if Event->DefaultVideo
|
||||
?>
|
||||
<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="scaleControl"><label for="scale"><?php echo translate('Scale') ?></label><?php echo buildSelect( "scale", $scales, "changeScale();" ); ?></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="codecControl"><label for="codec"><?php echo translate('Codec') ?></label><?php echo htmlSelect('codec', $codecs, $codec, array('onchange'=>'changeCodec(this);') ); ?></div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -192,7 +192,6 @@ if ( $video_tag ) {
|
|||
<?php
|
||||
} else {
|
||||
?>
|
||||
<?php if ( !$video_tag ) { ?>
|
||||
<div id="imageFeed">
|
||||
<?php
|
||||
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><!--progressBar-->
|
||||
</div><!--imageFeed-->
|
||||
<?php } /*end if !DefaultVideo*/ ?>
|
||||
<?php
|
||||
} /*end if !DefaultVideo*/
|
||||
?>
|
||||
<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="fastRevBtn" title="<?php echo translate('Rewind') ?>" class="inactive" data-on-click-true="streamFastRev"/>
|
||||
|
|
|
@ -18,8 +18,11 @@
|
|||
}
|
||||
?>";
|
||||
|
||||
//var newUrl = thisUrl + querySuffix;
|
||||
var newUrl = '<?php echo $_SERVER['PHP_SELF'] ?>' + querySuffix;
|
||||
if ( querySuffix == '?view=login' ) {
|
||||
querySuffix = '?view=console';
|
||||
}
|
||||
var newUrl = querySuffix;
|
||||
console.log("Redirecting to" + newUrl + ' ' + thisUrl);
|
||||
window.location.replace(newUrl);
|
||||
}
|
||||
).delay( 500 );
|
||||
|
|
Loading…
Reference in New Issue