OpenIPC / majestic

Majestic Community edition integration kit
MIT License
32 stars 5 forks source link

[Feature request] Linux named pipe for motion detection #28

Closed k1x0r closed 2 months ago

k1x0r commented 2 years ago

Introduction

Currently it isn't possible to get the motion detection events from Majestic streamer from 3rd party applications. The solution of running a "motion-detect" example from Hi3516EV200 MPP alongside Majestic isn't possible, because of the implementation of the SDK. Having a 3rd-party app on the camera side would allow the user to send "motion detect" events to the server.

The suitable approach for this would be a linux pipe, because the implementation of sending "motion detect" event wouldn't depend on implementation in majestic. Analyzing such stream, a 3rd party app would send a request to the server, which will trigger the recording of the video on the server side.

Detailed design

The most straightforward approach is to create a pipe named e.g "/tmp/majestic_md" and send current motion detection status if it's changed. To keep the protocol simple, the pipe should output only '1' and '0' characters with the meaning: "Motion detection is present" and "Motion detection is absent".

A 'dummy' implementation for sending events to the pipe:

int main(int argc, char *argv[]) {
    signal(SIGPIPE, SIG_IGN); // Not to exit the app when the last reading process has been killed
    const char* pipeName = "/tmp/majestic_md";
    mkfifo(pipeName, 0777);                     
    int fd = open(pipeName, O_CREAT | O_WRONLY); 
    const char kOne = '1';
    const char kZero = '0';      
    for (int i = 0; i < 10000; i++) {         
       write(fd, &(i % 2 == 0 ? kZero : kOne), sizeof(char));
       usleep(1000);
    }
    close(fd);
    unlink(pipeName);
}

In order to test this sample, one should run the following command line: cat /tmp/majestic_md

And reading such pipe programmatically in blocking mode should also be also pretty straightforward:

int main(int argc, char *argv[]) {
  const char* file = "/tmp/majestic_md";
  int fd = open(file, O_RDONLY);
  if (fd < 0) return -1;
  char motionDetected;
  while (1) {
    ssize_t count = read(fd, &motionDetected, sizeof(char));
    if (count > 0) { 
        printf("Motion Detected: %c\r\n", motionDetected);
    } else {
        break;
    }
  }
  close(fd);
  unlink(file);
}
flyrouter commented 12 months ago

Please use md_detect param in /metrics setting

More params:

# HELP md_rects_recv_total Number of rectangles returned by HW MD algorithm.
# TYPE md_rects_recv_total counter
md_rects_recv_total 0
# HELP md_rects_acc_total Number of rectangles fit into ROI.
# TYPE md_rects_acc_total counter
md_rects_acc_total 0
# HELP md_status Motion detect activation status.
# TYPE md_status gauge
md_status 0
flyrouter commented 10 months ago

The request is opened again because it becomes relevant and overlaps with others.

flyrouter commented 10 months ago

In the new Majestic dated 2023.10.24

If motion detect is enabled (for Hisilion/Goke, Ingenic and Sigmastar), the first check is for an executable file: /etc/majestic_motion.sh

Then the following will be called: /etc/majestic_motion.sh 1163 0 400 275 &

The usage is: /etc/majestic_motion.sh [x coordinate] [y coordinate] [region width] [region height]

Example script:

#!/bin/sh

echo 0:[$0] 1:[$1] 2:[$2] 3:[$3] 4:[$4]

Final diagnosis

20:37:02  <SED_IVE_DETCTOR> [  motion] motion_update@155             Motion detected: [1163x0] -> [690x475]
20:37:02  <SED_IVE_DETCTOR> [   tools] motion_event@615              Execute motion script: /etc/majestic_motion.sh
0:[/etc/majestic_motion.sh] 1:[1163] 2:[0] 3:[690] 4:[475]
flyrouter commented 10 months ago

Updated the following 2023.11.02