Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gst-launch-1.0 stops at first frame #535

Closed
sanbrother opened this issue Apr 6, 2023 · 2 comments · Fixed by #536
Closed

gst-launch-1.0 stops at first frame #535

sanbrother opened this issue Apr 6, 2023 · 2 comments · Fixed by #536
Assignees
Labels
needs triage new issues

Comments

@sanbrother
Copy link
Contributor

Environment

  • v4l2loopback version: upstream commit fb410fc
  • kernel version: 5.3.0-28-generic
  • Distribution (+version): Ubuntu 18.04.4 LTS

Problem:

gst-launch-1.0 stops at first frame, seems freezed.

Steps to reproduce:

sudo modprobe v4l2loopback max_buffers=8
gst-launch-1.0 -v videotestsrc ! v4l2sink device=/dev/video0
# launch VLC Media Player
vlc -d v4l2:///dev/video0

Relevant Code:

I'm sure, the commit ff4e9ee introduced a bug.

Here is my patch, strange, but works.
As far as I understand, write_position and read_position should not be applied modulo operation.

index 1a02f57..9b04506 100644
--- a/v4l2loopback.c
+++ b/v4l2loopback.c
@@ -96,10 +96,10 @@ MODULE_LICENSE("GPL");
 static inline int mod_inc(int *number, int mod)
 {
        int result;
-       result = (*number + 1) % mod;
+       result = (*number) % mod;
        if (unlikely(result < 0))
                result += mod;
-       *number = result;
+       *number = (*number + 1);
        return result;
 }
@betaboon
Copy link

betaboon commented Apr 6, 2023

i just ran into the same issue.
running a git bisect between v0.12.7 and current HEAD also shows that the mentioned commit is the culprit.
i then tested with a revert-commit and the problem goes away.

this is the revert-patch:

diff --git a/v4l2loopback.c b/v4l2loopback.c
index 2ab1f76..2514f09 100644
--- a/v4l2loopback.c
+++ b/v4l2loopback.c
@@ -92,17 +92,6 @@ MODULE_LICENSE("GPL");
 		}                                                      \
 	} while (0)
 
-/* TODO: Make sure that function is never interrupted. */
-static inline int mod_inc(int *number, int mod)
-{
-	int result;
-	result = (*number + 1) % mod;
-	if (unlikely(result < 0))
-		result += mod;
-	*number = result;
-	return result;
-}
-
 static inline void v4l2l_get_timestamp(struct v4l2_buffer *b)
 {
 	/* ktime_get_ts is considered deprecated, so use ktime_get_ts64 if possible */
@@ -1424,8 +1413,9 @@ static int vidioc_reqbufs(struct file *file, void *fh,
 			i = dev->write_position;
 			list_for_each_entry(pos, &dev->outbufs_list,
 					    list_head) {
-				dev->bufpos2index[mod_inc(&i, b->count)] =
+				dev->bufpos2index[i % b->count] =
 					pos->buffer.index;
+				++i;
 			}
 		}
 
@@ -1489,9 +1479,10 @@ static void buffer_written(struct v4l2_loopback_device *dev,
 	del_timer_sync(&dev->timeout_timer);
 	spin_lock_bh(&dev->lock);
 
-	dev->bufpos2index[mod_inc(&dev->write_position, dev->used_buffers)] =
+	dev->bufpos2index[dev->write_position % dev->used_buffers] =
 		buf->buffer.index;
 	list_move_tail(&buf->list_head, &dev->outbufs_list);
+	++dev->write_position;
 	dev->reread_count = 0;
 
 	check_timers(dev);
@@ -1586,7 +1577,8 @@ static int get_capture_buffer(struct file *file)
 		if (dev->write_position >
 		    opener->read_position + dev->used_buffers)
 			opener->read_position = dev->write_position - 1;
-		pos = mod_inc(&opener->read_position, dev->used_buffers);
+		pos = opener->read_position % dev->used_buffers;
+		++opener->read_position;
 	}
 	timeout_happened = dev->timeout_happened;
 	dev->timeout_happened = 0;

@sanbrother
Copy link
Contributor Author

i just ran into the same issue. running a git bisect between v0.12.7 and current HEAD also shows that the mentioned commit is the culprit. i then tested with a revert-commit and the problem goes away.

It seems that, the base code depends heavily on read_position and write_position.
If modulo operation applied on the two variables, it is hard to judge if (write_position > read_position) is true.
So, as you see, my patch just increase the input number, but returns a modulo value. But it is strange to read the code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs triage new issues
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants