Skip to content

Commit eb65edd

Browse files
Merge whoosinn:sandbox/ZoneMinder into ai_server
2 parents 7f63058 + f7034a0 commit eb65edd

6 files changed

Lines changed: 62 additions & 46 deletions

File tree

src/zm_ffmpeg.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ static CodecData dec_codecs[] = {
5656
{ AV_CODEC_ID_AV1, "av1", "av1_vaapi", AV_PIX_FMT_YUV420P, AV_PIX_FMT_VAAPI, AV_HWDEVICE_TYPE_VAAPI, nullptr, nullptr },
5757
{ AV_CODEC_ID_MJPEG, "mjpeg", "mjpeg", AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ422P, AV_HWDEVICE_TYPE_NONE, nullptr, nullptr },
5858
{ AV_CODEC_ID_H264, "h264", "h264", AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV420P, AV_HWDEVICE_TYPE_NONE, nullptr, nullptr },
59-
{ AV_CODEC_ID_H264, "h264", "h264_v4lm2m", AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV420P, AV_HWDEVICE_TYPE_NONE, nullptr, nullptr },
59+
{ AV_CODEC_ID_H264, "h264", "h264_v4l2m2m", AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV420P, AV_HWDEVICE_TYPE_NONE, nullptr, nullptr },
6060
{ AV_CODEC_ID_H264, "h264", "h264_qsv", AV_PIX_FMT_YUV420P, AV_PIX_FMT_QSV, AV_HWDEVICE_TYPE_QSV, nullptr, nullptr },
6161
};
6262

