2 STATIC
void init_once_public(void)
6 /* linux bug: still no CLOCK_MONOTONIC_RAW for timerfd */
8 timer_fd_p
= timerfd_create(CLOCK_MONOTONIC
, TFD_NONBLOCK
);
10 fatal("unable to get a timer file descriptor:%s\n", strerror(errno
));
11 memset(&st_p
, 0, sizeof(st_p
));
12 pkt_q_p
= npv_pkt_q_new("video");
14 r
= pthread_mutex_init(&dec_ctx_mutex_l
, 0);
16 fatal("unable to create the mutex for the decoder context\n");
18 dec_frs_p
.eof_receive
= false;
23 r
= pthread_mutex_init(&dec_frs_p
.mutex
, 0);
25 fatal("unable to create the mutex for the array of frames\n");
28 memset(&scaler_p
.img
.layout
, 0, sizeof(scaler_p
.img
.layout
));
29 scaler_p
.img
.dev_mem
= 0;
30 scaler_p
.img
.data
= 0;
31 scaler_p
.img
.fr
= NO_FR
;
33 last_fr_sent_to_pe_l
= NO_FR
;
35 aspect_ratio
.width
= 0;
36 aspect_ratio
.height
= 0;
38 /* we are targetting AVUTIL_PIX_FMT_RGB32/sRGB */
39 scaler_p
.ctx
= npv_thdsws_init_once();
40 if (scaler_p
.ctx
== 0)
41 fatalff("scaler:unable to initialize\n");
44 STATIC
void init_once(void)
49 STATIC
void dec_ctx_cfg(avcodec_params_t
*params
)
53 dec_l
= avcodec_find_dec(params
->codec_id
);
55 fatalff("unable to find a proper decoder\n");
56 avcodec_free_context(&dec_ctx_p
);
57 dec_ctx_p
= avcodec_alloc_ctx(dec_l
);
59 fatalff("unable to allocate an decoder context\n");
61 r
= avcodec_params_to_ctx(dec_ctx_p
, params
);
63 fatalff("unable to apply stream codec parameters in codec context\n");
64 /* XXX: ffmpeg thread count default is 1, set to 0 = auto */
65 dec_ctx_p
->thread_count
= 0;
66 r
= avcodec_open2(dec_ctx_p
, dec_l
, 0);
68 fatalff("unable to open the decoder context\n");
70 /* we will define the video aspect ratio with those values */
71 aspect_ratio
.width
= params
->width
;
72 aspect_ratio
.height
= params
->height
;
74 STATIC
void timer_start(void)
79 memset(&t
, 0, sizeof(t
));
80 /* initial and interval */
81 t
.it_value
.tv_nsec
= 1; /* asap */
82 t
.it_interval
.tv_nsec
= 2000000; /* 2ms */
83 r
= timerfd_settime(timer_fd_p
, 0, &t
, 0);
85 fatal("unable to arm the timer\n");
87 STATIC
void timer_slow_start(void)
92 memset(&t
, 0, sizeof(t
));
93 /* initial and interval */
94 t
.it_value
.tv_nsec
= 1; /* asap */
95 t
.it_interval
.tv_nsec
= 100000000; /* 100ms */
96 r
= timerfd_settime(timer_fd_p
, 0, &t
, 0);
98 fatal("unable to arm the timer\n");
103 STATIC u8
dec_fr_try_receive(void)
108 r
= avcodec_receive_video_fr(dec_ctx_p
, receive_fr_l
);
110 if (r
== AVUTIL_AVERROR(EAGAIN
))
116 if (dec_frs_p
.n
== dec_frs_p
.n_max
)
119 avutil_video_fr_ref_move(dec_frs_p
.a
[last
], receive_fr_l
);
120 memset(dec_frs_p
.priv_a
[last
], 0, sizeof(**dec_frs_p
.priv_a
));
124 } else if (r
== AVUTIL_AVERROR_EOF
) {
125 poutff("last decoder frame reached (receiving)\n");
127 dec_frs_p
.eof_receive
= true;
131 fatalff("error while receiving frame from the decoder\n");
139 STATIC
void dec_frs_receive_avail(void) { loop
143 r
= dec_fr_try_receive();
146 else if (r
== AGAIN
|| r
== EOF_DEC
)
153 STATIC
void dec_flush(void)
155 npv_pkt_q_unref_all(pkt_q_p
);
157 dec_frs_p
.eof_receive
= false;
158 last_fr_sent_to_pe_l
= NO_FR
;
159 avcodec_flush_bufs(dec_ctx_p
);
162 STATIC
void dec_ctx_lock(void)
166 r
= pthread_mutex_lock(&dec_ctx_mutex_l
);
168 fatal("%d:unable to lock the video decoder context\n", r
);
170 STATIC
void dec_ctx_unlock(void)
174 r
= pthread_mutex_unlock(&dec_ctx_mutex_l
);
176 fatal("%d:unable to unlock the video decoder context\n", r
);
178 STATIC
void dec_frs_lock(void)
182 r
= pthread_mutex_lock(&dec_frs_p
.mutex
);
184 fatal("%d:unable to lock the array of decoder frames\n", r
);
186 STATIC
void dec_frs_unlock(void)
190 r
= pthread_mutex_unlock(&dec_frs_p
.mutex
);
192 fatal("%d:unable to unlock the array of decoder frames\n", r
);
194 /* go non-blocking or a worker thread is needed */
196 #define TS_FROM_CLK_OK 0
200 /* XXX: we do want to lock the frs q the least amount of time as possible */
201 STATIC
void timer_evt(void)
205 avutil_video_fr_ref_t
*fr
;
206 struct dec_fr_priv_t
*fr_priv
;
210 r
= npv_clk_get_video_st_ts(&now
);
211 if (r
!= TS_FROM_CLK_OK
)
213 /* lock --------------------------------------------------------------*/
215 if (dec_frs_p
.n
== 0) {
219 select_fr(now
, &fr
, &fr_priv
);
222 /* unlock ------------------------------------------------------------*/
225 /* in pause, we "redraw" the same img all the time */
226 if (!npv_paused_p
&& fr
== last_fr_sent_to_pe_l
)
228 if (npv_thdsws_is_busy(scaler_p
.ctx
)) {
231 if (scaler_p
.img
.fr
!= fr
) {
232 start_scaling(fr
, fr_priv
);
236 npv_video_osd_rop_restore();
237 npv_video_osd_rop_blend(now
);
238 if (!is_swpchn_sem_consistent())
240 loop
{ /* because the swpchn can change for many reasons */
241 r
= swpchn_next_img(&swpchn_img
);
244 blit_setup(swpchn_img
);
245 r
= send_to_pe(swpchn_img
);
248 /* r == SWPCHN_UPDATED */
250 last_fr_sent_to_pe_l
= fr
;
251 fr_priv
->was_qed_to_pe
= true; /* drop detection */
254 #undef TS_FROM_CLK_OK
258 /* we do per-loop fine-grained locking */
260 STATIC
void pkts_send(void) { loop
263 avcodec_pkt_ref_t
*pr
;
265 npv_pkt_q_lock(pkt_q_p
);
267 goto unlock_and_return
;
270 r
= avcodec_send_pkt(dec_ctx_p
, pr
);
272 if (r
== AVERROR(EAGAIN
)) /* dec is full and the pkt is rejected */
273 goto unlock_and_return
;
274 else if (r
== AVUTIL_AVERROR_EOF
) /* the dec is in draining mode */
275 goto unlock_and_return
;
277 fatal("error while sending a packet to the decoder\n");
279 npv_pipeline_limits_lock();
280 npv_pipeline_limits_p
.pkts
.video_bytes_n
-= pr
->sz
;
281 npv_pipeline_limits_unlock();
283 npv_pkt_q_deq(pkt_q_p
);
284 avcodec_pkt_unref(pr
);
285 npv_pkt_q_unlock(pkt_q_p
);
289 npv_pkt_q_unlock(pkt_q_p
);