[mpp_enc_v2]: Unify sei writing process

Change interface of adding stream prefix which is adding sei packet in
H.264/H.265.

The sei will be added with certain type:
1. version info
2. rate control info (rc api name + rc cfg)
3. user data

Change-Id: Ic17efb6b9f75db774b7ad7e7cc78818170260def
Signed-off-by: Herman Chen <herman.chen@rock-chips.com>
This commit is contained in:
Herman Chen 2020-06-01 14:10:02 +08:00
parent b8caab0fe0
commit 9f6dcfccc4
12 changed files with 167 additions and 122 deletions

View File

@ -19,7 +19,6 @@
#include <string.h>
#include "mpp_env.h"
#include "mpp_info.h"
#include "mpp_log.h"
#include "mpp_mem.h"
#include "mpp_common.h"
@ -581,46 +580,11 @@ static MPP_RET h264e_proc_hal(void *ctx, HalEncTask *task)
return MPP_OK;
}
static MPP_RET h264e_add_sei(void *ctx, HalEncTask *task)
MPP_RET h264e_add_sei(MppPacket pkt, RK_S32 *length, RK_U8 uuid[16],
const void *data, RK_S32 size)
{
H264eCtx *p = (H264eCtx *)ctx;
MppMeta meta = mpp_frame_get_meta(task->frame);
EncRcTask *rc_task = task->rc_task;
EncFrmStatus *frm = &rc_task->frm;
MppEncUserData *user_data = NULL;
h264e_dbg_func("enter\n");
task->sei_length = 0;
if (frm->is_idr) {
const char *version = get_mpp_version();
RK_S32 len = strlen(version);
RK_S32 version_len = 0;
h264e_sei_to_packet(version, len,
H264_SEI_USER_DATA_UNREGISTERED,
task->packet, &version_len);
task->sei_length += version_len;
task->length += version_len;
}
mpp_meta_get_ptr(meta, KEY_USER_DATA, (void**)&user_data);
if (user_data) {
if (user_data->pdata && user_data->len) {
h264e_sei_to_packet(user_data->pdata, user_data->len,
H264_SEI_USER_DATA_UNREGISTERED,
task->packet, &p->sei_len);
task->sei_length += p->sei_len;
task->length += p->sei_len;
} else
mpp_err_f("failed to insert user data %p len %d\n",
user_data->pdata, user_data->len);
}
h264e_dbg_func("leave\n");
return MPP_OK;
return h264e_sei_to_packet(pkt, length, H264_SEI_USER_DATA_UNREGISTERED,
uuid, data, size);
}
/*!

View File

@ -26,13 +26,8 @@
#include "h264_syntax.h"
#include "h264e_sei.h"
static RK_U8 mpp_h264e_uuid[16] = {
0x63, 0xfc, 0x6a, 0x3c, 0xd8, 0x5c, 0x44, 0x1e,
0x87, 0xfb, 0x3f, 0xab, 0xec, 0xb3, 0xb6, 0x77,
};
MPP_RET h264e_sei_to_packet(const void *data, RK_S32 size, RK_S32 type,
MppPacket packet, RK_S32 *len)
MPP_RET h264e_sei_to_packet(MppPacket packet, RK_S32 *len, RK_S32 type,
RK_U8 uuid[16], const void *data, RK_S32 size)
{
void *pos = mpp_packet_get_pos(packet);
void *pkt_base = mpp_packet_get_data(packet);
@ -43,7 +38,7 @@ MPP_RET h264e_sei_to_packet(const void *data, RK_S32 size, RK_S32 type,
RK_S32 buf_size = (pkt_base + pkt_size) - (pos + length);
MppWriteCtx bit_ctx;
MppWriteCtx *bit = &bit_ctx;
RK_S32 uuid_size = sizeof(mpp_h264e_uuid);
RK_S32 uuid_size = 16;
RK_S32 payload_size = size + uuid_size;
RK_S32 sei_size = 0;
RK_S32 i;
@ -79,7 +74,7 @@ MPP_RET h264e_sei_to_packet(const void *data, RK_S32 size, RK_S32 type,
/* uuid_iso_iec_11578 */
for (i = 0; i < uuid_size; i++)
mpp_writer_put_bits(bit, mpp_h264e_uuid[i], 8);
mpp_writer_put_bits(bit, uuid[i], 8);
/* sei_payload_data */
for (i = 0; i < size; i++)

View File

