xref: /aosp_15_r20/external/libvpx/vp9/decoder/vp9_job_queue.c (revision fb1b10ab9aebc7c7068eedab379b749d7e3900be)
1*fb1b10abSAndroid Build Coastguard Worker /*
2*fb1b10abSAndroid Build Coastguard Worker  *  Copyright (c) 2018 The WebM project authors. All Rights Reserved.
3*fb1b10abSAndroid Build Coastguard Worker  *
4*fb1b10abSAndroid Build Coastguard Worker  *  Use of this source code is governed by a BSD-style license
5*fb1b10abSAndroid Build Coastguard Worker  *  that can be found in the LICENSE file in the root of the source
6*fb1b10abSAndroid Build Coastguard Worker  *  tree. An additional intellectual property rights grant can be found
7*fb1b10abSAndroid Build Coastguard Worker  *  in the file PATENTS.  All contributing project authors may
8*fb1b10abSAndroid Build Coastguard Worker  *  be found in the AUTHORS file in the root of the source tree.
9*fb1b10abSAndroid Build Coastguard Worker  */
10*fb1b10abSAndroid Build Coastguard Worker 
11*fb1b10abSAndroid Build Coastguard Worker #include <assert.h>
12*fb1b10abSAndroid Build Coastguard Worker #include <string.h>
13*fb1b10abSAndroid Build Coastguard Worker 
14*fb1b10abSAndroid Build Coastguard Worker #include "vpx/vpx_integer.h"
15*fb1b10abSAndroid Build Coastguard Worker #include "vpx_util/vpx_pthread.h"
16*fb1b10abSAndroid Build Coastguard Worker 
17*fb1b10abSAndroid Build Coastguard Worker #include "vp9/decoder/vp9_job_queue.h"
18*fb1b10abSAndroid Build Coastguard Worker 
vp9_jobq_init(JobQueueRowMt * jobq,uint8_t * buf,size_t buf_size)19*fb1b10abSAndroid Build Coastguard Worker void vp9_jobq_init(JobQueueRowMt *jobq, uint8_t *buf, size_t buf_size) {
20*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_MULTITHREAD
21*fb1b10abSAndroid Build Coastguard Worker   pthread_mutex_init(&jobq->mutex, NULL);
22*fb1b10abSAndroid Build Coastguard Worker   pthread_cond_init(&jobq->cond, NULL);
23*fb1b10abSAndroid Build Coastguard Worker #endif
24*fb1b10abSAndroid Build Coastguard Worker   jobq->buf_base = buf;
25*fb1b10abSAndroid Build Coastguard Worker   jobq->buf_wr = buf;
26*fb1b10abSAndroid Build Coastguard Worker   jobq->buf_rd = buf;
27*fb1b10abSAndroid Build Coastguard Worker   jobq->buf_end = buf + buf_size;
28*fb1b10abSAndroid Build Coastguard Worker   jobq->terminate = 0;
29*fb1b10abSAndroid Build Coastguard Worker }
30*fb1b10abSAndroid Build Coastguard Worker 
vp9_jobq_reset(JobQueueRowMt * jobq)31*fb1b10abSAndroid Build Coastguard Worker void vp9_jobq_reset(JobQueueRowMt *jobq) {
32*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_MULTITHREAD
33*fb1b10abSAndroid Build Coastguard Worker   pthread_mutex_lock(&jobq->mutex);
34*fb1b10abSAndroid Build Coastguard Worker #endif
35*fb1b10abSAndroid Build Coastguard Worker   jobq->buf_wr = jobq->buf_base;
36*fb1b10abSAndroid Build Coastguard Worker   jobq->buf_rd = jobq->buf_base;
37*fb1b10abSAndroid Build Coastguard Worker   jobq->terminate = 0;
38*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_MULTITHREAD
39*fb1b10abSAndroid Build Coastguard Worker   pthread_mutex_unlock(&jobq->mutex);
40*fb1b10abSAndroid Build Coastguard Worker #endif
41*fb1b10abSAndroid Build Coastguard Worker }
42*fb1b10abSAndroid Build Coastguard Worker 
vp9_jobq_deinit(JobQueueRowMt * jobq)43*fb1b10abSAndroid Build Coastguard Worker void vp9_jobq_deinit(JobQueueRowMt *jobq) {
44*fb1b10abSAndroid Build Coastguard Worker   vp9_jobq_reset(jobq);
45*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_MULTITHREAD
46*fb1b10abSAndroid Build Coastguard Worker   pthread_mutex_destroy(&jobq->mutex);
47*fb1b10abSAndroid Build Coastguard Worker   pthread_cond_destroy(&jobq->cond);
48*fb1b10abSAndroid Build Coastguard Worker #endif
49*fb1b10abSAndroid Build Coastguard Worker }
50*fb1b10abSAndroid Build Coastguard Worker 
vp9_jobq_terminate(JobQueueRowMt * jobq)51*fb1b10abSAndroid Build Coastguard Worker void vp9_jobq_terminate(JobQueueRowMt *jobq) {
52*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_MULTITHREAD
53*fb1b10abSAndroid Build Coastguard Worker   pthread_mutex_lock(&jobq->mutex);
54*fb1b10abSAndroid Build Coastguard Worker #endif
55*fb1b10abSAndroid Build Coastguard Worker   jobq->terminate = 1;
56*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_MULTITHREAD
57*fb1b10abSAndroid Build Coastguard Worker   pthread_cond_broadcast(&jobq->cond);
58*fb1b10abSAndroid Build Coastguard Worker   pthread_mutex_unlock(&jobq->mutex);
59*fb1b10abSAndroid Build Coastguard Worker #endif
60*fb1b10abSAndroid Build Coastguard Worker }
61*fb1b10abSAndroid Build Coastguard Worker 
vp9_jobq_queue(JobQueueRowMt * jobq,void * job,size_t job_size)62*fb1b10abSAndroid Build Coastguard Worker int vp9_jobq_queue(JobQueueRowMt *jobq, void *job, size_t job_size) {
63*fb1b10abSAndroid Build Coastguard Worker   int ret = 0;
64*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_MULTITHREAD
65*fb1b10abSAndroid Build Coastguard Worker   pthread_mutex_lock(&jobq->mutex);
66*fb1b10abSAndroid Build Coastguard Worker #endif
67*fb1b10abSAndroid Build Coastguard Worker   if (jobq->buf_end >= jobq->buf_wr + job_size) {
68*fb1b10abSAndroid Build Coastguard Worker     memcpy(jobq->buf_wr, job, job_size);
69*fb1b10abSAndroid Build Coastguard Worker     jobq->buf_wr = jobq->buf_wr + job_size;
70*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_MULTITHREAD
71*fb1b10abSAndroid Build Coastguard Worker     pthread_cond_signal(&jobq->cond);
72*fb1b10abSAndroid Build Coastguard Worker #endif
73*fb1b10abSAndroid Build Coastguard Worker     ret = 0;
74*fb1b10abSAndroid Build Coastguard Worker   } else {
75*fb1b10abSAndroid Build Coastguard Worker     /* Wrap around case is not supported */
76*fb1b10abSAndroid Build Coastguard Worker     assert(0);
77*fb1b10abSAndroid Build Coastguard Worker     ret = 1;
78*fb1b10abSAndroid Build Coastguard Worker   }
79*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_MULTITHREAD
80*fb1b10abSAndroid Build Coastguard Worker   pthread_mutex_unlock(&jobq->mutex);
81*fb1b10abSAndroid Build Coastguard Worker #endif
82*fb1b10abSAndroid Build Coastguard Worker   return ret;
83*fb1b10abSAndroid Build Coastguard Worker }
84*fb1b10abSAndroid Build Coastguard Worker 
vp9_jobq_dequeue(JobQueueRowMt * jobq,void * job,size_t job_size,int blocking)85*fb1b10abSAndroid Build Coastguard Worker int vp9_jobq_dequeue(JobQueueRowMt *jobq, void *job, size_t job_size,
86*fb1b10abSAndroid Build Coastguard Worker                      int blocking) {
87*fb1b10abSAndroid Build Coastguard Worker   int ret = 0;
88*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_MULTITHREAD
89*fb1b10abSAndroid Build Coastguard Worker   pthread_mutex_lock(&jobq->mutex);
90*fb1b10abSAndroid Build Coastguard Worker #endif
91*fb1b10abSAndroid Build Coastguard Worker   if (jobq->buf_end >= jobq->buf_rd + job_size) {
92*fb1b10abSAndroid Build Coastguard Worker     while (1) {
93*fb1b10abSAndroid Build Coastguard Worker       if (jobq->buf_wr >= jobq->buf_rd + job_size) {
94*fb1b10abSAndroid Build Coastguard Worker         memcpy(job, jobq->buf_rd, job_size);
95*fb1b10abSAndroid Build Coastguard Worker         jobq->buf_rd = jobq->buf_rd + job_size;
96*fb1b10abSAndroid Build Coastguard Worker         ret = 0;
97*fb1b10abSAndroid Build Coastguard Worker         break;
98*fb1b10abSAndroid Build Coastguard Worker       } else {
99*fb1b10abSAndroid Build Coastguard Worker         /* If all the entries have been dequeued, then break and return */
100*fb1b10abSAndroid Build Coastguard Worker         if (jobq->terminate == 1) {
101*fb1b10abSAndroid Build Coastguard Worker           ret = 1;
102*fb1b10abSAndroid Build Coastguard Worker           break;
103*fb1b10abSAndroid Build Coastguard Worker         }
104*fb1b10abSAndroid Build Coastguard Worker         if (blocking == 1) {
105*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_MULTITHREAD
106*fb1b10abSAndroid Build Coastguard Worker           pthread_cond_wait(&jobq->cond, &jobq->mutex);
107*fb1b10abSAndroid Build Coastguard Worker #endif
108*fb1b10abSAndroid Build Coastguard Worker         } else {
109*fb1b10abSAndroid Build Coastguard Worker           /* If there is no job available,
110*fb1b10abSAndroid Build Coastguard Worker            * and this is non blocking call then return fail */
111*fb1b10abSAndroid Build Coastguard Worker           ret = 1;
112*fb1b10abSAndroid Build Coastguard Worker           break;
113*fb1b10abSAndroid Build Coastguard Worker         }
114*fb1b10abSAndroid Build Coastguard Worker       }
115*fb1b10abSAndroid Build Coastguard Worker     }
116*fb1b10abSAndroid Build Coastguard Worker   } else {
117*fb1b10abSAndroid Build Coastguard Worker     /* Wrap around case is not supported */
118*fb1b10abSAndroid Build Coastguard Worker     ret = 1;
119*fb1b10abSAndroid Build Coastguard Worker   }
120*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_MULTITHREAD
121*fb1b10abSAndroid Build Coastguard Worker   pthread_mutex_unlock(&jobq->mutex);
122*fb1b10abSAndroid Build Coastguard Worker #endif
123*fb1b10abSAndroid Build Coastguard Worker 
124*fb1b10abSAndroid Build Coastguard Worker   return ret;
125*fb1b10abSAndroid Build Coastguard Worker }
126