35
35
#include "common/msg.h"
36
36
#include "misc/thread_tools.h"
37
37
#include "stream.h"
38
+ #include "options/m_config.h"
38
39
#include "options/m_option.h"
39
40
#include "options/path.h"
40
41
@@ -85,6 +86,26 @@ typedef enum _FSINFOCLASS {
85
86
#endif
86
87
#endif
87
88
89
+
90
+ struct appending_opts {
91
+ double retry_timeout ;
92
+ int max_retries ;
93
+ };
94
+
95
+ #define OPT_BASE_STRUCT struct appending_opts
96
+ const struct m_sub_options stream_appending_conf = {
97
+ .opts = (const struct m_option []) {
98
+ {"retry-timeout" , OPT_DOUBLE (retry_timeout ), M_RANGE (0.1 , 1.0 )},
99
+ {"max-retries" , OPT_INT (max_retries ), M_RANGE (2 , 1000 )},
100
+ {0 },
101
+ },
102
+ .size = sizeof (struct appending_opts ),
103
+ .defaults = & (const struct appending_opts ){
104
+ .retry_timeout = 0.2 ,
105
+ .max_retries = 10 ,
106
+ },
107
+ };
108
+
88
109
struct priv {
89
110
int fd ;
90
111
bool close ;
@@ -93,12 +114,9 @@ struct priv {
93
114
bool appending ;
94
115
int64_t orig_size ;
95
116
struct mp_cancel * cancel ;
117
+ struct appending_opts * opts ;
96
118
};
97
119
98
- // Total timeout = RETRY_TIMEOUT * MAX_RETRIES
99
- #define RETRY_TIMEOUT 0.2
100
- #define MAX_RETRIES 10
101
-
102
120
static int64_t get_size (stream_t * s )
103
121
{
104
122
struct priv * p = s -> priv ;
@@ -129,13 +147,20 @@ static int fill_buffer(stream_t *s, void *buffer, int max_len)
129
147
}
130
148
#endif
131
149
132
- for (int retries = 0 ; retries < MAX_RETRIES ; retries ++ ) {
150
+ int max_retries = p -> opts -> max_retries ;
151
+ double retry_timeout = p -> opts -> retry_timeout ;
152
+
153
+ for (int retries = 0 ; retries < max_retries ; retries ++ ) {
154
+ int64_t size = get_size (s );
155
+
156
+ MP_DBG (s , "appending retry %d/%d @ pos %" PRId64 "/%" PRId64 " (timeout=%lf)\n" ,
157
+ retries , max_retries , s -> pos , size , retry_timeout );
158
+
133
159
int r = read (p -> fd , buffer , max_len );
134
160
if (r > 0 )
135
161
return r ;
136
162
137
163
// Try to detect and handle files being appended during playback.
138
- int64_t size = get_size (s );
139
164
if (p -> regular_file && size > p -> orig_size && !p -> appending ) {
140
165
MP_WARN (s , "File is apparently being appended to, will keep "
141
166
"retrying with timeouts.\n" );
@@ -145,7 +170,7 @@ static int fill_buffer(stream_t *s, void *buffer, int max_len)
145
170
if (!p -> appending || p -> use_poll )
146
171
break ;
147
172
148
- if (mp_cancel_wait (p -> cancel , RETRY_TIMEOUT ))
173
+ if (mp_cancel_wait (p -> cancel , retry_timeout ))
149
174
break ;
150
175
}
151
176
@@ -279,6 +304,8 @@ static int open_f(stream_t *stream, const struct stream_open_args *args)
279
304
* p = (struct priv ) {
280
305
.fd = -1 ,
281
306
};
307
+ p -> opts = mp_get_config_group (stream , stream -> global ,
308
+ & stream_appending_conf );
282
309
stream -> priv = p ;
283
310
stream -> is_local_fs = true;
284
311
0 commit comments