Skip to content

Commit e56b3fe

Browse files
committed
multiple-acquisition: callback method is not compatible with main thread polling
When the callback is called with ARV_STREAM_CALLBACK_TYPE_BUFFER_DONE, the buffer is already pushed in the output FIFO, and signaled. The buffer could be already pushed back to the input FIFO.
1 parent 4565ccb commit e56b3fe

3 files changed

Lines changed: 135 additions & 31 deletions

File tree

02-multiple-acquisition-callback.c

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
/* SPDX-License-Identifier:Unlicense */
2+
3+
/* Aravis header */
4+
5+
#include <arv.h>
6+
7+
/* Standard headers */
8+
9+
#include <stdlib.h>
10+
#include <stdio.h>
11+
12+
typedef struct {
13+
ArvStream *stream;
14+
int counter;
15+
gboolean done;
16+
} ArvStreamCallbackData;
17+
18+
static void
19+
stream_callback (void *user_data, ArvStreamCallbackType type, ArvBuffer *buffer)
20+
{
21+
ArvStreamCallbackData *callback_data = (ArvStreamCallbackData *) user_data;
22+
23+
/* This code is called from the stream receiving thread, which means all the time spent there is less time
24+
* available for the reception of incoming packets */
25+
26+
switch (type) {
27+
case ARV_STREAM_CALLBACK_TYPE_INIT:
28+
/* Stream thread started.
29+
*
30+
* Here you may want to change the thread priority arv_make_thread_realtime() or
31+
* arv_make_thread_high_priority() */
32+
break;
33+
case ARV_STREAM_CALLBACK_TYPE_START_BUFFER:
34+
/* The first packet of a new frame was received */
35+
break;
36+
case ARV_STREAM_CALLBACK_TYPE_BUFFER_DONE:
37+
/* The buffer is received, successfully or not. It is already pushed in the output FIFO.
38+
*
39+
* You could here signal the new buffer to another thread than the main one, and pull/push the
40+
* buffer from this another thread.
41+
*
42+
* Or use the buffer here. We need to pull it, process it, then push it back for reuse by the
43+
* stream receiving thread */
44+
45+
g_assert (buffer == arv_stream_pop_buffer(callback_data->stream));
46+
g_assert (buffer != NULL);
47+
48+
/* Retrieve 10 buffers */
49+
if (callback_data->counter < 10) {
50+
if (arv_buffer_get_status(buffer) == ARV_BUFFER_STATUS_SUCCESS)
51+
printf ("Acquired %d×%d buffer\n",
52+
arv_buffer_get_image_width (buffer),
53+
arv_buffer_get_image_height (buffer));
54+
55+
arv_stream_push_buffer(callback_data->stream, buffer);
56+
callback_data->counter++;
57+
} else {
58+
callback_data->done = TRUE;
59+
}
60+
61+
break;
62+
case ARV_STREAM_CALLBACK_TYPE_EXIT:
63+
/* Stream thread ended */
64+
break;
65+
}
66+
}
67+
68+
/*
69+
* Connect to the first available camera, then acquire 10 buffers.
70+
*/
71+
72+
int
73+
main (int argc, char **argv)
74+
{
75+
ArvCamera *camera;
76+
GError *error = NULL;
77+
78+
/* Connect to the first available camera */
79+
camera = arv_camera_new (NULL, &error);
80+
81+
if (ARV_IS_CAMERA (camera)) {
82+
ArvStreamCallbackData callback_data;
83+
84+
printf ("Found camera '%s'\n", arv_camera_get_model_name (camera, NULL));
85+
86+
/* Create the stream object without callback */
87+
callback_data.counter = 0;
88+
callback_data.done = FALSE;
89+
callback_data.stream = arv_camera_create_stream (camera, stream_callback, &callback_data, &error);
90+
if (ARV_IS_STREAM (callback_data.stream)) {
91+
int i;
92+
size_t payload;
93+
94+
/* Retrieve the payload size for buffer creation */
95+
payload = arv_camera_get_payload (camera, &error);
96+
if (error == NULL) {
97+
/* Insert some buffers in the stream buffer pool */
98+
for (i = 0; i < 2; i++)
99+
arv_stream_push_buffer (callback_data.stream, arv_buffer_new (payload, NULL));
100+
}
101+
102+
if (error == NULL)
103+
/* Start the acquisition */
104+
arv_camera_start_acquisition (camera, &error);
105+
106+
if (error == NULL) {
107+
while (!callback_data.done) {
108+
usleep (1000);
109+
}
110+
}
111+
112+
if (error == NULL)
113+
/* Stop the acquisition */
114+
arv_camera_stop_acquisition (camera, &error);
115+
116+
/* Destroy the stream object */
117+
g_clear_object (&callback_data.stream);
118+
}
119+
120+
/* Destroy the camera instance */
121+
g_clear_object (&camera);
122+
}
123+
124+
if (error != NULL) {
125+
/* En error happened, display the correspdonding message */
126+
printf ("Error: %s\n", error->message);
127+
return EXIT_FAILURE;
128+
}
129+
130+
return EXIT_SUCCESS;
131+
}
Lines changed: 2 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -9,34 +9,6 @@
99
#include <stdlib.h>
1010
#include <stdio.h>
1111

