Repository: blakeblackshear/frigate

Issue:
save_clips resulting in "moov atom not found" errors
**Describe the bug**

I have 2 types of RTSP cameras:
- yihome 1080p with the https://github.com/roleoroleo/yi-hack-Allwinner firmware
- Eufy 2k indoor: https://www.amazon.com/gp/product/B08571VZ3Q/

On both of them, enabling save_clips will just cause 'Invalid data found when processing input' problems.

Since they only have 1  stream on these cameras, I tried to remove the mapping (-map) in detect_objects.py (similar to https://github.com/blakeblackshear/frigate/issues/251), but no change.

**Version of frigate**

docker tag 0.7.2-amd64

**Config file**
Include your full config file wrapped in back ticks.
```
# Optional: port for http server (default: shown below)
web_port: 5000

# Optional: detectors configuration
# USB Coral devices will be auto detected with CPU fallback
detectors:
  # Required: name of the detector
  coral:
    # Required: type of the detector
    # Valid values are 'edgetpu' (requires device property below) and 'cpu'.
    type: edgetpu
    # Optional: device name as defined here: https://coral.ai/docs/edgetpu/multiple-edgetpu/#using-the-tensorflow-lite-python-api
    device: usb

# Required: mqtt configuration
mqtt:
  host: REDACTED
  port: 1883
  topic_prefix: frigate
  client_id: frigate
  user: REDACTED
  password: REDACTED

save_clips:
  max_seconds: 300
  clips_dir: /clips/frigate
  cache_dir: /cache

ffmpeg:
  # Optional: global ffmpeg args (default: shown below)
  global_args:
    - -hide_banner
    - -loglevel
    - panic
  # Optional: global hwaccel args (default: shown below)
  # NOTE: See hardware acceleration docs for your specific device
  hwaccel_args: []
  # Optional: global input args (default: shown below)
  input_args:
    - -avoid_negative_ts
    - make_zero
    - -fflags
    - nobuffer
    - -flags
    - low_delay
    - -strict
    - experimental
    - -fflags
    - +genpts+discardcorrupt
    - -rtsp_transport
    - tcp
    - -stimeout
    - '5000000'
    - -use_wallclock_as_timestamps
    - '1'
  # Optional: global output args (default: shown below)
  output_args:
    - -f
    - rawvideo
    - -pix_fmt
    - yuv420p


cameras:
  outdoor:
    ffmpeg:
      # Required: Source passed to ffmpeg after the -i parameter.
      # NOTE: Environment variables that begin with 'FRIGATE_' may be referenced in {}
      input: rtsp://IP/live0    
    fps: 5
    save_clips:
      enabled: True
      pre_capture: 15

  garage:
    ffmpeg:
      input: rtsp://IP/ch0_0.h264
    fps: 5
    save_clips:
      enabled: True 
      pre_capture: 15

  frontdoor:
    ffmpeg:
      input: rtsp://IP/ch0_0.h264
    fps: 5
    save_clips:
      enabled: True 
      pre_capture: 15

  outdoor2:
    ffmpeg:
      input: rtsp://IP/ch0_0.h264
    fps: 5
    save_clips:
      enabled: True 
      pre_capture: 15
```

**Logs**
```
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x5568d013c140] moov atom not found,
/cache/garage-20201025193104.mp4: Invalid data found when processing input,
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x55f7a2b05140] moov atom not found,
bad file: garage-20201025193104.mp4
```

**Frigate debug stats**
```
Output from frigate's /debug/stats endpoint
```

**FFprobe from your camera**

Run the following command and paste output below
```
ffprobe version 4.3.1 Copyright (c) 2007-2020 the FFmpeg developers
  built with gcc 9 (Ubuntu 9.3.0-10ubuntu2)
  configuration: --disable-debug --disable-doc --disable-ffplay --enable-shared --enable-avresample --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-gpl --enable-libass --enable-fontconfig --enable-libfreetype --enable-libvidstab --enable-libmp3lame --enable-libopus --enable-libtheora --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libxcb --enable-libx265 --enable-libxvid --enable-libx264 --enable-nonfree --enable-openssl --enable-libfdk_aac --enable-postproc --enable-small --enable-version3 --enable-libbluray --enable-libzmq --extra-libs=-ldl --prefix=/opt/ffmpeg --enable-libopenjpeg --enable-libkvazaar --enable-libaom --extra-libs=-lpthread --enable-vaapi --extra-cflags=-I/opt/ffmpeg/include --extra-ldflags=-L/opt/ffmpeg/lib
  libavutil      56. 51.100 / 56. 51.100
  libavcodec     58. 91.100 / 58. 91.100
  libavformat    58. 45.100 / 58. 45.100
  libavdevice    58. 10.100 / 58. 10.100
  libavfilter     7. 85.100 /  7. 85.100
  libavresample   4.  0.  0 /  4.  0.  0
  libswscale      5.  7.100 /  5.  7.100
  libswresample   3.  7.100 /  3.  7.100
  libpostproc    55.  7.100 / 55.  7.100
Input #0, rtsp, from 'rtsp://192.168.1.206/ch0_0.h264':
  Metadata:
    title           : Session streamed by "rRTSPServer"
    comment         : ch0_0.h264
  Duration: N/A, start: 0.100078, bitrate: N/A
    Stream #0:0: Video: h264, yuvj420p(pc, bt709, progressive), 1920x1080, 20 fps, 20 tbr, 90k tbn, 180k tbc
```

**Computer Hardware**
 - OS: Docker container on Ubuntu
 - Virtualization: Proxmox
 - Coral Version: USB
 - Network Setup: Wired

**Camera Info:**
- yihome 1080p with the https://github.com/roleoroleo/yi-hack-Allwinner firmware
- Eufy 2k indoor: https://www.amazon.com/gp/product/B08571VZ3Q/
- Resolution: 1080p stream, I let it auto-detect
- FPS: I set it to 5

** Additonal context*

I see the moov atom problem via ffprobe:
```
root@a797261fbe10:/opt/frigate# ls -lash /cache/frontdoor-*; ffprobe /cache/frontdoor-*
260K -rw-r--r-- 1 root root 257K Oct 25 19:50 /cache/frontdoor-20201025195032.mp4
ffprobe version 4.3.1 Copyright (c) 2007-2020 the FFmpeg developers
  built with gcc 9 (Ubuntu 9.3.0-10ubuntu2)
  configuration: --disable-debug --disable-doc --disable-ffplay --enable-shared --enable-avresample --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-gpl --enable-libass --enable-fontconfig --enable-libfreetype --enable-libvidstab --enable-libmp3lame --enable-libopus --enable-libtheora --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libxcb --enable-libx265 --enable-libxvid --enable-libx264 --enable-nonfree --enable-openssl --enable-libfdk_aac --enable-postproc --enable-small --enable-version3 --enable-libbluray --enable-libzmq --extra-libs=-ldl --prefix=/opt/ffmpeg --enable-libopenjpeg --enable-libkvazaar --enable-libaom --extra-libs=-lpthread --enable-vaapi --extra-cflags=-I/opt/ffmpeg/include --extra-ldflags=-L/opt/ffmpeg/lib
  libavutil      56. 51.100 / 56. 51.100
  libavcodec     58. 91.100 / 58. 91.100
  libavformat    58. 45.100 / 58. 45.100
  libavdevice    58. 10.100 / 58. 10.100
  libavfilter     7. 85.100 /  7. 85.100
  libavresample   4.  0.  0 /  4.  0.  0
  libswscale      5.  7.100 /  5.  7.100
  libswresample   3.  7.100 /  3.  7.100
  libpostproc    55.  7.100 / 55.  7.100
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x558400eb0b80] moov atom not found
/cache/frontdoor-20201025195032.mp4: Invalid data found when processing input
```


Discussion:
These errors are expected in some circumstances. Do you get files in the cache folder or any clips generated? 
I found the bug, but it shouldn't break the clips.

Resolving patch:
diff --git a/detect_objects.py b/detect_objects.py
--- a/detect_objects.py
+++ b/detect_objects.py
@@ -244,6 +244,7 @@ def on_connect(client, userdata, flags, rc):
             'detection_fps': mp.Value('d', 0.0),
             'detection_frame': mp.Value('d', 0.0),
             'read_start': mp.Value('d', 0.0),
+            'ffmpeg_pid': mp.Value('i', 0),
             'frame_queue': mp.Queue(maxsize=2)
         }
 
