From 3a562c64fb7f54aa2cdf61029bb26a90af069b3e Mon Sep 17 00:00:00 2001 From: aangerma Date: Tue, 21 Aug 2018 14:19:25 +0300 Subject: [PATCH] Libuvc - fixed bug on start and stop stream --- src/libuvc/libuvc.cpp | 1 + src/libuvc/libuvc_internal.h | 1 + src/libuvc/stream.cpp | 45 +++++++++++++++--------------------- 3 files changed, 21 insertions(+), 26 deletions(-) diff --git a/src/libuvc/libuvc.cpp b/src/libuvc/libuvc.cpp index 21fcb050b3..7572b4dfd7 100644 --- a/src/libuvc/libuvc.cpp +++ b/src/libuvc/libuvc.cpp @@ -356,6 +356,7 @@ namespace librealsense _is_capturing = false; _is_started = false; } + uvc_stop_streaming(_device_handle); } void power_D0() { diff --git a/src/libuvc/libuvc_internal.h b/src/libuvc/libuvc_internal.h index 54ea61eb65..e32d41b47b 100644 --- a/src/libuvc/libuvc_internal.h +++ b/src/libuvc/libuvc_internal.h @@ -261,6 +261,7 @@ struct uvc_stream_handle { uint8_t *outbuf, *holdbuf; std::mutex cb_mutex; std::condition_variable cb_cond; + std::condition_variable cb_cancel; std::thread cb_thread; uint32_t last_polled_seq; uvc_frame_callback_t *user_cb; diff --git a/src/libuvc/stream.cpp b/src/libuvc/stream.cpp index 5a55b63fce..77bce7d0e4 100644 --- a/src/libuvc/stream.cpp +++ b/src/libuvc/stream.cpp @@ -699,10 +699,7 @@ uvc_error_t uvc_probe_stream_ctrl( */ void _uvc_swap_buffers(uvc_stream_handle_t *strmh) { uint8_t *tmp_buf; - { - std::unique_lock lock(strmh->cb_mutex); - /* swap the buffers */ tmp_buf = strmh->holdbuf; strmh->hold_bytes = strmh->got_bytes; @@ -840,9 +837,14 @@ void LIBUSB_CALL _uvc_stream_callback(struct libusb_transfer *transfer) { switch (transfer->status) { case LIBUSB_TRANSFER_COMPLETED: if (transfer->num_iso_packets == 0) { + std::unique_lock lock(strmh->cb_mutex); /* This is a bulk mode transfer, so it just has one payload transfer */ _uvc_process_payload(strmh, transfer->buffer, transfer->actual_length); - } else { + + + } + else + { /* This is an isochronous mode transfer, so each packet has a payload transfer */ int packet_id; @@ -887,8 +889,9 @@ void LIBUSB_CALL _uvc_stream_callback(struct libusb_transfer *transfer) { } resubmit = 0; + strmh->cb_cancel.notify_all(); } - strmh->cb_cond.notify_all(); + break; } @@ -896,13 +899,14 @@ void LIBUSB_CALL _uvc_stream_callback(struct libusb_transfer *transfer) { case LIBUSB_TRANSFER_STALL: case LIBUSB_TRANSFER_OVERFLOW: case LIBUSB_TRANSFER_ERROR: - UVC_DEBUG("retrying transfer, status = %d", transfer->status); break; } - if ( strmh->running && resubmit ) - libusb_submit_transfer(transfer); + if (strmh && strmh->running && resubmit ) + { + auto res = libusb_submit_transfer(transfer); + } } /** Begin streaming video from the camera into the callback function. @@ -1194,7 +1198,6 @@ void *_uvc_user_caller(void *arg) { _uvc_populate_frame(strmh); } - strmh->user_cb(&strmh->frame, strmh->user_ptr); } while(1); @@ -1381,32 +1384,21 @@ uvc_error_t uvc_stream_stop(uvc_stream_handle_t *strmh) { if (!strmh->running) return UVC_ERROR_INVALID_PARAM; - strmh->running = 0; - { - std::unique_lock lock(strmh->cb_mutex); - - for (i = 0; i < LIBUVC_NUM_TRANSFER_BUFS; i++) { + std::unique_lock lock(strmh->cb_mutex); + strmh->running = 0; + for (i = 0; i < LIBUVC_NUM_TRANSFER_BUFS; i++) { if (strmh->transfers[i] != NULL) { int res = libusb_cancel_transfer(strmh->transfers[i]); - if (res < 0 && res != LIBUSB_ERROR_NOT_FOUND) { + if (res < 0) { free(strmh->transfers[i]->buffer); libusb_free_transfer(strmh->transfers[i]); strmh->transfers[i] = NULL; } + else + strmh->cb_cancel.wait(lock); } } - - /* Wait for transfers to complete/cancel */ - do { - for (i = 0; i < LIBUVC_NUM_TRANSFER_BUFS; i++) { - if (strmh->transfers[i] != NULL) - break; - } - if (i == LIBUVC_NUM_TRANSFER_BUFS) - break; - strmh->cb_cond.wait(lock); - } while (1); } // Kick the user thread awake strmh->cb_cond.notify_all(); @@ -1418,6 +1410,7 @@ uvc_error_t uvc_stream_stop(uvc_stream_handle_t *strmh) { * LIBUSB_TRANSFER_CANCELLED transfer) */ strmh->cb_thread.join(); } + auto res = libusb_clear_halt(strmh->devh->usb_devh,strmh->stream_if->bEndpointAddress); return UVC_SUCCESS; }