]> git.sesse.net Git - bmusb/blobdiff - v4l2proxy.cpp
Release 0.7.8.
[bmusb] / v4l2proxy.cpp
index 3cb3bc0af137c197aee90bfd473f830e03c338aa..7ead4aa1b60f352ca5070724aed68a9a0225f4e5 100644 (file)
@@ -12,6 +12,7 @@
 #include <string.h>
 #include <unistd.h>
 #include <fcntl.h>
+#include <errno.h>
 #include <sys/ioctl.h>
 #include <linux/videodev2.h>
 #include <bmusb/bmusb.h>
@@ -69,7 +70,7 @@ void frame_callback(uint16_t timecode,
                uint8_t *origptr = video_frame.data + video_offset + video_format.extra_lines_top * video_format.stride;
 #if __SSE2__
                __m128i *ptr = (__m128i *)origptr;
-               for (unsigned i = 0; i < video_format.width * video_format.height / 8; ++i) {
+               for (unsigned i = 0; i < video_format.stride * video_format.height / 16; ++i) {
                        __m128i val = _mm_loadu_si128(ptr);
                        val = _mm_slli_epi16(val, 8) | _mm_srli_epi16(val, 8);
                        _mm_storeu_si128(ptr, val);
@@ -77,14 +78,27 @@ void frame_callback(uint16_t timecode,
                }
 #else
                uint8_t *ptr = origptr;
-               for (unsigned i = 0; i < video_format.width * video_format.height; ++i) {
+               for (unsigned i = 0; i < video_format.stride * video_format.height / 4; ++i) {
                        swap(ptr[0], ptr[1]);
                        swap(ptr[2], ptr[3]);
                        ptr += 4;
                }
 #endif
 
-               write(video_fd, origptr, video_frame.len);
+               size_t len = video_frame.len;
+               while (len > 0) {
+                       ssize_t ret = write(video_fd, origptr, len);
+                       if (ret == -1) {
+                               if (errno == EINTR) {
+                                       continue;
+                               } else {
+                                       perror("write");
+                                       break;  // Hope for better luck next frame.
+                               }
+                       }
+                       origptr += ret;
+                       len -= ret;
+               }
        }
 
        usb->get_video_frame_allocator()->release_frame(video_frame);