diff --git a/frigate/events.py b/frigate/events.py
--- a/frigate/events.py
+++ b/frigate/events.py
@@ -26,7 +26,7 @@ def refresh_cache(self):
         files_in_use = []
         for process_data in self.camera_processes.values():
             try:
-                ffmpeg_process = psutil.Process(pid=process_data['ffmpeg_process'].pid)
+                ffmpeg_process = psutil.Process(pid=process_data['ffmpeg_pid'].value)
                 flist = ffmpeg_process.open_files()
                 if flist:
                     for nt in flist:
diff --git a/frigate/video.py b/frigate/video.py
--- a/frigate/video.py
+++ b/frigate/video.py
@@ -122,6 +122,7 @@ def capture_frames(ffmpeg_process, camera_name, frame_shape, frame_manager: Fram
     frame_num = 0
     frame_size = frame_shape[0] * frame_shape[1] * 3 // 2
     frame_rate = EventsPerSecond()
+    frame_rate.start()
     skipped_eps = EventsPerSecond()
     skipped_eps.start()
     while True:
@@ -167,7 +168,7 @@ def capture_frames(ffmpeg_process, camera_name, frame_shape, frame_manager: Fram
         frame_queue.put(current_frame.value)
 
 class CameraWatchdog(threading.Thread):
-    def __init__(self, name, config, frame_queue, camera_fps, stop_event):
+    def __init__(self, name, config, frame_queue, camera_fps, ffmpeg_pid, stop_event):
         threading.Thread.__init__(self)
         self.name = name
         self.config = config
@@ -175,6 +176,7 @@ def __init__(self, name, config, frame_queue, camera_fps, stop_event):
         self.ffmpeg_process = None
         self.stop_event = stop_event
         self.camera_fps = camera_fps
+        self.ffmpeg_pid = ffmpeg_pid
         self.frame_queue = frame_queue
         self.frame_shape = self.config['frame_shape']
         self.frame_size = self.frame_shape[0] * self.frame_shape[1] * 3 // 2
@@ -207,6 +209,7 @@ def run(self):
     
     def start_ffmpeg(self):
       self.ffmpeg_process = start_or_restart_ffmpeg(self.config['ffmpeg_cmd'], self.frame_size)
+      self.ffmpeg_pid.value = self.ffmpeg_process.pid
       self.capture_thread = CameraCapture(self.name, self.ffmpeg_process, self.frame_shape, self.frame_queue, 
           self.config['take_frame'], self.camera_fps, self.stop_event)
       self.capture_thread.start()
@@ -234,7 +237,7 @@ def run(self):
 
 def capture_camera(name, config, process_info, stop_event):
     frame_queue = process_info['frame_queue']
-    camera_watchdog = CameraWatchdog(name, config, frame_queue, process_info['camera_fps'], stop_event)
+    camera_watchdog = CameraWatchdog(name, config, frame_queue, process_info['camera_fps'], process_info['ffmpeg_pid'], stop_event)
     camera_watchdog.start()
     camera_watchdog.join()
 


Test patch: