File npv/config.h changed (mode: 100644) (index 090af26..fea4c64) |
... |
... |
struct npv_x11_bind_t npv_x11_binds[] = { |
85 |
85 |
* a time window based on the following value. |
* a time window based on the following value. |
86 |
86 |
*/ |
*/ |
87 |
87 |
#define DISCONT_BACKWARD_RESYNC_MS 500 |
#define DISCONT_BACKWARD_RESYNC_MS 500 |
|
88 |
|
/* |
|
89 |
|
* the rate limiter while resyncing, since it can flood memory. We target 16 ms |
|
90 |
|
* or 60 fps |
|
91 |
|
*/ |
|
92 |
|
#define RESYNC_RATE_LIMITER_MS 16 |
88 |
93 |
#endif |
#endif |
File npv/pipeline/local/code.frag.c changed (mode: 100644) (index aac6b3d..4ab9aec) |
... |
... |
STATIC void *audio_thd_entry(void *arg) |
141 |
141 |
audio(); |
audio(); |
142 |
142 |
/* unreachable */ |
/* unreachable */ |
143 |
143 |
} |
} |
|
144 |
|
/* will return true to block, false to let it pass */ |
|
145 |
|
STATIC bool rate_limiter_do_block(void) |
|
146 |
|
{ |
|
147 |
|
int r; |
|
148 |
|
struct timespec current_tp; |
|
149 |
|
s64 current; |
|
150 |
|
s64 previous; |
|
151 |
|
|
|
152 |
|
memset(¤t_tp, 0, sizeof(current_tp)); |
|
153 |
|
r = clock_gettime(CLOCK_MONOTONIC, ¤t_tp); |
|
154 |
|
if (r == -1) |
|
155 |
|
return false; /* error, let it pass */ |
|
156 |
|
previous = (s64)rate_limiter_previous_tp.tv_sec * 1000 + |
|
157 |
|
(s64)rate_limiter_previous_tp.tv_nsec / 1000000; |
|
158 |
|
current = (s64)current_tp.tv_sec * 1000 |
|
159 |
|
+ (s64)current_tp.tv_nsec / 1000000; |
|
160 |
|
#ifdef NPV_DEBUG |
|
161 |
|
if (npv_debug_p) |
|
162 |
|
npv_perr("DEBUG:%s:delta=%ld\n", __func__, current - previous); |
|
163 |
|
#endif |
|
164 |
|
if ((current - previous) <= RESYNC_RATE_LIMITER_MS) |
|
165 |
|
return true; |
|
166 |
|
memcpy(&rate_limiter_previous_tp, ¤t_tp, sizeof(current_tp)); |
|
167 |
|
return false; |
|
168 |
|
} |
144 |
169 |
/* |
/* |
145 |
170 |
* predecoded video frs are expensive from the perspectives of the cpu and the |
* predecoded video frs are expensive from the perspectives of the cpu and the |
146 |
171 |
* mem hierarchy. |
* mem hierarchy. |
|
... |
... |
STATIC bool have_enough_predecoded_video_frs(void) |
158 |
183 |
* We are looking for a "resyncing" fr, and to secure we |
* We are looking for a "resyncing" fr, and to secure we |
159 |
184 |
* receive one, we must decode more frs or the dec frs a |
* receive one, we must decode more frs or the dec frs a |
160 |
185 |
* may endup full and dead locked. |
* may endup full and dead locked. |
|
186 |
|
* In pratice, this can burst mem with frs, let's rate |
|
187 |
|
* limit it 16 ms (~60fps). |
161 |
188 |
*/ |
*/ |
162 |
|
r = false; |
|
|
189 |
|
r = rate_limiter_do_block(); |
163 |
190 |
else if (npv_video_dec_frs_p.n < DEC_FRS_ARRAY_N_MAX) { |
else if (npv_video_dec_frs_p.n < DEC_FRS_ARRAY_N_MAX) { |
164 |
191 |
r = false; |
r = false; |
165 |
192 |
} else /* >= DEC_FRS_ARRAY_N_MAX && ! RESYNCING */ |
} else /* >= DEC_FRS_ARRAY_N_MAX && ! RESYNCING */ |
File npv/pipeline/namespace/main.c changed (mode: 100644) (index df1bddf..d303c84) |
12 |
12 |
#define have_enough_predecoded_audio_frs npv_pipeline_have_enough_predecoded_audio_frs |
#define have_enough_predecoded_audio_frs npv_pipeline_have_enough_predecoded_audio_frs |
13 |
13 |
#define have_enough_predecoded_video_frs npv_pipeline_have_enough_predecoded_video_frs |
#define have_enough_predecoded_video_frs npv_pipeline_have_enough_predecoded_video_frs |
14 |
14 |
#define pout npv_pipeline_pout |
#define pout npv_pipeline_pout |
|
15 |
|
#define rate_limiter_do_block npv_pipeline_rate_limiter_do_block |
|
16 |
|
#define rate_limiter_previous_tp npv_pipeline_rate_limiter_previous_tp |
15 |
17 |
#define read npv_pipeline_read |
#define read npv_pipeline_read |
16 |
18 |
#define read_thd_entry npv_pipeline_read_thd_entry |
#define read_thd_entry npv_pipeline_read_thd_entry |
17 |
19 |
#define timer_ack npv_pipeline_timer_ack |
#define timer_ack npv_pipeline_timer_ack |
|
28 |
30 |
#undef have_enough_predecoded_audio_frs |
#undef have_enough_predecoded_audio_frs |
29 |
31 |
#undef have_enough_predecoded_video_frs |
#undef have_enough_predecoded_video_frs |
30 |
32 |
#undef pout |
#undef pout |
|
33 |
|
#undef rate_limiter_do_block |
|
34 |
|
#undef rate_limiter_previous_tp |
31 |
35 |
#undef read |
#undef read |
32 |
36 |
#undef read_thd_entry |
#undef read_thd_entry |
33 |
37 |
#undef timer_ack |
#undef timer_ack |
File npv/pipeline/public/code.frag.c changed (mode: 100644) (index f522590..bc341e7) |
... |
... |
STATIC void init_once(void) |
38 |
38 |
r = pthread_mutex_init(&limits_p.mutex, 0); |
r = pthread_mutex_init(&limits_p.mutex, 0); |
39 |
39 |
if (r != 0) |
if (r != 0) |
40 |
40 |
fatal("unable to initialize the mutex to guard the accounting of limits\n"); |
fatal("unable to initialize the mutex to guard the accounting of limits\n"); |
|
41 |
|
memset(&rate_limiter_previous_tp, 0, sizeof(rate_limiter_previous_tp)); |
41 |
42 |
} |
} |
42 |
43 |
STATIC void limits_lock(void) |
STATIC void limits_lock(void) |
43 |
44 |
{ |
{ |
File npv/video/local/code.frag.c changed (mode: 100644) (index 20a1a18..292835d) |
... |
... |
STATIC void discont_backward(s64 now) |
748 |
748 |
if (dec_frs_p.discont_backward.prev_now != AV_NOPTS_VALUE |
if (dec_frs_p.discont_backward.prev_now != AV_NOPTS_VALUE |
749 |
749 |
&& now < dec_frs_p.discont_backward.prev_now) |
&& now < dec_frs_p.discont_backward.prev_now) |
750 |
750 |
dec_frs_p.discont_backward.resyncing = true; |
dec_frs_p.discont_backward.resyncing = true; |
751 |
|
if (dec_frs_p.discont_backward.resyncing) |
|
|
751 |
|
if (!dec_frs_p.discont_backward.resyncing) |
752 |
752 |
goto exit; |
goto exit; |
753 |
753 |
#ifdef NPV_DEBUG |
#ifdef NPV_DEBUG |
754 |
754 |
if (npv_debug_p) |
if (npv_debug_p) |