branch: elpa/camera
commit 63c41548d77f271b14b8333e4f91cfdf786f1ce8
Author: Akib Azmain Turja <a...@disroot.org>
Commit: Akib Azmain Turja <a...@disroot.org>

    Rewrite ffmpeg part to fix flickering
---
 camera.el | 89 +++++++++++++++++++++++++++++++++++++++++++++++----------------
 1 file changed, 67 insertions(+), 22 deletions(-)

diff --git a/camera.el b/camera.el
index 7330a8c33e..d5a20ffe50 100644
--- a/camera.el
+++ b/camera.el
@@ -158,32 +158,77 @@ Don't do anything if current buffer is not BUFFER."
     (display-buffer (current-buffer))
     (camera--update-frame (current-buffer))))
 
+(defvar camera--ffmpeg-process nil
+  "The ffmpeg process.")
+
+(defvar camera--ffmpeg-image-file nil
+  "The image file where the frames are being saved.")
+
+(defvar camera--ffmpeg-frame-size nil
+  "Size of frames being captured by the current ffmpeg process.")
+
+(defun camera--ffmpeg-cleanup ()
+  "Cleanup before killing buffer."
+  (when camera--ffmpeg-process
+    (when (process-live-p camera--ffmpeg-process)
+      (kill-process camera--ffmpeg-process)
+      (while (process-live-p camera--ffmpeg-process)
+        (sit-for 0.05)))
+    (when (process-buffer camera--ffmpeg-process)
+      (kill-buffer (process-buffer camera--ffmpeg-process))))
+  (when (and camera--ffmpeg-image-file
+             (file-exists-p camera--ffmpeg-image-file))
+    (delete-file camera--ffmpeg-image-file)))
+
 (defun camera-capture-frame-ffmpeg (size)
   "Capture a frame from the camera with `ffmpeg'.
 
 Return an image of the frame.  Try to make the size of the frame SIZE."
-  (let ((temp-file (make-temp-file "emacs-camera-ffmpeg-" nil ".jpeg")))
-    (unwind-protect
-        ;; TODO: Refractor.
-        (with-temp-buffer
-
-          ;; `ffmpeg' complains when file exists.
-          (when (file-exists-p temp-file)
-            (delete-file temp-file))
-          (let ((process (start-file-process
-                          "camera-ffmpeg" (current-buffer)
-                          "ffmpeg" "-f" "video4linux2" "-s"
-                          (format "%ix%i" (car size) (cdr size))
-                          "-i" camera-ffmpeg-video-device "-frames" "1"
-                          temp-file)))
-            (while (process-live-p process)
-              (sleep-for 0.05)))
-          (erase-buffer)
-          (set-buffer-multibyte nil)
-          (insert-file-contents-literally temp-file)
-          (create-image (buffer-string) 'jpeg t))
-      (when (file-exists-p temp-file)
-        (delete-file temp-file)))))
+  (when (and camera--ffmpeg-process
+             (not (process-live-p camera--ffmpeg-process)))
+    (message "ffmpeg process exited with status %i, retrying..."
+             (process-exit-status camera--ffmpeg-process)))
+  (unless (and (equal camera--ffmpeg-frame-size size)
+               camera--ffmpeg-image-file
+               camera--ffmpeg-process
+               (process-live-p camera--ffmpeg-process))
+    (when camera--ffmpeg-process
+      (when (process-live-p camera--ffmpeg-process)
+        (kill-process camera--ffmpeg-process)
+        (while (process-live-p camera--ffmpeg-process)
+          (sit-for 0.05)))
+      (when (process-buffer camera--ffmpeg-process)
+        (kill-buffer (process-buffer camera--ffmpeg-process))))
+    (when (and camera--ffmpeg-image-file
+               (file-exists-p camera--ffmpeg-image-file))
+      (delete-file camera--ffmpeg-image-file))
+    (setq-local camera--ffmpeg-image-file
+                (make-temp-file "emacs-camera-ffmpeg-" nil ".jpeg"))
+    (when (and camera--ffmpeg-image-file
+               (file-exists-p camera--ffmpeg-image-file))
+      (delete-file camera--ffmpeg-image-file))
+    (setq-local camera--ffmpeg-frame-size size)
+    (setq-local camera--ffmpeg-process
+                (start-file-process
+                 "camera-ffmpeg"
+                 (generate-new-buffer " *camera-ffmpeg*" t)
+                 "ffmpeg" "-f" "video4linux2" "-s"
+                 (format "%ix%i" (car camera--ffmpeg-frame-size)
+                         (cdr camera--ffmpeg-frame-size))
+                 "-i" camera-ffmpeg-video-device
+                 "-fpsmax" (number-to-string camera-framerate)
+                 "-update" "true" camera--ffmpeg-image-file))
+    (while (and (process-live-p camera--ffmpeg-process)
+                (not (file-exists-p camera--ffmpeg-image-file)))
+      (sleep-for 0.05))
+    (add-hook 'kill-buffer-hook #'camera--ffmpeg-cleanup nil t))
+  (when (file-exists-p camera--ffmpeg-image-file)
+    (let ((img-file camera--ffmpeg-image-file))
+      (with-temp-buffer
+        (erase-buffer)
+        (set-buffer-multibyte nil)
+        (insert-file-contents-literally img-file)
+        (create-image (buffer-string) 'jpeg t)))))
 
 (provide 'camera)
 ;;; camera.el ends here

Reply via email to