File npv/TODO changed (mode: 100644) (index 67827cc..fa11084) |
... |
... |
not ordered: |
3 |
3 |
x11 xfixes4 protocol should have the required requests. |
x11 xfixes4 protocol should have the required requests. |
4 |
4 |
- better/smoother/less drop/(correct?) video frame display strategy ? |
- better/smoother/less drop/(correct?) video frame display strategy ? |
5 |
5 |
- xcb(resize)/vulkan swapchain loss or "not optimal" ? (state re-factoring) |
- xcb(resize)/vulkan swapchain loss or "not optimal" ? (state re-factoring) |
6 |
|
- x11 map/unmap handling to: |
|
7 |
|
+ restore the paused image (aka keep the image currently displayed in cpu ram) |
|
8 |
|
+ switch on/off video decoding? |
|
|
6 |
|
- x11 map/unmap handling: switch on/off video? |
9 |
7 |
- the exit condition is audio drained *AND* format eof was raised. |
- the exit condition is audio drained *AND* format eof was raised. |
10 |
|
dynamic formats: if eof was not raised and audio is drained, reprobe |
|
|
8 |
|
dynamic formats: if format eof was not raised and audio is drained, reprobe |
11 |
9 |
for best streams? Wait for user streams selection? |
for best streams? Wait for user streams selection? |
12 |
10 |
- "power management event"? it implies: |
- "power management event"? it implies: |
13 |
11 |
+ if alsa notify of a "power management" event we should |
+ if alsa notify of a "power management" event we should |
|
... |
... |
not ordered: |
21 |
19 |
some yuvX pixel formats to srgb format conversions. do NOT use the vulkan |
some yuvX pixel formats to srgb format conversions. do NOT use the vulkan |
22 |
20 |
yuvX samplers as they are mostly dirty hack tricks built into spirv |
yuvX samplers as they are mostly dirty hack tricks built into spirv |
23 |
21 |
translaters. |
translaters. |
24 |
|
- vulkan thingy for better quality down/up scaling? |
|
|
22 |
|
- vulkan thingy for better quality down/up scaling? ffmpeg can do an amazing |
|
23 |
|
job, but in a cpu expensive way. |
File npv/clk/public/code.frag.c changed (mode: 100644) (index 1795d99..90df049) |
... |
... |
static void clk_init_once(void) |
12 |
12 |
r = snd_pcm_hw_params_malloc(&clk_pcm_hw_params_l); |
r = snd_pcm_hw_params_malloc(&clk_pcm_hw_params_l); |
13 |
13 |
if (r < 0) |
if (r < 0) |
14 |
14 |
FATALCLK("alsa:unable to allocate hardware parameters context\n"); |
FATALCLK("alsa:unable to allocate hardware parameters context\n"); |
|
15 |
|
clk_l.paused = false; |
15 |
16 |
} |
} |
16 |
17 |
#define NO_REF_TIME_POINT 1 |
#define NO_REF_TIME_POINT 1 |
17 |
18 |
static u8 clk_get_audio_st_ts(s64 *ts) |
static u8 clk_get_audio_st_ts(s64 *ts) |
|
... |
... |
static u8 clk_get_audio_st_ts(s64 *ts) |
36 |
37 |
|
|
37 |
38 |
if (!clk_l.ref_valid) |
if (!clk_l.ref_valid) |
38 |
39 |
return NO_REF_TIME_POINT; |
return NO_REF_TIME_POINT; |
39 |
|
memset(clk_l.now.status, 0, snd_pcm_status_sizeof()); |
|
40 |
|
ac.report_delay = 0; |
|
41 |
|
ac.type_requested = (unsigned int)audio_selected_ts_type_p; |
|
42 |
|
snd_pcm_status_set_audio_htstamp_config(clk_l.now.status, &ac); |
|
43 |
|
r = snd_pcm_status(audio_pcm_p, clk_l.now.status); |
|
44 |
|
if (r < 0) |
|
45 |
|
FATALCLK("alsa:unable to sample timing information for 'now' time point\n"); |
|
|
40 |
|
if (!clk_l.paused) { |
|
41 |
|
memset(clk_l.now.status, 0, snd_pcm_status_sizeof()); |
|
42 |
|
ac.report_delay = 0; |
|
43 |
|
ac.type_requested = (unsigned int)audio_selected_ts_type_p; |
|
44 |
|
snd_pcm_status_set_audio_htstamp_config(clk_l.now.status, &ac); |
|
45 |
|
r = snd_pcm_status(audio_pcm_p, clk_l.now.status); |
|
46 |
|
if (r < 0) |
|
47 |
|
FATALCLK("alsa:unable to sample timing information for 'now' time point\n"); |
|
48 |
|
} |
46 |
49 |
snd_pcm_status_get_audio_htstamp(clk_l.now.status, &hts); |
snd_pcm_status_get_audio_htstamp(clk_l.now.status, &hts); |
47 |
50 |
now_ns = (f64)hts.tv_sec * 1e9 + (f64)hts.tv_nsec; |
now_ns = (f64)hts.tv_sec * 1e9 + (f64)hts.tv_nsec; |
48 |
51 |
|
|
|
... |
... |
static void clk_invalidate(void) |
123 |
126 |
{ |
{ |
124 |
127 |
clk_l.ref_valid = false; |
clk_l.ref_valid = false; |
125 |
128 |
} |
} |
|
129 |
|
static void clk_pause(void) |
|
130 |
|
{ |
|
131 |
|
int r; |
|
132 |
|
snd_pcm_audio_tstamp_config_t ac; |
|
133 |
|
|
|
134 |
|
clk_l.paused = true; |
|
135 |
|
memset(clk_l.now.status, 0, snd_pcm_status_sizeof()); |
|
136 |
|
ac.report_delay = 0; |
|
137 |
|
ac.type_requested = (unsigned int)audio_selected_ts_type_p; |
|
138 |
|
snd_pcm_status_set_audio_htstamp_config(clk_l.now.status, &ac); |
|
139 |
|
r = snd_pcm_status(audio_pcm_p, clk_l.now.status); |
|
140 |
|
if (r < 0) |
|
141 |
|
FATALCLK("alsa:unable to sample timing information for 'paused' time point\n"); |
|
142 |
|
} |
|
143 |
|
static void clk_unpause(void) |
|
144 |
|
{ |
|
145 |
|
clk_l.paused = false; |
|
146 |
|
clk_invalidate(); |
|
147 |
|
} |
File npv/local/code.frag.c changed (mode: 100644) (index d51c520..ef428d8) |
... |
... |
static void seek_x(s64 delta) |
678 |
678 |
WARNING("seek:audio is draining, seeking disable\n"); |
WARNING("seek:audio is draining, seeking disable\n"); |
679 |
679 |
return; |
return; |
680 |
680 |
} |
} |
|
681 |
|
if (paused_p) /* we don't seek in pause */ |
|
682 |
|
return; |
681 |
683 |
|
|
682 |
684 |
thdsws_wait_for_idle(video_scaler_p.ctx); |
thdsws_wait_for_idle(video_scaler_p.ctx); |
683 |
685 |
|
|
|
... |
... |
static void cmd_pause(void) |
796 |
798 |
fmt_ctx_lock(); |
fmt_ctx_lock(); |
797 |
799 |
avformat_read_play(fmt_ctx_p); |
avformat_read_play(fmt_ctx_p); |
798 |
800 |
fmt_ctx_unlock(); |
fmt_ctx_unlock(); |
|
801 |
|
clk_unpause(); |
|
802 |
|
video_timer_140fps_start(); |
799 |
803 |
} else { |
} else { |
800 |
804 |
int r; |
int r; |
801 |
805 |
|
|
|
... |
... |
static void cmd_pause(void) |
804 |
808 |
fmt_ctx_lock(); |
fmt_ctx_lock(); |
805 |
809 |
avformat_read_pause(fmt_ctx_p); |
avformat_read_pause(fmt_ctx_p); |
806 |
810 |
fmt_ctx_unlock(); |
fmt_ctx_unlock(); |
807 |
|
/* the clk source won't stop for us */ |
|
808 |
|
clk_invalidate(); |
|
|
811 |
|
clk_pause(); |
|
812 |
|
video_timer_10fps_start(); |
809 |
813 |
} |
} |
810 |
814 |
} |
} |
811 |
815 |
static void cmd_vol_up(void) |
static void cmd_vol_up(void) |
|
... |
... |
int main(int argc, u8 **args) |
863 |
867 |
POUT("predecoding audio and video..."); |
POUT("predecoding audio and video..."); |
864 |
868 |
predecode_wait(); |
predecode_wait(); |
865 |
869 |
POUT("done\n"); |
POUT("done\n"); |
866 |
|
video_timer_start(); |
|
|
870 |
|
video_timer_140fps_start(); |
867 |
871 |
|
|
868 |
872 |
loop evts_loop(); |
loop evts_loop(); |
869 |
873 |
/* unreachable */ |
/* unreachable */ |
File npv/video/local/code.frag.c changed (mode: 100644) (index 5a0a591..251c94e) |
... |
... |
static void dec_a_grow(void) |
241 |
241 |
|
|
242 |
242 |
++dec_frs_p.n_max; |
++dec_frs_p.n_max; |
243 |
243 |
} |
} |
|
244 |
|
#define NO_FR 0 |
244 |
245 |
/* extract a fr ref, shift the a, push it back at the e, and unref its bufs */ |
/* extract a fr ref, shift the a, push it back at the e, and unref its bufs */ |
245 |
246 |
static void fr_drop(u16 fr) |
static void fr_drop(u16 fr) |
246 |
247 |
{ |
{ |
|
... |
... |
static void fr_drop(u16 fr) |
267 |
268 |
} |
} |
268 |
269 |
dec_frs_p.n--; |
dec_frs_p.n--; |
269 |
270 |
} |
} |
|
271 |
|
#undef NO_FR |
|
272 |
|
#define NO_FR 0 |
270 |
273 |
static void frs_drop(s64 now) |
static void frs_drop(s64 now) |
271 |
274 |
{ |
{ |
272 |
275 |
s64 low; |
s64 low; |
|
... |
... |
static void frs_drop(s64 now) |
287 |
290 |
pts = dec_frs_p.a[fr]->pts; |
pts = dec_frs_p.a[fr]->pts; |
288 |
291 |
fr_priv = dec_frs_p.priv_a[fr]; |
fr_priv = dec_frs_p.priv_a[fr]; |
289 |
292 |
|
|
290 |
|
if ((dec_frs_p.a[fr] != dec_frs_p.being_scaled.fr) |
|
291 |
|
&& (pts < low)) |
|
|
293 |
|
/* keep the fr the scaler is related to */ |
|
294 |
|
if ((dec_frs_p.a[fr] != scaler_p.img.fr) && (pts < low)) { |
|
295 |
|
if (dec_frs_p.a[fr] == last_fr_sent_to_pe) |
|
296 |
|
last_fr_sent_to_pe = NO_FR; |
292 |
297 |
fr_drop(fr); /* do not advance */ |
fr_drop(fr); /* do not advance */ |
293 |
|
else |
|
|
298 |
|
} else |
294 |
299 |
++fr; |
++fr; |
295 |
300 |
} |
} |
296 |
301 |
} |
} |
|
302 |
|
#undef NO_FR |
297 |
303 |
#define NO_FR 0 |
#define NO_FR 0 |
298 |
304 |
static void select_fr(s64 now, avutil_video_fr_ref_t **selected_fr, |
static void select_fr(s64 now, avutil_video_fr_ref_t **selected_fr, |
299 |
305 |
struct dec_fr_priv_t **selected_fr_priv) |
struct dec_fr_priv_t **selected_fr_priv) |
|
... |
... |
static void select_fr(s64 now, avutil_video_fr_ref_t **selected_fr, |
319 |
325 |
} |
} |
320 |
326 |
++fr_idx; |
++fr_idx; |
321 |
327 |
} |
} |
322 |
|
/* smooth occasional drops due to spikes in latency over 1-2 frames */ |
|
323 |
|
if (selected_fr_idx >= 1) { |
|
324 |
|
struct dec_fr_priv_t *prev_fr_priv; |
|
325 |
|
|
|
326 |
|
if (selected_fr_idx >= 2) { |
|
327 |
|
prev_fr_priv = dec_frs_p.priv_a[selected_fr_idx - 2]; |
|
328 |
|
if (!prev_fr_priv->was_qed_to_pe) { |
|
329 |
|
/* hijack the time slot */ |
|
330 |
|
*selected_fr = dec_frs_p.a[selected_fr_idx - 2]; |
|
331 |
|
*selected_fr_priv = prev_fr_priv; |
|
332 |
|
return; |
|
333 |
|
} |
|
334 |
|
} |
|
335 |
|
prev_fr_priv = dec_frs_p.priv_a[selected_fr_idx - 1]; |
|
336 |
|
if (!prev_fr_priv->was_qed_to_pe) { |
|
337 |
|
/* hijack the time slot */ |
|
338 |
|
*selected_fr = dec_frs_p.a[selected_fr_idx - 1]; |
|
339 |
|
*selected_fr_priv = prev_fr_priv; |
|
340 |
|
} |
|
341 |
|
} |
|
342 |
328 |
} |
} |
343 |
329 |
#undef NO_FR |
#undef NO_FR |
344 |
|
static void frs_clear_last_qed_to_pe(void) |
|
345 |
|
{ |
|
346 |
|
u16 fr; |
|
347 |
|
|
|
348 |
|
fr = 0; |
|
349 |
|
loop { |
|
350 |
|
struct dec_fr_priv_t *fr_priv; |
|
351 |
|
|
|
352 |
|
if (fr == dec_frs_p.n) |
|
353 |
|
break; |
|
354 |
|
fr_priv = dec_frs_p.priv_a[fr]; |
|
355 |
|
if (fr_priv->is_last_qed_to_pe) { |
|
356 |
|
fr_priv->is_last_qed_to_pe = false; |
|
357 |
|
break; |
|
358 |
|
} |
|
359 |
|
++fr; |
|
360 |
|
} |
|
361 |
|
} |
|
362 |
330 |
static void frs_reset(void) |
static void frs_reset(void) |
363 |
331 |
{ |
{ |
364 |
332 |
u16 fr; |
u16 fr; |
|
... |
... |
static void start_scaling(avutil_video_fr_ref_t *fr, |
526 |
494 |
scaler_p.ctx->scale.dst_slice = scaler_p.img.data; |
scaler_p.ctx->scale.dst_slice = scaler_p.img.data; |
527 |
495 |
scaler_p.ctx->scale.dst_stride = scaled_line_bytes_n; |
scaler_p.ctx->scale.dst_stride = scaled_line_bytes_n; |
528 |
496 |
thdsws_run(scaler_p.ctx); |
thdsws_run(scaler_p.ctx); |
|
497 |
|
scaler_p.img.fr = fr; |
529 |
498 |
} |
} |
530 |
499 |
static void timer_ack(void) |
static void timer_ack(void) |
531 |
500 |
{ |
{ |
File npv/video/main.c changed (mode: 100644) (index 0db8fe4..eedf25e) |
45 |
45 |
#define POUTVVK(fmt, ...) POUTVK("video:" fmt, ##__VA_ARGS__) |
#define POUTVVK(fmt, ...) POUTVK("video:" fmt, ##__VA_ARGS__) |
46 |
46 |
#define WARNINGVVK(fmt, ...) WARNINGVK("video:" fmt, ##__VA_ARGS__) |
#define WARNINGVVK(fmt, ...) WARNINGVK("video:" fmt, ##__VA_ARGS__) |
47 |
47 |
#define IF_FATALVVK(fmt, ...) IF_FATALVK("video:" fmt, ##__VA_ARGS__) |
#define IF_FATALVVK(fmt, ...) IF_FATALVK("video:" fmt, ##__VA_ARGS__) |
48 |
|
|
|
49 |
|
#define TIMER_INTERVAL_NSECS_N 4000000 /* 4ms should be enough? */ |
|
50 |
48 |
/*----------------------------------------------------------------------------*/ |
/*----------------------------------------------------------------------------*/ |
51 |
49 |
#include "npv/video/local/state.frag.c" |
#include "npv/video/local/state.frag.c" |
52 |
50 |
/*----------------------------------------------------------------------------*/ |
/*----------------------------------------------------------------------------*/ |
|
63 |
61 |
#undef POUTVVK |
#undef POUTVVK |
64 |
62 |
#undef WARNINGVVK |
#undef WARNINGVVK |
65 |
63 |
#undef IF_FATALVVK |
#undef IF_FATALVVK |
66 |
|
#undef TIMER_INTERVAL_NSECS_N |
|
67 |
64 |
/*----------------------------------------------------------------------------*/ |
/*----------------------------------------------------------------------------*/ |
68 |
65 |
#define CLEANUP |
#define CLEANUP |
69 |
66 |
#include "npv/namespace/ffmpeg.h" |
#include "npv/namespace/ffmpeg.h" |
File npv/video/public.h changed (mode: 100644) (index 820867c..3ef832c) |
11 |
11 |
#include "npv/c_fixing.h" |
#include "npv/c_fixing.h" |
12 |
12 |
#include "npv/nyanvk/consts.h" |
#include "npv/nyanvk/consts.h" |
13 |
13 |
#include "npv/nyanvk/types.h" |
#include "npv/nyanvk/types.h" |
14 |
|
/*---------------------------------------------------------------------------*/ |
|
|
14 |
|
/*----------------------------------------------------------------------------*/ |
15 |
15 |
#include "npv/namespace/ffmpeg.h" |
#include "npv/namespace/ffmpeg.h" |
16 |
16 |
#include "npv/video/namespace/ffmpeg.h" |
#include "npv/video/namespace/ffmpeg.h" |
17 |
17 |
#include "npv/video/namespace/public.h" |
#include "npv/video/namespace/public.h" |
18 |
|
/*---------------------------------------------------------------------------*/ |
|
|
18 |
|
/*----------------------------------------------------------------------------*/ |
19 |
19 |
#include "npv/video/public/state.frag.h" |
#include "npv/video/public/state.frag.h" |
20 |
|
/*---------------------------------------------------------------------------*/ |
|
|
20 |
|
/*----------------------------------------------------------------------------*/ |
21 |
21 |
static void dec_ctx_cfg(avcodec_params_t *params); |
static void dec_ctx_cfg(avcodec_params_t *params); |
22 |
22 |
static void dec_flush(void); |
static void dec_flush(void); |
23 |
23 |
static u8 dec_fr_try_receive(void); |
static u8 dec_fr_try_receive(void); |
24 |
24 |
static void dec_frs_receive_avail(void); |
static void dec_frs_receive_avail(void); |
25 |
25 |
static void init_once(void); |
static void init_once(void); |
26 |
26 |
static void timer_evt(void); |
static void timer_evt(void); |
27 |
|
static void timer_start(void); |
|
|
27 |
|
static void timer_140fps_start(void); |
|
28 |
|
static void timer_10fps_start(void); |
28 |
29 |
static void dec_ctx_lock(void); |
static void dec_ctx_lock(void); |
29 |
30 |
static void dec_ctx_unlock(void); |
static void dec_ctx_unlock(void); |
30 |
31 |
static void dec_frs_lock(void); |
static void dec_frs_lock(void); |
31 |
32 |
static void dec_frs_unlock(void); |
static void dec_frs_unlock(void); |
32 |
33 |
static void pkts_send(void); |
static void pkts_send(void); |
33 |
|
/*---------------------------------------------------------------------------*/ |
|
|
34 |
|
/*----------------------------------------------------------------------------*/ |
34 |
35 |
#define CLEANUP |
#define CLEANUP |
35 |
36 |
#include "npv/namespace/ffmpeg.h" |
#include "npv/namespace/ffmpeg.h" |
36 |
37 |
#include "npv/video/namespace/ffmpeg.h" |
#include "npv/video/namespace/ffmpeg.h" |
File npv/video/public/code.frag.c changed (mode: 100644) (index 386bb83..65b73e3) |
... |
... |
static void init_once_public(void) |
20 |
20 |
dec_frs_p.n = 0; |
dec_frs_p.n = 0; |
21 |
21 |
dec_frs_p.a = 0; |
dec_frs_p.a = 0; |
22 |
22 |
dec_frs_p.priv_a = 0; |
dec_frs_p.priv_a = 0; |
23 |
|
dec_frs_p.being_scaled.fr = NO_FR; |
|
24 |
|
dec_frs_p.being_scaled.fr_priv = 0; |
|
25 |
23 |
r = pthread_mutex_init(&dec_frs_p.mutex, 0); |
r = pthread_mutex_init(&dec_frs_p.mutex, 0); |
26 |
24 |
if (r != 0) |
if (r != 0) |
27 |
25 |
FATALV("unable to create the mutex for the array of frames\n"); |
FATALV("unable to create the mutex for the array of frames\n"); |
|
... |
... |
static void init_once_public(void) |
30 |
28 |
memset(&scaler_p.img.layout, 0, sizeof(scaler_p.img.layout)); |
memset(&scaler_p.img.layout, 0, sizeof(scaler_p.img.layout)); |
31 |
29 |
scaler_p.img.dev_mem = 0; |
scaler_p.img.dev_mem = 0; |
32 |
30 |
scaler_p.img.data = 0; |
scaler_p.img.data = 0; |
33 |
|
|
|
|
31 |
|
scaler_p.img.fr = NO_FR; |
|
32 |
|
|
|
33 |
|
last_fr_sent_to_pe = NO_FR; |
|
34 |
|
|
34 |
35 |
/* we are targetting AVUTIL_PIX_FMT_RGB32/sRGB */ |
/* we are targetting AVUTIL_PIX_FMT_RGB32/sRGB */ |
35 |
36 |
scaler_p.ctx = thdsws_init_once(); |
scaler_p.ctx = thdsws_init_once(); |
36 |
37 |
if (scaler_p.ctx == 0) |
if (scaler_p.ctx == 0) |
|
... |
... |
static void dec_ctx_cfg(avcodec_params_t *params) |
63 |
64 |
if (r < 0) |
if (r < 0) |
64 |
65 |
FATALVFF("unable to open the decoder context\n"); |
FATALVFF("unable to open the decoder context\n"); |
65 |
66 |
} |
} |
66 |
|
static void timer_start(void) |
|
|
67 |
|
static void timer_140fps_start(void) |
|
68 |
|
{ |
|
69 |
|
struct itimerspec t; |
|
70 |
|
int r; |
|
71 |
|
|
|
72 |
|
memset(&t, 0, sizeof(t)); |
|
73 |
|
/* initial and interval */ |
|
74 |
|
t.it_value.tv_nsec = 1; /* asap */ |
|
75 |
|
t.it_interval.tv_nsec = 7000000; /* ~7ms */ |
|
76 |
|
r = timerfd_settime(timer_fd_p, 0, &t, 0); |
|
77 |
|
if (r == -1) |
|
78 |
|
FATALV("unable to arm the timer\n"); |
|
79 |
|
} |
|
80 |
|
static void timer_10fps_start(void) |
67 |
81 |
{ |
{ |
68 |
82 |
struct itimerspec t; |
struct itimerspec t; |
69 |
83 |
int r; |
int r; |
|
... |
... |
static void timer_start(void) |
71 |
85 |
memset(&t, 0, sizeof(t)); |
memset(&t, 0, sizeof(t)); |
72 |
86 |
/* initial and interval */ |
/* initial and interval */ |
73 |
87 |
t.it_value.tv_nsec = 1; /* asap */ |
t.it_value.tv_nsec = 1; /* asap */ |
74 |
|
t.it_interval.tv_nsec = TIMER_INTERVAL_NSECS_N; |
|
|
88 |
|
t.it_interval.tv_nsec = 100000000; /* 100ms */ |
75 |
89 |
r = timerfd_settime(timer_fd_p, 0, &t, 0); |
r = timerfd_settime(timer_fd_p, 0, &t, 0); |
76 |
90 |
if (r == -1) |
if (r == -1) |
77 |
91 |
FATALV("unable to arm the timer\n"); |
FATALV("unable to arm the timer\n"); |
|
... |
... |
static void dec_flush(void) |
134 |
148 |
pkt_q_unref_all(pkt_q_p); |
pkt_q_unref_all(pkt_q_p); |
135 |
149 |
frs_reset(); |
frs_reset(); |
136 |
150 |
dec_frs_p.eof_receive = false; |
dec_frs_p.eof_receive = false; |
137 |
|
dec_frs_p.being_scaled.fr = NO_FR; |
|
138 |
|
dec_frs_p.being_scaled.fr_priv = 0; |
|
|
151 |
|
last_fr_sent_to_pe = NO_FR; |
139 |
152 |
avcodec_flush_bufs(dec_ctx_p); |
avcodec_flush_bufs(dec_ctx_p); |
140 |
153 |
} |
} |
141 |
154 |
#undef NO_FR |
#undef NO_FR |
|
... |
... |
static void dec_frs_unlock(void) |
176 |
189 |
#define TS_FROM_CLK_OK 0 |
#define TS_FROM_CLK_OK 0 |
177 |
190 |
#define READY 0 |
#define READY 0 |
178 |
191 |
#define NOT_READY 1 |
#define NOT_READY 1 |
179 |
|
/* |
|
180 |
|
* XXX: we do want to lock the frs q the least amount of time as possible. but |
|
181 |
|
* the main thd seems to have too much latency for the video output. may |
|
182 |
|
* need to move the video output to its own thd in the end. |
|
183 |
|
*/ |
|
|
192 |
|
/* XXX: we do want to lock the frs q the least amount of time as possible */ |
184 |
193 |
static void timer_evt(void) |
static void timer_evt(void) |
185 |
194 |
{ |
{ |
186 |
195 |
u8 r; |
u8 r; |
187 |
196 |
s64 now; |
s64 now; |
188 |
197 |
avutil_video_fr_ref_t *fr; |
avutil_video_fr_ref_t *fr; |
189 |
198 |
struct dec_fr_priv_t *fr_priv; |
struct dec_fr_priv_t *fr_priv; |
190 |
|
bool scaler_is_busy; |
|
191 |
199 |
bool scaler_dims_changed; |
bool scaler_dims_changed; |
192 |
200 |
u32 swpchn_img; |
u32 swpchn_img; |
193 |
201 |
|
|
194 |
202 |
timer_ack(); |
timer_ack(); |
195 |
|
if (npv_paused_p) |
|
196 |
|
return; |
|
197 |
203 |
r = clk_get_video_st_ts(&now); |
r = clk_get_video_st_ts(&now); |
198 |
204 |
if (r != TS_FROM_CLK_OK) |
if (r != TS_FROM_CLK_OK) |
199 |
205 |
return; |
return; |
|
... |
... |
static void timer_evt(void) |
209 |
215 |
/* unlock ------------------------------------------------------------*/ |
/* unlock ------------------------------------------------------------*/ |
210 |
216 |
if (fr == NO_FR) |
if (fr == NO_FR) |
211 |
217 |
return; |
return; |
212 |
|
if (fr_priv->is_last_qed_to_pe) |
|
|
218 |
|
/* in pause, we "redraw" the same img all the time */ |
|
219 |
|
if (!npv_paused_p && fr == last_fr_sent_to_pe) |
213 |
220 |
return; |
return; |
214 |
|
scaler_is_busy = thdsws_is_busy(scaler_p.ctx); |
|
215 |
|
if (!scaler_is_busy) { |
|
216 |
|
/* the fr which was scaled may not be the selected one */ |
|
217 |
|
if (dec_frs_p.being_scaled.fr != NO_FR) { |
|
218 |
|
dec_frs_p.being_scaled.fr_priv->is_scaled = true; |
|
219 |
|
dec_frs_p.being_scaled.fr = NO_FR; |
|
220 |
|
} |
|
221 |
|
} |
|
222 |
|
if (!fr_priv->is_scaled) { /* the selected fr */ |
|
223 |
|
if (scaler_is_busy) |
|
224 |
|
return; |
|
|
221 |
|
if (thdsws_is_busy(scaler_p.ctx)) |
|
222 |
|
return; |
|
223 |
|
if (scaler_p.img.fr != fr) { |
225 |
224 |
start_scaling(fr, fr_priv, &scaler_dims_changed); |
start_scaling(fr, fr_priv, &scaler_dims_changed); |
226 |
|
dec_frs_p.being_scaled.fr = fr; |
|
227 |
|
dec_frs_p.being_scaled.fr_priv = fr_priv; |
|
228 |
225 |
return; |
return; |
229 |
226 |
} |
} |
230 |
227 |
r = swpchn_next_img(&swpchn_img); |
r = swpchn_next_img(&swpchn_img); |
|
... |
... |
static void timer_evt(void) |
232 |
229 |
return; |
return; |
233 |
230 |
blit_setup(swpchn_img, scaler_dims_changed); |
blit_setup(swpchn_img, scaler_dims_changed); |
234 |
231 |
send_to_pe(swpchn_img); |
send_to_pe(swpchn_img); |
235 |
|
/* lock --------------------------------------------------------------*/ |
|
236 |
|
dec_frs_lock(); |
|
237 |
|
frs_clear_last_qed_to_pe(); |
|
238 |
|
dec_frs_unlock(); |
|
239 |
|
/* unlock ------------------------------------------------------------*/ |
|
240 |
|
fr_priv->is_last_qed_to_pe = true; |
|
|
232 |
|
last_fr_sent_to_pe = fr; |
241 |
233 |
fr_priv->was_qed_to_pe = true; /* drop detection */ |
fr_priv->was_qed_to_pe = true; /* drop detection */ |
242 |
234 |
} |
} |
243 |
235 |
#undef NO_FR |
#undef NO_FR |