Results 1 to 7 of 7

Thread: QSocketNotifier--is errno still valid in slot connected to activate(int)

  1. #1
    Join Date
    Jun 2012
    Posts
    219
    Thanks
    28
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default QSocketNotifier--is errno still valid in slot connected to activate(int)

    I have an application that's streaming frames from a webcam. After a few minutes of streaming, the QSocketNotifier associated with camera fd stops generating activated events.

    This might be a camera hardware, firmware, or RPI kernel issue, but I want to make sure my use of a QSocketNotifier instead of the exact code in the Vl42 example isn't part of the problem



    In examples mainLoop() function there is a blocking select:

    Qt Code:
    1. r = select(fd + 1, &fds, NULL, NULL, &tv);
    2. if (-1 == r) {
    3. if (EINTR == errno)
    4. continue;
    To copy to clipboard, switch view to plain text mode 

    I have these lines of code instead:

    Qt Code:
    1. fd = open(dev_name.toAscii().data(), O_RDWR /* required */ | O_NONBLOCK, 0);
    2. notify_fd = new QSocketNotifier(fd, QSocketNotifier::Read);
    3. connect(notify_fd, SIGNAL(activated(int)), this, SLOT(read_frame(int)), Qt::QueuedConnection );
    To copy to clipboard, switch view to plain text mode 

    So, what happens when the fd associated the QSocketNotifier breaks out of the select with EINTR==errno? I've been assuming that's a QSocketNotifier::Exception event, so creating the QSocketNotifier using a QSocketNotifier::Read type would result in exceptions like the EINTR==errno being ignored. That's the equivalent of the example code.

    Is this true? Can I check errno in the read_frame slot, or will it likely be reset before the slot code executes?

    Next step will be to redo the code without the QtSocketNotifier, but that will take a few hours to get working, I think.

    Thanks!

  2. #2
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: QSocketNotifier--is errno still valid in slot connected to activate(int)

    Your approach looks valid to me.
    Have you tried a second notifier for the Exception type?

    Cheers,
    _

  3. #3
    Join Date
    Jun 2012
    Posts
    219
    Thanks
    28
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QSocketNotifier--is errno still valid in slot connected to activate(int)

    Thanks for the reply.

    We think alike--yes, I added this since my post:

    exception_fd = new QSocketNotifier(fd, QSocketNotifier::Exception);
    connect(exception_fd, SIGNAL(activated(int)), this, SLOT(printException(int)));

    void printException(int _fd){qDebug() << "errno: " << errno;}

    I reproduce the hang, but printException never gets called.

  4. #4
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: QSocketNotifier--is errno still valid in slot connected to activate(int)

    Strange, the Qt event loop, or rather the unix event dispatcher works quite similar to the select() call.

    Cheers,
    _

  5. #5
    Join Date
    Oct 2009
    Posts
    483
    Thanked 97 Times in 94 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: QSocketNotifier--is errno still valid in slot connected to activate(int)

    What do you do in the read_frame(int) slot? Are you certain that you read all the bytes available for reading? The name of the slot suggests that it reads exactly one frame. Perhaps, at some point, two frames (or one frame and a fraction of another, etc.) are available for reading by the time the slot has a chance to run, then the slot only reads one frame, and activated(int) is never emitted again since there are some bytes still waiting to be read.

  6. The following user says thank you to yeye_olive for this useful post:

    davethomaspilot (12th January 2015)

  7. #6
    Join Date
    Jun 2012
    Posts
    219
    Thanks
    28
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QSocketNotifier--is errno still valid in slot connected to activate(int)

    While that's not the cause of this issue (camera quits streaming), your note got me looking at the read_frame code.

    I'd had a code fragment that just ignored the frame (by re-queuing without processing it) when it didn't match the expected frame size. However, that code was for a specific camera resolution and needed changing for the camera I'm testing with now.

    But, the hang occurs immediately after receiving frames of the expected size. I fixedthe code that ignores frames with unexpected buffer sizes, but it never executes even when I see the hangs. So, that's not what's causing this issue.

    But thanks for the good suggestion! It lead me to fix what would have been a nasty bug.

    Code for read_frame:

    Qt Code:
    1. int CameraInterface::read_frame(int)
    2. {
    3. struct v4l2_buffer buf;
    4. unsigned int i;
    5. //qDebug() << frames_read++;
    6. if (testing_only) return 0;
    7.  
    8.  
    9. if (!stream_forever && frames_read >= frame_count)
    10. {
    11. qDebug() << "frame count exceeded";
    12. emit frames_done();
    13. return 0;
    14. }
    15.  
    16. switch (io)
    17. {
    18. .....
    19.  
    20. case IO_METHOD_MMAP:
    21. CLEAR(buf);
    22.  
    23. buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    24. buf.memory = V4L2_MEMORY_MMAP;
    25.  
    26. if (-1 == xioctl(fd, VIDIOC_DQBUF, &buf))
    27. {
    28. switch (errno)
    29. {
    30. case EAGAIN:
    31. return 0;
    32.  
    33. case EIO:
    34. /* Could ignore EIO, see spec. */
    35.  
    36. /* fall through */
    37.  
    38. default:
    39. errno_exit("VIDIOC_DQBUF");
    40. }
    41. }
    42. #if 0
    43. qDebug() << "frames read: " << frames_read++;
    44. if (frames_read % 2)
    45. {
    46. qDebug() << "skipping frame";
    47. xioctl(fd, VIDIOC_QBUF, &buf);
    48. return 1;
    49. }
    50. #endif
    51. frameQueued = false;
    52. assert(buf.index < n_buffers);
    53.  
    54. qDebug() << "\t\t\tframe DQ'ed, bytes " << buf.bytesused << "buffers = " << n_buffers;
    55. if (buf.bytesused != 921600)
    56. {
    57. qDebug() << "partial frame";
    58. xioctl(fd, VIDIOC_QBUF, &buf);
    59. frameQueued = true;
    60. qDebug() << "Unexpected framesize" << buf.bytesused;
    61. //exit(-1);
    62. }
    63. /*
    64.   if (!colorCamera && buf.bytesused < 1843200)
    65.   {
    66.   xioctl(fd, VIDIOC_QBUF, &buf);
    67.   frameQueued = true;
    68.   qDebug() << "Partial frame" << buf.bytesused;
    69.   }
    70.   */
    71. else
    72. {
    73.  
    74. emit frameReady(buffers[buf.index].start,buf.bytesused);
    75.  
    76. // when streaming expect client to send message to queue next frame
    77. // otherwise, we know there's been seconds for client to process frame
    78. // setup = false;
    79. if (!setup)
    80. {
    81. xioctl(fd, VIDIOC_QBUF, &buf);
    82. frameQueued=true;
    83. }
    84. }
    85.  
    86. break;
    87.  
    88. ...
    To copy to clipboard, switch view to plain text mode 

  8. #7
    Join Date
    Jun 2012
    Posts
    219
    Thanks
    28
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QSocketNotifier--is errno still valid in slot connected to activate(int)

    The problem probably isn't related to QSocketNotifier.

    I hacked my code to immediately enqueue after each dequeue. With this change, it streamed for several hours without hanging. This is using the same code that binds the activated (type = read) signal from a QTSocketNotifier to a slot to do the xioctl to dequeue the frame.

    So, I conclude that the issue isn't related to my use of QSocketNotifier.

    I also tried sleeping two seconds after each dequeue, then enqueing. So far,no hang, but it will have to run much longer to get a lot of frames through.

Similar Threads

  1. Slot connected to a generic signal
    By Momergil in forum Qt Programming
    Replies: 5
    Last Post: 28th June 2014, 22:42
  2. Replies: 11
    Last Post: 2nd February 2013, 14:39
  3. Replies: 2
    Last Post: 26th August 2011, 08:51
  4. Connected QTimer slot not being called
    By Polnareff in forum Qt Programming
    Replies: 4
    Last Post: 27th July 2010, 15:55
  5. Disconnect slot when another is being connected
    By holst in forum Qt Programming
    Replies: 4
    Last Post: 8th September 2009, 09:49

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.