1 struct thdsws_ctx_private_t
{
4 pthread_cond_t have_fr_to_scale
;
5 struct SwsContext
*sws
;
7 STATIC
void fatal(u8
*fmt
, ...)
14 va_end(ap
); /* unreachable */
16 STATIC
void fatalw(u8
*fmt
, ...)
20 npv_perr("scaler worker:");
23 va_end(ap
); /* unreachable */
25 STATIC
void state_lock(struct thdsws_ctx_private_t
*ctx_priv
)
29 r
= pthread_mutex_lock(&ctx_priv
->mutex
);
31 fatal("unable to lock the state\n");
33 STATIC
void state_unlock(struct thdsws_ctx_private_t
*ctx_priv
)
37 r
= pthread_mutex_unlock(&ctx_priv
->mutex
);
39 fatal("unable to unlock the state\n");
41 STATIC
void do_work(struct thdsws_ctx_t
*ctx
, struct thdsws_ctx_private_t
*ctx_priv
)
43 ctx_priv
->sws
= sws_get_cached_ctx(ctx_priv
->sws
,
44 (int)ctx
->cfg
.width
, (int)ctx
->cfg
.height
, ctx
->cfg
.src_fmt
,
45 (int)ctx
->cfg
.width
, (int)ctx
->cfg
.height
, ctx
->cfg
.dst_fmt
,
46 (int)ctx
->cfg
.flags
, 0, 0, 0);
47 if (ctx_priv
->sws
== 0)
48 fatalw("unable to get a ffmpeg context\n");
50 /* XXX: this is the hotspot */
51 (void)sws_scale(ctx_priv
->sws
,
52 (uint8_t const*const*)ctx
->scale
.src_slices
,
53 (int*)ctx
->scale
.src_strides
,
54 0, (int)ctx
->cfg
.height
,
55 (uint8_t*const*)&ctx
->scale
.dst_slice
,
56 (int*)&ctx
->scale
.dst_stride
);
60 STATIC
void worker(struct thdsws_ctx_t
*ctx
,
61 struct thdsws_ctx_private_t
*ctx_priv
)
63 /* on entry the state must be locked */
64 if (ctx_priv
->state
== RUNNING
) {
65 state_unlock(ctx_priv
);
66 do_work(ctx
, ctx_priv
);
68 ctx_priv
->state
= IDLE
;
71 loop
{ /* spurious IDLE protection */
74 /* while waiting the mutex is unlocked */
75 r
= pthread_cond_wait(&ctx_priv
->have_fr_to_scale
,
77 /* on exit the mutex is locked */
79 fatalw("an error occured while waiting for a frame\n");
80 if (ctx_priv
->state
!= IDLE
)
87 STATIC
void *worker_entry(void *arg
)
91 struct thdsws_ctx_t
*ctx
;
92 struct thdsws_ctx_private_t
*ctx_priv
;
94 r
= sigfillset(&sset
);
96 fatalw("unable to get a full signal mask\n");
98 r
= pthread_sigmask(SIG_SETMASK
, &sset
, 0);
100 fatalw("unable to \"block\" \"all\" signals\n");
103 ctx_priv
= ctx
->private;
105 state_lock(ctx_priv
);
106 loop
worker(ctx
, ctx_priv
); /* state must be locked on entry */