Skip to content

Commit 5beca99

Browse files
Mr-DaveDevMr-Dave
authored andcommitted
Cross thread and timing issues with streams
1 parent a4fb0d0 commit 5beca99

3 files changed

Lines changed: 49 additions & 25 deletions

File tree

webu.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ static void webu_context_init(struct context **cntlst, struct context *cnt, stru
8585
webui->lang_full = mymalloc(6); /* lang code, e.g US_en */
8686
webui->resp_size = WEBUI_LEN_RESP * 10; /* The size of the resp_page buffer. May get adjusted */
8787
webui->resp_used = 0; /* How many bytes used so far in resp_page*/
88+
webui->stream_pos = 0; /* Stream position of image being sent */
8889
webui->resp_page = mymalloc(webui->resp_size); /* The response being constructed */
8990
webui->cntlst = cntlst; /* The list of context's for all cameras */
9091
webui->cnt = cnt; /* The context pointer for a single camera */

webu.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ struct webui_ctx {
5959
char *resp_page; /* The response that will be sent */
6060
size_t resp_size; /* The allocated size of the response */
6161
size_t resp_used; /* The amount of the response page used */
62+
uint64_t stream_pos; /* Stream position of sent image */
63+
struct timeval time_last; /* Keep track of processing time for stream thread*/
6264
int mhd_first; /* Boolean for whether it is the first connection*/
6365

6466
struct MHD_Connection *connection; /* The MHD connection value from the client */

webu_stream.c

Lines changed: 46 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,39 @@ static void webu_stream_mjpeg_checkbuffers(struct webui_ctx *webui) {
3030

3131
}
3232

33+
static void webu_stream_mjpeg_delay(struct webui_ctx *webui) {
34+
/* Sleep required time to get to the user requested frame
35+
* rate for the stream
36+
*/
37+
38+
long stream_rate;
39+
struct timeval time_curr;
40+
long stream_delay;
41+
42+
gettimeofday(&time_curr, NULL);
43+
44+
/* The stream rate MUST be less than 1000000000 otherwise undefined behaviour
45+
* will occur with the SLEEP function.
46+
*/
47+
stream_delay = ((time_curr.tv_usec - webui->time_last.tv_usec)*1000000) -
48+
((time_curr.tv_sec - webui->time_last.tv_sec)*1000000000);
49+
if (stream_delay < 0) stream_delay = 0;
50+
if (stream_delay > 1000000000 ) stream_delay = 1000000000;
51+
52+
if (webui->cnt->conf.stream_maxrate > 1){
53+
stream_rate = ( (1000000000 / webui->cnt->conf.stream_maxrate) - stream_delay);
54+
if ((stream_rate > 0) && (stream_rate < 1000000000)){
55+
SLEEP(0,stream_rate);
56+
} else if (stream_rate == 1000000000) {
57+
SLEEP(1,0);
58+
}
59+
} else {
60+
SLEEP(1,0);
61+
}
62+
gettimeofday(&webui->time_last, NULL);
63+
64+
}
65+
3366
static void webu_stream_mjpeg_getimg(struct webui_ctx *webui) {
3467
long jpeg_size;
3568
char resp_head[80];
@@ -84,52 +117,38 @@ static ssize_t webu_stream_mjpeg_response (void *cls, uint64_t pos, char *buf, s
84117
* browser. We sleep the requested amount of time between fetching images to match
85118
* the user configuration parameters. This function may be called multiple times for
86119
* a single image so we can write what we can to the buffer and pick up remaining bytes
87-
* to send based upon the static variable of stream position
120+
* to send based upon the stream position
88121
*/
89122
struct webui_ctx *webui = cls;
90-
static uint64_t stream_pos;
91123
size_t sent_bytes;
92-
long stream_rate;
93-
static int indx_start;
94124

95125
(void)pos; /*Remove compiler warning */
96126

97127
if (webui->cnt->webcontrol_finish) return -1;
98128

99-
/* We use indx_start to send a few extra images when the stream starts*/
100-
if ((stream_pos == 0) || (webui->resp_used == 0)){
101-
if (webui->resp_used == 0){
102-
indx_start = 1;
103-
} else if (indx_start < 4) {
104-
indx_start++;
105-
} else {
106-
if (webui->cnt->conf.stream_maxrate > 1){
107-
stream_rate = (1000000000 / webui->cnt->conf.stream_maxrate);
108-
SLEEP(0,stream_rate);
109-
} else {
110-
SLEEP(1,0);
111-
}
112-
}
129+
if ((webui->stream_pos == 0) || (webui->resp_used == 0)){
113130

114-
stream_pos = 0;
131+
webu_stream_mjpeg_delay(webui);
132+
133+
webui->stream_pos = 0;
115134
webui->resp_used = 0;
116135

117136
webu_stream_mjpeg_getimg(webui);
118137

119138
if (webui->resp_used == 0) return 0;
120139
}
121140

122-
if ((webui->resp_used - stream_pos) > max) {
141+
if ((webui->resp_used - webui->stream_pos) > max) {
123142
sent_bytes = max;
124143
} else {
125-
sent_bytes = webui->resp_used - stream_pos;
144+
sent_bytes = webui->resp_used - webui->stream_pos;
126145
}
127146

128-
memcpy(buf, webui->resp_page + stream_pos, sent_bytes);
147+
memcpy(buf, webui->resp_page + webui->stream_pos, sent_bytes);
129148

130-
stream_pos = stream_pos + sent_bytes;
131-
if (stream_pos >= webui->resp_used){
132-
stream_pos = 0;
149+
webui->stream_pos = webui->stream_pos + sent_bytes;
150+
if (webui->stream_pos >= webui->resp_used){
151+
webui->stream_pos = 0;
133152
}
134153

135154
return sent_bytes;
@@ -249,6 +268,8 @@ int webu_stream_mjpeg(struct webui_ctx *webui) {
249268

250269
webu_stream_mjpeg_checkbuffers(webui);
251270

271+
gettimeofday(&webui->time_last, NULL);
272+
252273
response = MHD_create_response_from_callback (MHD_SIZE_UNKNOWN, 1024
253274
,&webu_stream_mjpeg_response, webui, NULL);
254275
if (!response){

0 commit comments

Comments
 (0)