@ -23,8 +23,8 @@
extern "C" {
#endif
MPP_RET h264e_sei_to_packet(const void *data, RK_S32 size, RK_S32 type,
MppPacket packet, RK_S32 *len);
MPP_RET h264e_sei_to_packet(MppPacket packet, RK_S32 *len, RK_S32 type,
RK_U8 uuid[16], const void *data, RK_S32 size);
#ifdef __cplusplus
}

View File

@ -20,7 +20,6 @@
#include "mpp_env.h"
#include "mpp_mem.h"
#include "mpp_info.h"
#include "rc.h"
#include "mpp_enc_cfg_impl.h"
@ -253,45 +252,19 @@ static MPP_RET h265e_proc_hal(void *ctx, HalEncTask *task)
return MPP_OK;
}
static MPP_RET h265e_add_sei(void *ctx, HalEncTask *task)
static MPP_RET h265e_add_sei(MppPacket pkt, RK_S32 *length, RK_U8 uuid[16],
const void *data, RK_S32 size)
{
(void) ctx;
MppFrame frame = task->frame;
RK_U8 *out_ptr = mpp_buffer_get_ptr(task->output);
RK_U32 offset = mpp_packet_get_length(task->packet);
EncRcTask *rc_task = task->rc_task;
EncFrmStatus *frm = &rc_task->frm;
RK_U32 sei_size = 0;
MppMeta meta = mpp_frame_get_meta(frame);
MppEncUserData *user_data = NULL;
RK_U8 *ptr = mpp_packet_get_pos(pkt);
RK_U32 offset = mpp_packet_get_length(pkt);
RK_U32 new_length = 0;
h265e_dbg_func("enter\n");
ptr += offset;
new_length = h265e_data_to_sei(ptr, uuid, data, size);
*length = new_length;
task->sei_length = 0;
mpp_packet_set_length(pkt, offset + new_length);
out_ptr = out_ptr + offset;
if (frm->is_idr) {
const char *version = get_mpp_version();
RK_S32 len = strlen(version);
sei_size = h265e_insert_user_data(out_ptr, (void *)version, len);
mpp_packet_set_length(task->packet, sei_size + offset);
task->sei_length += sei_size;
task->length += sei_size;
offset += sei_size;
}
out_ptr = out_ptr + offset;
mpp_meta_get_ptr(meta, KEY_USER_DATA, (void**)&user_data);
if (user_data && user_data->len) {
sei_size = h265e_insert_user_data(out_ptr, user_data->pdata, user_data->len);
mpp_packet_set_length(task->packet, sei_size + offset);
task->sei_length += sei_size;
task->length += sei_size;
}
h265e_dbg_func("leave\n");
return MPP_OK;
}
@ -355,6 +328,13 @@ static MPP_RET h265e_proc_rc_cfg(MppEncRcCfg *dst, MppEncRcCfg *src)
dst->bps_target, dst->bps_min, dst->bps_max);
ret = MPP_ERR_VALUE;
}
if ((dst->bps_target > dst->bps_max || dst->bps_target < dst->bps_min) ||
(dst->bps_max < dst->bps_min)) {
mpp_err("invalid bit rate config %d [%d:%d] for size relationship\n",
dst->bps_target, dst->bps_min, dst->bps_max);
ret = MPP_ERR_VALUE;
}
}
dst->change |= change;

View File