12-
static void
13-
stream_callback (void *user_data, ArvStreamCallbackType type, ArvBuffer *buffer)
14-
{
15-
/* This code is called from the stream receiving thread, which means all the time spent there is less time
16-
* available for the reception of incoming packets */
17-
18-
switch (type) {
19-
case ARV_STREAM_CALLBACK_TYPE_INIT:
20-
/* Stream thread started.
21-
*
22-
* Here you may want to change the thread priority arv_make_thread_realtime() or
23-
* arv_make_thread_high_priority() */
24-
break;
25-
case ARV_STREAM_CALLBACK_TYPE_START_BUFFER:
26-
/* The first packet of a new frame was received */
27-
break;
28-
case ARV_STREAM_CALLBACK_TYPE_BUFFER_DONE:
29-
/* The buffer is received, successfully or not.
30-
*
31-
* You could here signal the new buffer to another thread than the main one, and pull/push the
32-
* buffer from there. */
33-
break;
34-
case ARV_STREAM_CALLBACK_TYPE_EXIT:
35-
/* Stream thread ended */
36-
break;
37-
}
38-
}
39-
4012
/*
4113
* Connect to the first available camera, then acquire 10 buffers.
4214
*/
@@ -56,7 +28,7 @@ main (int argc, char **argv)
5628
printf ("Found camera '%s'\n", arv_camera_get_model_name (camera, NULL));
5729

5830
/* Create the stream object without callback */
59-
stream = arv_camera_create_stream (camera, stream_callback, NULL, &error);
31+
stream = arv_camera_create_stream (camera, NULL, NULL, &error);
6032
if (ARV_IS_STREAM (stream)) {
6133
int i;
6234
size_t payload;
@@ -65,7 +37,7 @@ main (int argc, char **argv)
6537
payload = arv_camera_get_payload (camera, &error);
6638
if (error == NULL) {
6739
/* Insert some buffers in the stream buffer pool */
68-
for (i = 0; i < 5; i++)
40+
for (i = 0; i < 2; i++)
6941
arv_stream_push_buffer (stream, arv_buffer_new (payload, NULL));
7042
}
7143

meson.build

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ aravis_dep = dependency('aravis-0.8')
44

55
examples = [
66
'01-single-acquisition',
7-
'02-multiple-acquisition',
7+
'02-multiple-acquisition-main-thread',
8+
'02-multiple-acquisition-callback',
89
'02-multiple-acquisition-signal',
910
'03-camera-api',
1011
'04-camera-features',

0 commit comments

Comments
 (0)