Closed intc closed 2 years ago
It seems to me that even though you have set the source as JPEG on the "faulty" instance, it is trying to grab frames from an expected mp4 container. Can you query your monitor using sudo zmu -m[Monitor ID] -q -U username -P password
?
Id : 3
Name : katu
Type : Remote
Protocol : http
Host : 10.xx.xx.xx
Port : 80
Path : /stream?uri=video.pro2
Width : 1920
Height : 1080
Colours : 3
Subpixel Order : 6
Event Prefix : Katu-
Label Format : %N - %d/%m/%y %H:%M:%S
Label Coord : 0,0
Label Size : 1
Image Buffer Count : 3
Warmup Count : 0
Pre Event Count : 5
Post Event Count : 5
Stream Replay Buffer : 0
Alarm Frame Count : 1
Section Length : 600
Min Section Length : 10
Maximum FPS : 0.00
Alarm Maximum FPS : 0.00
Reference Blend %ge : 12
Alarm Reference Blend %ge : 6
Track Motion : 0
Function: 3 - Motion Detection
Zones : 0
Recording Enabled? enabled
Events Enabled (!TRIGGER_OFF)? enabled
Motion Detection Enabled? enabled
Alright that doesnt have the writer info, can you open a MySQL session and try select Id, VideoWriter, SaveJPEGs from Monitors;
or select VideoWriter, SaveJPEGs from Monitors where Id=3;
Oh, also FYI 'Remote' type has knows issues, can you try ffmpeg monitor type?
+----+-------------+-----------+
| Id | VideoWriter | SaveJPEGs |
+----+-------------+-----------+
| 1 | 0 | 3 |
| 2 | 0 | 3 |
| 3 | 0 | 3 |
+----+-------------+-----------+
Source type: Ffmpeg - No effect on the playback issue.
Checked against a recorded event generated AFTER source type switch.
Id : 3
Name : rk7 katu
Type : File
Path : http://10.xx.xx.xx/stream?uri=video.pro2
Width : 1920
Height : 1080
...
Well the DB and settings are in sync, I am unsure as to what the root cause may be. Have you tried running ffmpeg? In another issue, the dev mentions 'Remote' as being problematic.
After reading that forum post it seems like it may also be something internal to ZM in the code. I am assuming you have checked the JPEgs on disk and all is well there? Is this H264 codec?
Can you try running debug logs on this monitor and posting a sanitized gist of the debug logs for zms_m3 so they are available for the dev to look at?
JPEGs on the disk are fine (the playback is 100% ok when down scaled - and there's no other source than these files). I try to take some time later with debug options set on the m3 streaming server.
Inspired by the log line in zms_eXXXX.log:
02/16/22 05:19:29.132015 zms_e49591[18118].WAR-zm_eventstream.cpp/1131
Altered build/config.h on "faulty" node:
// #define HAVE_SENDFILE 1
Rebuilt ZM -> Playback OK ("Scale == Actual")
I reverted my config.h hack and did more proper fix so that sendfile works now. I'm not very happy about the type casts etc. If sendfile fails there will be a warning and EventStream::send_file() will exit with an error.
Quoting sendfile(2) man page:
Note that a successful call to sendfile() may write fewer bytes than requested; the caller should be prepared to retry the call if there were unsent bytes.
The diff:
diff --git a/src/zm_eventstream.cpp b/src/zm_eventstream.cpp
index 34f693f36..4d3c115f4 100644
--- a/src/zm_eventstream.cpp
+++ b/src/zm_eventstream.cpp
@@ -1107,6 +1107,7 @@ bool EventStream::send_file(const std::string &filepath) {
}
#if HAVE_SENDFILE
static struct stat filestat;
+ off_t off = 0;
if (fstat(fileno(fdj), &filestat) < 0) {
fclose(fdj); /* Close the file handle */
Error("Failed getting information about file %s: %s", filepath.c_str(), strerror(errno));
@@ -1122,14 +1123,21 @@ bool EventStream::send_file(const std::string &filepath) {
Info("Unable to send raw frame %d: %s", curr_frame_id, strerror(errno));
return false;
}
- int rc = zm_sendfile(fileno(stdout), fileno(fdj), 0, (int)filestat.st_size);
- if (rc == (int)filestat.st_size) {
- // Success
- fclose(fdj); /* Close the file handle */
- return true;
+ // send
+ int count = (int)filestat.st_size;
+ int rc = 0;
+ while (count > 0) {
+ count = count - rc;
+ rc = zm_sendfile(fileno(stdout), fileno(fdj), &off, (size_t)count);
+ if (rc < 0) {
+ Warning("Unable to send raw frame %d: %s, rc: %d, count: %d, off: %d, size: %d",
+ curr_frame_id, strerror(errno), rc, count, (int)off, (int)filestat.st_size);
+ fclose(fdj); /* Close the file handle */
+ return false;
+ }
}
- Warning("Unable to send raw frame %d: %s rc %d != %d",
- curr_frame_id, strerror(errno), rc, (int)filestat.st_size);
+ fclose(fdj); /* Close the file handle */
+ return true;
#endif
static unsigned char temp_img_buffer[ZM_MAX_IMAGE_SIZE];
Yeah I was suspecting that. I am reworking it all. Should be able to free up ram as well.
Environment
We have two ZM instances. Most of the system packages should be at same versions (except kernel as stated above).
Bug
"Faulty" instance has exactly same symptoms as described here: https://forums.zoneminder.com/viewtopic.php?t=31455 - We observe playback issues when Scale >= Actual (corrupted video). On "OK" instance the playback works without issues.
"Scale == 3/4x" works without issues and no zms_eXXXX.log file is created during the playback.
I have done my best to unify all configuration parameters between the two instances. Storage settings:
Faulty instance creates a zms_eXXXX.log file during the playback - Please see "Debug Logs" below.
I have no idea why the faulty instance attempts to open the .mp4 file even the camera storage settings has Video Writer disabled. Could this be related?
To Reproduce
Open saved event and start playback with Scale >= "Actual". Like said above we have only one zm node which does this.
Expected behavior
Normal clean playback despite selected scaling.
Debug Logs