xref: /OK3568_Linux_fs/external/mpp/mpp/codec/rc/rc_data_impl.cpp (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  * Copyright 2016 Rockchip Electronics Co. LTD
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define MODULE_TAG "rc_data_impl"
18 
19 #include <string.h>
20 
21 #include "mpp_env.h"
22 #include "mpp_mem.h"
23 #include "mpp_list.h"
24 #include "mpp_debug.h"
25 #include "mpp_common.h"
26 
27 #include "rc_data.h"
28 #include "rc_data_impl.h"
29 
30 #define RC_LIST_HEAD            1
31 #define RC_LIST_TAIL            0
32 
33 #define RC_FRM_TYPE_I           0
34 #define RC_FRM_TYPE_P           1
35 
36 #define RC_FRM_STATUS_VALID     (0x00000001)
37 #define RC_HAL_SET_VALID        (0x00000002)
38 #define RC_HAL_RET_VALID        (0x00000004)
39 
rc_data_indexes_init(RcDataIndexes * sort)40 static void rc_data_indexes_init(RcDataIndexes *sort)
41 {
42     RK_S32 i;
43 
44     memset(sort, 0, sizeof(*sort));
45 
46     INIT_LIST_HEAD(&sort->seq);
47 
48     for (i = 0; i < (RK_S32)MPP_ARRAY_ELEMS(sort->type); i++)
49         INIT_LIST_HEAD(&sort->type[i]);
50 
51     for (i = 0; i < (RK_S32)MPP_ARRAY_ELEMS(sort->tid); i++)
52         INIT_LIST_HEAD(&sort->tid[i]);
53 
54     for (i = 0; i < (RK_S32)MPP_ARRAY_ELEMS(sort->status); i++)
55         INIT_LIST_HEAD(&sort->status[i]);
56 }
57 
rc_data_node_init(DataGroupImpl * p,RcDataNode * node,RK_S32 slot_idx)58 static void rc_data_node_init(DataGroupImpl *p, RcDataNode *node, RK_S32 slot_idx)
59 {
60     RcDataIndexes *indexes = &p->indexes;
61     RcDataStatus status = RC_DATA_ST_UNUSED;
62     RcDataHead *head = &node->head;
63     RcDataBase *base = &node->base;
64 
65     memset(node, 0, sizeof(*node));
66 
67     head->node = node;
68     head->slot_id = slot_idx;
69 
70     INIT_LIST_HEAD(&head->seq);
71     INIT_LIST_HEAD(&head->type);
72     INIT_LIST_HEAD(&head->tid);
73     INIT_LIST_HEAD(&head->status);
74     list_add_tail(&head->status, &indexes->status[status]);
75     indexes->status_cnt[status]++;
76 
77     base->head = head;
78 
79     node->extra = NULL;
80 }
81 
rc_data_group_init(DataGroupImpl * p,RK_S32 base_cnt,RK_S32 extra_cnt)82 MPP_RET rc_data_group_init(DataGroupImpl *p, RK_S32 base_cnt, RK_S32 extra_cnt)
83 {
84     p->lock = new Mutex();
85 
86     node_group_init(&p->node, sizeof(RcDataNode), base_cnt);
87     node_group_init(&p->extra, sizeof(RcDataExtra), extra_cnt);
88 
89     mpp_assert(p->lock);
90     mpp_assert(p->node);
91     mpp_assert(p->extra);
92 
93     p->base_cnt = base_cnt;
94     p->extra_cnt = extra_cnt;
95 
96     rc_data_group_reset(p);
97 
98     return MPP_OK;
99 }
100 
rc_data_group_deinit(DataGroupImpl * p)101 MPP_RET rc_data_group_deinit(DataGroupImpl *p)
102 {
103     mpp_assert(p->lock);
104     mpp_assert(p->node);
105     mpp_assert(p->extra);
106 
107     node_group_deinit(p->node);
108     node_group_deinit(p->extra);
109 
110     delete p->lock;
111 
112     return MPP_OK;
113 }
114 
rc_data_group_reset(DataGroupImpl * p)115 MPP_RET rc_data_group_reset(DataGroupImpl *p)
116 {
117     RK_S32 i;
118 
119     rc_data_indexes_init(&p->indexes);
120 
121     for (i = 0; i < p->base_cnt; i++) {
122         RcDataNode *node = (RcDataNode *)node_group_get(p->node, i);
123 
124         rc_data_node_init(p, node, i);
125     }
126 
127     for (i = 0; i < p->extra_cnt; i++) {
128         RcDataExtra *extra = (RcDataExtra *)node_group_get(p->extra, i);
129 
130         /* NOTE: node in head is NULL */
131         memset(extra, 0, sizeof(*extra));
132     }
133 
134     return MPP_OK;
135 }
136 
rc_data_group_get_node_by_seq_id(DataGroupImpl * p,RK_S32 seq_id)137 RcDataNode *rc_data_group_get_node_by_seq_id(DataGroupImpl *p, RK_S32 seq_id)
138 {
139     RcDataIndexes *indexes = &p->indexes;
140 
141     if (list_empty(&indexes->seq))
142         return NULL;
143 
144     RcDataNode *node = NULL;
145     RcDataHead *pos;
146 
147     if (MPP_ABS(seq_id - indexes->seq_new) < MPP_ABS(seq_id - indexes->seq_old)) {
148         list_for_each_entry(pos, &indexes->seq, RcDataHead, seq) {
149             if (pos->seq_id == seq_id) {
150                 node = pos->node;
151                 break;
152             }
153         }
154     } else {
155         list_for_each_entry_reverse(pos, &indexes->seq, RcDataHead, seq) {
156             if (pos->seq_id == seq_id) {
157                 node = pos->node;
158                 break;
159             }
160         }
161     }
162 
163     return node;
164 }
165 
rc_data_group_get_node_by_status(DataGroupImpl * p,RcDataStatus status,RK_S32 whence)166 RcDataNode *rc_data_group_get_node_by_status(DataGroupImpl *p, RcDataStatus status, RK_S32 whence)
167 {
168     RcDataIndexes *indexes = &p->indexes;
169 
170     mpp_assert(status >= RC_DATA_ST_UNUSED && status <= RC_DATA_ST_DONE);
171 
172     struct list_head *list = &indexes->status[status];
173 
174     if (list_empty(list))
175         return NULL;
176 
177     list = (whence == RC_LIST_HEAD) ? (list->next) : (list->prev);
178     RcDataHead *head = list_entry(list, RcDataHead, status);
179     mpp_assert(head->data_status == status);
180     mpp_assert(head->node);
181     return head->node;
182 }
183 
rc_data_group_put_node(DataGroupImpl * p,RcDataNode * node)184 void rc_data_group_put_node(DataGroupImpl *p, RcDataNode *node)
185 {
186     RcDataIndexes *indexes = &p->indexes;
187     RcDataHead *head = &node->head;
188 
189     AutoMutex auto_lock(p->lock);
190     RcDataStatus data_status = head->data_status;
191 
192     list_del_init(&head->status);
193     indexes->status_cnt[data_status]--;
194 
195     if (data_status == RC_DATA_ST_FILLING) {
196         // ready on filling add to indexing list by property
197         EncFrmStatus frm_status = head->frm_status;
198         RK_S32 type_id = frm_status.is_intra ? RC_FRM_TYPE_I : RC_FRM_TYPE_P;
199         RK_S32 tid = frm_status.temporal_id;
200 
201         mpp_assert(list_empty(&head->seq));
202         list_add_tail(&head->seq, &indexes->seq);
203         indexes->seq_cnt++;
204         indexes->seq_new = head->seq_id;
205 
206         mpp_assert(list_empty(&head->type));
207         list_add_tail(&head->type, &indexes->type[type_id]);
208         indexes->type_cnt[type_id]++;
209 
210         mpp_assert(tid < 4);
211         mpp_assert(list_empty(&head->tid));
212         list_add_tail(&head->tid, &indexes->tid[type_id]);
213         indexes->tid_cnt[type_id]++;
214     }
215 
216     // goto next status
217     switch (data_status) {
218     case RC_DATA_ST_UNUSED : {
219         data_status = RC_DATA_ST_FILLING;
220     } break;
221     case RC_DATA_ST_FILLING : {
222         data_status = RC_DATA_ST_DONE;
223     } break;
224     case RC_DATA_ST_DONE : {
225         data_status = RC_DATA_ST_UNUSED;
226     } break;
227     default : {
228         data_status = RC_DATA_ST_BUTT;
229         mpp_assert(data_status != RC_DATA_ST_BUTT);
230     } break;
231     }
232 
233     if (data_status == RC_DATA_ST_UNUSED) {
234         // removed from indexing list
235         EncFrmStatus frm_status = head->frm_status;
236 
237         if (!list_empty(&head->seq)) {
238             list_del_init(&head->seq);
239             indexes->seq_cnt--;
240             indexes->seq_old = head->seq_id;
241         }
242 
243         if (!list_empty(&head->type)) {
244             RK_S32 type_id = frm_status.is_intra ? RC_FRM_TYPE_I : RC_FRM_TYPE_P;
245 
246             list_del_init(&head->type);
247             indexes->type_cnt[type_id]--;
248         }
249 
250         if (!list_empty(&head->tid)) {
251             RK_S32 tid = frm_status.temporal_id;
252 
253             mpp_assert(tid < 4);
254             list_del_init(&head->tid);
255             indexes->tid_cnt[tid]--;
256         }
257     }
258 
259     list_add_tail(&head->status, &indexes->status[data_status]);
260     indexes->status_cnt[data_status]++;
261     head->data_status = data_status;
262 }
263 
rc_data_get_next(DataGroup grp)264 RcData rc_data_get_next(DataGroup grp)
265 {
266     DataGroupImpl *p = (DataGroupImpl *)grp;
267     RcDataNode *node = rc_data_group_get_node_by_status(
268                            p, RC_DATA_ST_UNUSED, RC_LIST_HEAD);
269 
270     return (RcData)node;
271 }
272 
rc_data_get_curr_latest(DataGroup grp)273 RcData rc_data_get_curr_latest(DataGroup grp)
274 {
275     DataGroupImpl *p = (DataGroupImpl *)grp;
276     RcDataNode *node = rc_data_group_get_node_by_status(
277                            p, RC_DATA_ST_FILLING, RC_LIST_TAIL);
278 
279     return (RcData)node;
280 }
281 
rc_data_get_curr_oldest(DataGroup grp)282 RcData rc_data_get_curr_oldest(DataGroup grp)
283 {
284     DataGroupImpl *p = (DataGroupImpl *)grp;
285     RcDataNode *node = rc_data_group_get_node_by_status(
286                            p, RC_DATA_ST_FILLING, RC_LIST_HEAD);
287 
288     return (RcData)node;
289 }
290 
rc_data_get_last_latest(DataGroup grp)291 RcData rc_data_get_last_latest(DataGroup grp)
292 {
293     DataGroupImpl *p = (DataGroupImpl *)grp;
294     RcDataNode *node = rc_data_group_get_node_by_status(
295                            p, RC_DATA_ST_DONE, RC_LIST_TAIL);
296 
297     return (RcData)node;
298 }
299 
rc_data_get_last_oldest(DataGroup grp)300 RcData rc_data_get_last_oldest(DataGroup grp)
301 {
302     DataGroupImpl *p = (DataGroupImpl *)grp;
303     RcDataNode *node = rc_data_group_get_node_by_status(
304                            p, RC_DATA_ST_DONE, RC_LIST_HEAD);
305 
306     return (RcData)node;
307 }
308