@ -124,23 +124,18 @@ static MPP_RET h265e_encapsulate_nals(H265eExtraInfo *out)
return MPP_OK;
}
static MPP_RET h265e_sei_write(H265eStream *s, RK_U8 *payload,
static MPP_RET h265e_sei_write(H265eStream *s, RK_U8 uuid[16], const RK_U8 *payload,
RK_S32 payload_size, RK_S32 payload_type)
{
#define H265E_UUID_LENGTH 16
static const RK_U8 h265e_sei_uuid[H265E_UUID_LENGTH] = {
0x63, 0xfc, 0x6a, 0x3c, 0xd8, 0x5c, 0x44, 0x1e,
0x87, 0xfb, 0x3f, 0xab, 0xec, 0xb3, 0xb6, 0x77
};
RK_S32 i = 0;
RK_S32 uuid_len = H265E_UUID_LENGTH;
RK_S32 data_len = payload_size;
h265e_dbg_func("enter\n");
h265e_stream_realign(s);
payload_size += H265E_UUID_LENGTH;
payload_size += uuid_len;
for (i = 0; i <= payload_type - 255; i += 255)
h265e_stream_write_with_log(s, 0xff, 8,
@ -156,8 +151,8 @@ static MPP_RET h265e_sei_write(H265eStream *s, RK_U8 *payload,
h265e_stream_write_with_log(s, payload_size - i, 8,
"sei_last_payload_size_byte");
for (i = 0; i < H265E_UUID_LENGTH; i++) {
h265e_stream_write_with_log(s, h265e_sei_uuid[i], 8,
for (i = 0; i < uuid_len; i++) {
h265e_stream_write_with_log(s, uuid[i], 8,
"sei_uuid_byte");
}
@ -669,7 +664,7 @@ MPP_RET h265e_set_extra_info(H265eCtx *ctx)
return MPP_OK;
}
RK_U32 h265e_insert_user_data(void *dst, void *play_load, RK_S32 play_size)
RK_U32 h265e_data_to_sei(void *dst, RK_U8 uuid[16], const void *payload, RK_S32 size)
{
H265eNal sei_nal;
H265eStream stream;
@ -682,7 +677,7 @@ RK_U32 h265e_insert_user_data(void *dst, void *play_load, RK_S32 play_size)
sei_nal.i_type = NAL_SEI_PREFIX;
sei_nal.p_payload = &stream.buf[stream.enc_stream.byte_cnt];
h265e_sei_write(&stream, play_load, play_size, H265_SEI_USER_DATA_UNREGISTERED);
h265e_sei_write(&stream, uuid, payload, size, H265_SEI_USER_DATA_UNREGISTERED);
RK_U8 *end = &stream.buf[stream.enc_stream.byte_cnt];
sei_nal.i_payload = (RK_S32)(end - sei_nal.p_payload);

View File

@ -95,8 +95,7 @@ void h265e_rkv_nal_start(H265eExtraInfo *out, RK_S32 i_type,
void h265e_nal_end(H265eExtraInfo *out);
RK_U32 h265e_insert_user_data(void *dst, void *play_load,
RK_S32 play_size);
RK_U32 h265e_data_to_sei(void *dst, RK_U8 uuid[16], const void *payload, RK_S32 size);
MPP_RET h265e_set_extra_info(H265eCtx *ctx);
MPP_RET h265e_get_extra_info(H265eCtx *ctx, MppPacket pkt_out);

View File

@ -72,7 +72,8 @@ typedef struct EncImplApi_t {
MPP_RET (*proc_dpb)(void *ctx, HalEncTask *task);
MPP_RET (*proc_hal)(void *ctx, HalEncTask *task);
MPP_RET (*add_prefix)(void *ctx, HalEncTask *task);
MPP_RET (*add_prefix)(MppPacket pkt, RK_S32 *length, RK_U8 uuid[16],
const void *data, RK_S32 size);
MPP_RET (*reset)(void *ctx);
MPP_RET (*flush)(void *ctx);

View File

@ -25,19 +25,20 @@ typedef void* EncImpl;
extern "C" {
#endif
MPP_RET enc_impl_init(EncImpl *ctrl, EncImplCfg *cfg);
MPP_RET enc_impl_deinit(EncImpl ctrl);
MPP_RET enc_impl_init(EncImpl *impl, EncImplCfg *cfg);
MPP_RET enc_impl_deinit(EncImpl impl);
MPP_RET enc_impl_proc_cfg(EncImpl ctrl, MpiCmd cmd, void *para);
MPP_RET enc_impl_gen_hdr(EncImpl ctrl, MppPacket pkt);
MPP_RET enc_impl_proc_cfg(EncImpl impl, MpiCmd cmd, void *para);
MPP_RET enc_impl_gen_hdr(EncImpl impl, MppPacket pkt);
MPP_RET enc_impl_start(EncImpl ctrl, HalEncTask *task);
MPP_RET enc_impl_proc_dpb(EncImpl ctrl, HalEncTask *task);
MPP_RET enc_impl_proc_hal(EncImpl ctrl, HalEncTask *task);
MPP_RET enc_impl_start(EncImpl impl, HalEncTask *task);
MPP_RET enc_impl_proc_dpb(EncImpl impl, HalEncTask *task);
MPP_RET enc_impl_proc_hal(EncImpl impl, HalEncTask *task);
MPP_RET enc_impl_add_prefix(EncImpl ctrl, HalEncTask *task);
MPP_RET enc_impl_add_prefix(EncImpl impl, MppPacket pkt, RK_S32 *length,
RK_U8 uuid[16], const void *data, RK_S32 size);
MPP_RET hal_enc_callback(void* ctrl, void *err_info);
MPP_RET hal_enc_callback(void* impl, void *err_info);
#ifdef __cplusplus
}

View File

@ -62,7 +62,7 @@ typedef void* RcCtx;
extern "C" {
#endif
MPP_RET rc_init(RcCtx *ctx, MppCodingType type, const char *name);
MPP_RET rc_init(RcCtx *ctx, MppCodingType type, const char **request_name);
MPP_RET rc_deinit(RcCtx ctx);
/* update rc control */

View File

@ -209,17 +209,22 @@ MPP_RET enc_impl_proc_hal(EncImpl impl, HalEncTask *task)
return ret;
}
MPP_RET enc_impl_add_prefix(EncImpl impl, HalEncTask *task)
MPP_RET enc_impl_add_prefix(EncImpl impl, MppPacket pkt, RK_S32 *length,
RK_U8 uuid[16], const void *data, RK_S32 size)
{
if (NULL == impl || NULL == task) {
if (NULL == pkt || NULL == data) {
mpp_err_f("found NULL input\n");
return MPP_ERR_NULL_PTR;
}
MPP_RET ret = MPP_OK;
EncImplCtx *p = (EncImplCtx *)impl;
if (NULL == p->api->add_prefix)
return ret;
if (p->api->add_prefix)
ret = p->api->add_prefix(p->ctx, task);
ret = p->api->add_prefix(pkt, length, uuid, data, size);
return ret;
}

View File

@ -17,10 +17,12 @@
#define MODULE_TAG "mpp_enc_v2"
#include <string.h>
#include <stdarg.h>
#include "mpp_env.h"
#include "mpp_log.h"
#include "mpp_mem.h"
#include "mpp_info.h"
#include "mpp_common.h"
#include "mpp_packet_impl.h"
@ -50,9 +52,8 @@ typedef union MppEncHeaderStatus_u {
typedef struct RcApiStatus_t {
RK_U32 rc_api_inited : 1;
RK_U32 rc_api_user_cfg : 1;
RK_U32 rc_api_updated : 1;
RK_U32 rc_cfg_updated : 1;
RK_U32 rc_api_user_cfg : 1;
} RcApiStatus;
typedef struct MppEncImpl_t {
@ -103,6 +104,14 @@ typedef struct MppEncImpl_t {
RK_U32 hdr_len;
MppEncHeaderStatus hdr_status;
MppEncHeaderMode hdr_mode;
/* information for debug prefix */
const char *version_info;
RK_S32 version_length;
char *rc_cfg_info;
RK_S32 rc_cfg_pos;
RK_S32 rc_cfg_length;
RK_S32 rc_cfg_size;
} MppEncImpl;
typedef union EncTaskWait_u {
@ -165,6 +174,21 @@ typedef struct EncTask_t {
HalTaskInfo info;
} EncTask;
static RK_U8 uuid_version[16] = {
0x3d, 0x07, 0x6d, 0x45, 0x73, 0x0f, 0x41, 0xa8,
0xb1, 0xc4, 0x25, 0xd7, 0x97, 0x6b, 0xf1, 0xac,
};
static RK_U8 uuid_rc_cfg[16] = {
0xd7, 0xdc, 0x03, 0xc3, 0xc5, 0x6f, 0x40, 0xe0,
0x8e, 0xa9, 0x17, 0x1a, 0xd2, 0xef, 0x5e, 0x23,
};
static RK_U8 uuid_usr_data[16] = {
0xfe, 0x39, 0xac, 0x4c, 0x4a, 0x8e, 0x4b, 0x4b,
0x85, 0xd9, 0xb2, 0xa2, 0x4f, 0xa1, 0x19, 0x5b,
};
static void reset_hal_enc_task(HalEncTask *task)
{
memset(task, 0, sizeof(*task));
@ -485,6 +509,24 @@ static const char *name_of_rc_mode[] = {
"fixqp",
};
static void update_rc_cfg_log(MppEncImpl *impl, const char* fmt, ...)
{
va_list args;
va_start(args, fmt);
RK_S32 size = impl->rc_cfg_size;
RK_S32 length = impl->rc_cfg_length;
char *base = impl->rc_cfg_info + length;
length += vsnprintf(base, size - length, fmt, args);
if (length >= size)
mpp_log_f("rc cfg log is full\n");
impl->rc_cfg_length = length;
va_end(args);
}
static void set_rc_cfg(RcCfg *cfg, MppEncCfgSet *cfg_set)
{
MppEncRcCfg *rc = &cfg_set->rc;
@ -646,7 +688,7 @@ void *mpp_enc_thread(void *data)
}
/* NOTE: default name is NULL */
ret = rc_init(&enc->rc_ctx, enc->coding, brief->name);
ret = rc_init(&enc->rc_ctx, enc->coding, &brief->name);
if (ret)
mpp_err("enc %p fail to init rc %s\n", enc, brief->name);
else
@ -654,6 +696,10 @@ void *mpp_enc_thread(void *data)
enc_dbg_detail("rc init %p name %s ret %d\n", enc->rc_ctx, brief->name, ret);
enc->rc_status.rc_api_updated = 0;
enc->rc_cfg_length = 0;
update_rc_cfg_log(enc, "%s:", brief->name);
enc->rc_cfg_pos = enc->rc_cfg_length;
}
// 4. check input task
@ -722,6 +768,16 @@ void *mpp_enc_thread(void *data)
enc_dbg_detail("rc update cfg done\n");
enc->rc_status.rc_api_user_cfg = 0;
enc->rc_cfg_length = enc->rc_cfg_pos;
update_rc_cfg_log(enc, "%s-b:%d[%d:%d]-g:%d-q:%d:[%d:%d]:[%d:%d]:%d\n",
name_of_rc_mode[usr_cfg.mode],
usr_cfg.bps_target,
usr_cfg.bps_min, usr_cfg.bps_max, usr_cfg.igop,
usr_cfg.init_quality,
usr_cfg.min_quality, usr_cfg.max_quality,
usr_cfg.min_i_quality, usr_cfg.max_i_quality,
usr_cfg.i_quality_delta);
}
// 8. all task ready start encoding one frame
@ -868,7 +924,43 @@ void *mpp_enc_thread(void *data)
}
/* 17. Add all prefix info before encoding */
RUN_ENC_IMPL_FUNC(enc_impl_add_prefix, impl, hal_task, mpp, ret);
if (frm->is_idr) {
RK_S32 length = 0;
enc_impl_add_prefix(impl, packet, &length, uuid_version,
enc->version_info, enc->version_length);
hal_task->sei_length += length;
hal_task->length += length;
length = 0;
enc_impl_add_prefix(impl, packet, &length, uuid_rc_cfg,
enc->rc_cfg_info, enc->rc_cfg_length);
hal_task->sei_length += length;
hal_task->length += length;
}
{
MppEncUserData *user_data = NULL;
MppMeta meta = mpp_frame_get_meta(frame);
mpp_meta_get_ptr(meta, KEY_USER_DATA, (void**)&user_data);
if (user_data) {
if (user_data->pdata && user_data->len) {
RK_S32 length = 0;
enc_impl_add_prefix(impl, packet, &length, uuid_usr_data,
user_data->pdata, user_data->len);
hal_task->sei_length += length;
hal_task->length += length;
} else
mpp_err_f("failed to insert user data %p len %d\n",
user_data->pdata, user_data->len);
}
}
// check for user data adding
if (hal_task->length != mpp_packet_get_length(packet)) {
@ -1028,6 +1120,10 @@ MPP_RET mpp_enc_init_v2(MppEnc *enc, MppEncInitCfg *cfg)
p->impl = impl;
p->enc_hal = enc_hal;
p->mpp = cfg->mpp;
p->version_info = get_mpp_version();
p->version_length = strlen(p->version_info);
p->rc_cfg_size = SZ_1K;
p->rc_cfg_info = mpp_calloc_size(char, p->rc_cfg_size);
{
// create header packet storage
@ -1086,6 +1182,10 @@ MPP_RET mpp_enc_deinit_v2(MppEnc ctx)
enc->refs = NULL;
}
MPP_FREE(enc->rc_cfg_info);
enc->rc_cfg_size = 0;
enc->rc_cfg_length = 0;
sem_destroy(&enc->enc_reset);
sem_destroy(&enc->enc_ctrl);

View File

@ -45,15 +45,18 @@ RK_U32 rc_debug = 0;
const static char default_rc_api[] = "default";
MPP_RET rc_init(RcCtx *ctx, MppCodingType type, const char *name)
MPP_RET rc_init(RcCtx *ctx, MppCodingType type, const char **request_name)
{
MPP_RET ret = MPP_NOK;
MppRcImpl *p = NULL;
const char *name = NULL;
mpp_env_get_u32("rc_debug", &rc_debug, 0);
if (NULL == name)
if (NULL == request_name || NULL == *request_name)
name = default_rc_api;
else
name = *request_name;
rc_dbg_func("enter type %x name %s\n", type, name);
@ -80,6 +83,8 @@ MPP_RET rc_init(RcCtx *ctx, MppCodingType type, const char *name)
}
*ctx = p;
if (request_name)
*request_name = name;
rc_dbg_func("leave %p\n", p);