Files
mpp/mpp/codec/inc/rc_data_impl.h
Herman Chen 2c7f6c2d95 [rc_data]: Add rc data implement
The principle of rc_data is to maintain rate control related data for
default and user define rate control algorithm.

Mpp internal work flow will automatically maintain these data. Then rate
control algorithm can just use the data by some APIs.

RC data has some status transaction betweeen different flow stage.
Stage 1. RcData is at unused status.
Stage 2. RcData is got by encoder and encoder starts to filling data.
Stage 3. When data filling is finished RcData is marked as done status.
Stage 4. When data receive max life cycle it returns to unused status.

Encoder will fill in the RC related data including:
1. Unique sequence id
2. Frame type / status
3. Stream size
4. Extra info (hardware feedback)

 Overall status and stage diagram

 oldest                                                       latest
 +                                               +           +
 |last                                           |  current  | next
 +----------------------------------------------------------------->
 |                     done                      |  filling  |unused
 +head                                       tail+head   tail+head

Signed-off-by: Herman Chen <herman.chen@rock-chips.com>
Change-Id: Ib71581d0585f60b46de20662ffe1d20989270884
2019-12-19 10:43:41 +08:00

202 lines
5.6 KiB
C

/*
* Copyright 2016 Rockchip Electronics Co. LTD
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __RC_DATA_IMPL_H__
#define __RC_DATA_IMPL_H__
#include "rc_data_base.h"
typedef enum RcDataStatus_e {
RC_DATA_ST_UNUSED,
RC_DATA_ST_FILLING,
RC_DATA_ST_DONE,
RC_DATA_ST_BUTT,
} RcDataStatus;
/*
* RcDataNode is composed of several parts:
*
* Sort function node - for RcDataNode sorting
* Basic data node - basic long-term data storage
* Extra data node - extra short-term data storage
*/
typedef struct RcDataNode_t RcDataNode;
typedef struct RcDataHead_t {
// node pointer to RcDataNode
RcDataNode *node;
/* unique sequential id */
RK_S32 seq_id;
/* frame status parameter */
EncFrmStatus frm_status;
/* slot index in storage */
RK_S32 slot_id;
/* list head to sequence list */
struct list_head seq;
/* list head to frame type list */
struct list_head type;
/* list head to temporal id list */
struct list_head tid;
/* list head to status list */
struct list_head status;
RcDataStatus data_status;
} RcDataHead;
typedef struct RcDataBase_t {
// node pointer to RcDataNode
RcDataHead *head;
RK_S32 stream_size;
RK_S32 qp_sum;
} RcDataBase;
/*
* RcDataExtra is the short-term detail data storage.
*
* RC module will keep this frame data history for RcImplApi to implement
* different rate control strategy.
*/
typedef struct RcDataExtra_t {
// node pointer to RcDataNode
RcDataHead *head;
RK_S32 target_bit;
RcHalSet set;
RcHalRet ret;
} RcDataExtra;
typedef struct RcDataIndexes_t {
/* list head to sequence list */
struct list_head seq;
RK_S32 seq_cnt;
RK_S32 seq_new;
RK_S32 seq_old;
/*
* list head to frame type list
* 0 - I frame
* 1 - P frame
*/
struct list_head type[2];
RK_S32 type_cnt[2];
/*
* list head to temporal layer list
* 0 - layer 0
* 1 - layer 1
* 2 - layer 2
* 3 - layer 3
*/
struct list_head tid[4];
RK_S32 tid_cnt[4];
/*
* list head to status list
* 0 - unused
* 1 - filling
* 2 - fill done
*/
struct list_head status[3];
RK_S32 status_cnt[4];
} RcDataIndexes;
typedef struct RcDataNode_t {
RcDataHead head;
RcDataBase base;
RcDataExtra *extra;
} RcDataNode;
typedef struct DataGroupImpl_t {
Mutex *lock;
RK_S32 base_cnt;
RK_S32 extra_cnt;
/* status list header for recording the node */
RcDataIndexes indexes;
// cache for current update
RcDataNode *curr_node;
NodeGroup *node;
NodeGroup *extra;
} DataGroupImpl;
#ifdef __cplusplus
extern "C" {
#endif
/* mpp rate control data internal update function */
MPP_RET rc_data_set_frm_status(RcDataNode *node, EncFrmStatus status);
MPP_RET rc_data_set_hal_set(RcDataNode *node, RcHalSet *set);
MPP_RET rc_data_set_hal_ret(RcDataNode *node, RcHalRet *ret);
MPP_RET rc_data_group_init(DataGroupImpl *p, RK_S32 base_cnt, RK_S32 extra_cnt);
MPP_RET rc_data_group_deinit(DataGroupImpl *p);
MPP_RET rc_data_group_reset(DataGroupImpl *p);
RcDataNode *rc_data_group_get_node_by_seq_id(DataGroupImpl *p, RK_S32 seq_id);
RcDataNode *rc_data_group_get_node_by_status(DataGroupImpl *p, RcDataStatus status, RK_S32 head);
/* put the node to the tail of next status */
void rc_data_group_put_node(DataGroupImpl *p, RcDataNode *node);
/*
* rc data access helper function
*
* rc_data_get_next
* Get next rc data for current frame rc data storage
* equal to rc_data_group_get_node_by_status( unused, head )
*
* rc_data_get_curr_latest
* Get latest current encoding frame rc data storage.
* This function is for normal usage and reencoding.
* equal to rc_data_group_get_node_by_status( filling, tail )
*
* rc_data_get_curr_tail
* Get oldest current encoding frame rc data storage.
* equal to rc_data_group_get_node_by_status( filling, head )
*
* rc_data_get_last
* Get oldest encoded frame rc data storage.
* equal to rc_data_group_get_node_by_status( done, head )
*
* Overall status and stage diagram
*
* oldest latest
* + + +
* |last | current | next
* +----------------------------------------------------------------->
* | done | filling |unused
* +head tail+head tail+head
*
* status transaction: unused -> filling -> done -> unused
*/
RcData rc_data_get_next(DataGroup grp);
RcData rc_data_get_curr_latest(DataGroup grp);
RcData rc_data_get_curr_oldest(DataGroup grp);
RcData rc_data_get_last_latest(DataGroup grp);
RcData rc_data_get_last_oldest(DataGroup grp);
#ifdef __cplusplus
}
#endif
#endif /* __RC_DATA_IMPL_H__ */