src/zm_image.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1853,7 +1853,7 @@ bool Image::EncodeJpeg(JOCTET *outbuffer, size_t *outbuffer_size, AVCodecContext
18531853
ret = avcodec_receive_packet(p_jpegcodeccontext, pkt);
18541854
}
18551855
if (ret == 0) {
1856-
Debug(1, "receive_packet success");
1856+
Debug(1, "receive_packet success, pkt size is %u", pkt->size);
18571857
memcpy(outbuffer, pkt->data, pkt->size);
18581858
*outbuffer_size = pkt->size;
18591859
} else {

src/zm_monitor.cpp

Lines changed: 46 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -897,12 +897,6 @@ std::shared_ptr<Monitor> Monitor::Load(unsigned int p_id, bool load_zones,
897897
}
898898

899899
bool Monitor::connect() {
900-
ReloadZones();
901-
if (zones.size() != zone_count) {
902-
Warning("Monitor %d has incorrect zone_count %d != %zu", id, zone_count,
903-
zones.size());
904-
zone_count = zones.size();
905-
}
906900
if (mem_ptr != nullptr) {
907901
Warning("Already connected. Please call disconnect first.");
908902
}
@@ -1136,6 +1130,12 @@ bool Monitor::connect() {
11361130

11371131
ReloadLinkedMonitors();
11381132

1133+
// Normally we trust ZoneCount in the monitor field. In a healthy db it should be correct.
1134+
ReloadZones();
1135+
if (zones.size() != zone_count) {
1136+
Warning("Monitor %d has incorrect zone_count %d != %zu", id, zone_count, zones.size());
1137+
zone_count = zones.size();
1138+
}
11391139

11401140
if (RTSP2Web_enabled) {
11411141
RTSP2Web_Manager = new RTSP2WebManager(this);
@@ -2441,7 +2441,7 @@ int Monitor::Analyse() {
24412441
shared_data->last_read_index = index;
24422442
shared_data->analysis_image_count = analysis_image_count;
24432443
} else if (objectdetection == OBJECT_DETECTION_NONE) {
2444-
if (1 and packet->analysis_image) {
2444+
if (packet->analysis_image) {
24452445
analysis_image_buffer[index]->Assign(*packet->analysis_image);
24462446
analysis_image_pixelformats[index] = packet->analysis_image->AVPixFormat();
24472447
Debug(1, "image format %d, for index %d", analysis_image_pixelformats[index], index);
@@ -2456,7 +2456,7 @@ int Monitor::Analyse() {
24562456
analysis_image_buffer[index]->Assign(packet->out_frame.get());
24572457
analysis_image_pixelformats[index] = static_cast<AVPixelFormat>(packet->out_frame->format);
24582458
} else {
2459-
Error( "Unable to find an image to assign for index %d packet %d", index, packet->image_index);
2459+
Debug(1, "Unable to find an image to assign for index %d packet %d", index, packet->image_index);
24602460
}
24612461
shared_analysis_timestamps[index] = zm::chrono::duration_cast<timeval>(packet->timestamp.time_since_epoch());
24622462
shared_data->last_analysis_index = index;
@@ -2643,49 +2643,56 @@ std::pair<int, std::string> Monitor::Analyse_UVICORN(std::shared_ptr<ZMPacket> p
26432643

26442644
//Image img(packet->in_frame.get(), 640, 640); // copy, since we are scaling, maybe better to take from in_frame
26452645

2646-
uint8_t *img_buffer = new uint8_t[img.Size()];
2647-
img.EncodeJpeg(static_cast<JOCTET *>(img_buffer), &img_buffer_size);
2646+
std::vector<uint8_t> img_buffer;
2647+
img_buffer.reserve(img.Size());
2648+
2649+
img.EncodeJpeg(static_cast<JOCTET *>(img_buffer.data()), &img_buffer_size);
26482650

26492651
endtime = std::chrono::system_clock::now();
26502652
Debug(1, "UVICORN took: %.3f seconds to scale file size is %zu.", FPSeconds(endtime - partial_starttime).count(), img_buffer_size);
26512653
partial_starttime = endtime;
26522654
//
26532655
std::string response;
26542656
response.reserve(4096);
2657+
26552658
std::string endpoint = stringtf("http://127.0.0.1:8000/predict/?camera_id=%d", id);
2656-
curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1);
2657-
//curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
2658-
curl_easy_setopt(curl, CURLOPT_URL, endpoint.c_str());
2659-
2660-
curl_mime *mime = nullptr;
2661-
curl_mimepart *part = nullptr;
2662-
mime = curl_mime_init(curl);
2663-
part = curl_mime_addpart(mime);
2664-
2665-
struct transfer tr = {img_buffer, img_buffer_size, 0};
2666-
curl_mime_data_cb(part, (size_t)img_buffer_size, ReadCallback, NULL, NULL, &tr);
2667-
//curl_mime_data(part, (const char *)img_buffer, img_buffer_size);
2668-
curl_mime_name(part, "file");
2669-
curl_mime_filename(part, stringtf("camera%d.jpg", id).c_str());
2670-
2671-
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
2672-
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
2673-
curl_easy_setopt(curl, CURLOPT_MIMEPOST, mime);
2674-
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
2675-
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
2676-
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10); //timeout in seconds
2677-
CURLcode res = curl_easy_perform(curl);
2678-
2679-
if (res != CURLE_OK) {
2680-
Warning("CURL: Attempted to send to %s and got %s", endpoint.c_str(), curl_easy_strerror(res));
2681-
return std::make_pair(motion_score, cause);
2659+
if (endpoint.find("http") != std::string::npos) {
2660+
curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1);
2661+
//curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
2662+
curl_easy_setopt(curl, CURLOPT_URL, endpoint.c_str());
2663+
2664+
curl_mime *mime = nullptr;
2665+
curl_mimepart *part = nullptr;
2666+
mime = curl_mime_init(curl);
2667+
part = curl_mime_addpart(mime);
2668+
2669+
struct transfer tr = {img_buffer.data(), img_buffer_size, 0};
2670+
curl_mime_data_cb(part, (size_t)img_buffer_size, ReadCallback, NULL, NULL, &tr);
2671+
//curl_mime_data(part, (const char *)img_buffer, img_buffer_size);
2672+
curl_mime_name(part, "file");
2673+
curl_mime_filename(part, stringtf("camera%d.jpg", id).c_str());
2674+
2675+
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
2676+
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
2677+
curl_easy_setopt(curl, CURLOPT_MIMEPOST, mime);
2678+
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
2679+
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
2680+
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10); //timeout in seconds
2681+
CURLcode res = curl_easy_perform(curl);
2682+
curl_mime_free(mime);
2683+
2684+
if (res != CURLE_OK) {
2685+
Warning("CURL: Attempted to send to %s and got %s", endpoint.c_str(), curl_easy_strerror(res));
2686+
return std::make_pair(motion_score, cause);
2687+
}
2688+
} else {
2689+
// Write to local hotfolder
2690+
img.WriteJpeg(endpoint + stringtf("/camera%d.jpg", id));
26822691
}
26832692
endtime = std::chrono::system_clock::now();
26842693
Debug(1, "UVICORN took: %.3f seconds to send.", FPSeconds(endtime - partial_starttime).count());
26852694
partial_starttime = endtime;
26862695
//Debug(1, "CURL: Success sending to %s, response is %s", endpoint.c_str(), response.c_str());
2687-
curl_mime_free(mime);
2688-
delete[] img_buffer;
26892696

26902697
nlohmann::json detections = nlohmann::json::parse(response);
26912698
Debug(1, "CURL detections %s", detections.dump().c_str());
@@ -2722,7 +2729,7 @@ std::pair<int, std::string> Monitor::Analyse_MotionDetection(std::shared_ptr<ZMP
27222729
std::string cause = "";
27232730

27242731
if (!(packet->in_frame or packet->image)) {
2725-
Error("no image so skipping motion detection");
2732+
Debug(1, "no image so skipping motion detection");
27262733
return std::make_pair(motion_score, cause);
27272734
} // end if has image
27282735

src/zm_monitorstream.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -408,7 +408,7 @@ bool MonitorStream::sendFrame(Image *image, SystemTimePoint timestamp) {
408408
float factor = 128.0/l_height;
409409
l_height = 128;
410410
l_width = floor(l_width * factor);
411-
Debug(1, "Adjust height to 128 using factor %.2f", factor);
411+
Debug(1, "Adjust height to min 128, width to %d using factor %.2f", l_width, factor);
412412
}
413413
l_width += (2-l_width)%2;
414414

@@ -929,6 +929,10 @@ void MonitorStream::runStream() {
929929
continue;
930930
} // end if ( (unsigned int)last_read_index != monitor->shared_data->last_decoder_index )
931931

932+
if (frames_to_send > 0 && frame_count >= frames_to_send) {
933+
break;
934+
}
935+
932936
FPSeconds sleep_time;
933937
if (now >= when_to_send_next_frame) {
934938
// sent a frame, so update
@@ -982,9 +986,6 @@ void MonitorStream::runStream() {
982986
static_cast<int64>(std::chrono::duration_cast<Microseconds>(ttl).count()));
983987
break;
984988
}
985-
if (frames_to_send > 0 && frame_count >= frames_to_send) {
986-
break;
987-
}
988989
} // end while ! zm_terminate
989990

990991
if (buffered_playback) {

src/zm_videostore.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -824,7 +824,6 @@ bool VideoStore::setup_resampler() {
824824
for (i = 0; i < num_samplerates; i++)
825825
if (audio_out_ctx->sample_rate == supported_samplerates[i])
826826
break;
827-
828827
if (i == num_samplerates) {
829828
Debug(1, "Specified sample rate %d is not supported by the %s encoder", audio_out_ctx->sample_rate, audio_out_codec->name);
830829

web/skins/classic/views/js/watch.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1110,6 +1110,15 @@ function initPage() {
11101110
} else {
11111111
alert("No monitor found for id "+monitorId);
11121112
}
1113+
1114+
// If you click on the navigation links, shut down streaming so the browser can process it
1115+
document.querySelectorAll('#main-header-nav a').forEach(function(el) {
1116+
el.onclick = function() {
1117+
if (monitorStream) monitorStream.kill();
1118+
};
1119+
});
1120+
1121+
manageRTSP2WebChannelStream();
11131122
} // initPage
11141123

11151124
function watchFullscreen() {

0 commit comments

Comments
 (0)