npv:_reasonable_ "pedanticage" of the code
[nyanmp.git] / npv / thdsws / local / code.frag.c
blob2dcf8b00bbb1f1e016141caee48f75f45e9d9f32
1 struct thdsws_ctx_private_t {
2 pthread_mutex_t mutex;
3 u8 state;
4 pthread_cond_t have_fr_to_scale;
5 struct SwsContext *sws;
6 };
7 STATIC void fatal(u8 *fmt, ...)
9 va_list ap;
11 npv_perr("scaler:");
12 va_start(ap, fmt);
13 npv_vfatal(fmt, ap);
14 va_end(ap); /* unreachable */
16 STATIC void fatalw(u8 *fmt, ...)
18 va_list ap;
20 npv_perr("scaler worker:");
21 va_start(ap, fmt);
22 npv_vfatal(fmt, ap);
23 va_end(ap); /* unreachable */
25 STATIC void state_lock(struct thdsws_ctx_private_t *ctx_priv)
27 int r;
29 r = pthread_mutex_lock(&ctx_priv->mutex);
30 if (r != 0)
31 fatal("unable to lock the state\n");
33 STATIC void state_unlock(struct thdsws_ctx_private_t *ctx_priv)
35 int r;
37 r = pthread_mutex_unlock(&ctx_priv->mutex);
38 if (r != 0)
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);
58 #define IDLE 0
59 #define RUNNING 1
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);
67 state_lock(ctx_priv);
68 ctx_priv->state = IDLE;
70 /* state == IDLE */
71 loop { /* spurious IDLE protection */
72 int r;
74 /* while waiting the mutex is unlocked */
75 r = pthread_cond_wait(&ctx_priv->have_fr_to_scale,
76 &ctx_priv->mutex);
77 /* on exit the mutex is locked */
78 if (r != 0)
79 fatalw("an error occured while waiting for a frame\n");
80 if (ctx_priv->state != IDLE)
81 break;
82 /* state == IDLE */
85 #undef IDLE
86 #undef RUNNING
87 STATIC void *worker_entry(void *arg)
89 int r;
90 sigset_t sset;
91 struct thdsws_ctx_t *ctx;
92 struct thdsws_ctx_private_t *ctx_priv;
94 r = sigfillset(&sset);
95 if (r == -1)
96 fatalw("unable to get a full signal mask\n");
98 r = pthread_sigmask(SIG_SETMASK, &sset, 0);
99 if (r != 0)
100 fatalw("unable to \"block\" \"all\" signals\n");
102 ctx = arg;
103 ctx_priv = ctx->private;
105 state_lock(ctx_priv);
106 loop worker(ctx, ctx_priv); /* state must be locked on entry */