diff --git a/mpp/codec/enc/h264/h264e_api_v2.c b/mpp/codec/enc/h264/h264e_api_v2.c index 404bc7b9..ee0aad3d 100644 --- a/mpp/codec/enc/h264/h264e_api_v2.c +++ b/mpp/codec/enc/h264/h264e_api_v2.c @@ -19,7 +19,6 @@ #include #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); } /*! diff --git a/mpp/codec/enc/h264/h264e_sei.c b/mpp/codec/enc/h264/h264e_sei.c index 2c267de1..ea53c177 100644 --- a/mpp/codec/enc/h264/h264e_sei.c +++ b/mpp/codec/enc/h264/h264e_sei.c @@ -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++) diff --git a/mpp/codec/enc/h264/h264e_sei.h b/mpp/codec/enc/h264/h264e_sei.h index 2f34129d..c0f84385 100644 --- a/mpp/codec/enc/h264/h264e_sei.h +++ b/mpp/codec/enc/h264/h264e_sei.h @@ -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 } diff --git a/mpp/codec/enc/h265/h265e_api_v2.c b/mpp/codec/enc/h265/h265e_api_v2.c index 87ad510c..18f2b588 100644 --- a/mpp/codec/enc/h265/h265e_api_v2.c +++ b/mpp/codec/enc/h265/h265e_api_v2.c @@ -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; diff --git a/mpp/codec/enc/h265/h265e_header_gen.c b/mpp/codec/enc/h265/h265e_header_gen.c index f8528add..abeba194 100644 --- a/mpp/codec/enc/h265/h265e_header_gen.c +++ b/mpp/codec/enc/h265/h265e_header_gen.c @@ -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); diff --git a/mpp/codec/enc/h265/h265e_header_gen.h b/mpp/codec/enc/h265/h265e_header_gen.h index d1af8a84..c41a4667 100644 --- a/mpp/codec/enc/h265/h265e_header_gen.h +++ b/mpp/codec/enc/h265/h265e_header_gen.h @@ -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); diff --git a/mpp/codec/inc/enc_impl_api.h b/mpp/codec/inc/enc_impl_api.h index 64a6f4e9..f7f123d3 100644 --- a/mpp/codec/inc/enc_impl_api.h +++ b/mpp/codec/inc/enc_impl_api.h @@ -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); diff --git a/mpp/codec/inc/mpp_enc_impl.h b/mpp/codec/inc/mpp_enc_impl.h index c66da29f..aa428d32 100644 --- a/mpp/codec/inc/mpp_enc_impl.h +++ b/mpp/codec/inc/mpp_enc_impl.h @@ -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 } diff --git a/mpp/codec/inc/rc.h b/mpp/codec/inc/rc.h index 86a8adfe..d9261da3 100644 --- a/mpp/codec/inc/rc.h +++ b/mpp/codec/inc/rc.h @@ -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 */ diff --git a/mpp/codec/mpp_enc_impl.cpp b/mpp/codec/mpp_enc_impl.cpp index d942185c..e9c974df 100644 --- a/mpp/codec/mpp_enc_impl.cpp +++ b/mpp/codec/mpp_enc_impl.cpp @@ -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; } diff --git a/mpp/codec/mpp_enc_v2.cpp b/mpp/codec/mpp_enc_v2.cpp index 5eece154..79ab460d 100644 --- a/mpp/codec/mpp_enc_v2.cpp +++ b/mpp/codec/mpp_enc_v2.cpp @@ -17,10 +17,12 @@ #define MODULE_TAG "mpp_enc_v2" #include +#include #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); diff --git a/mpp/codec/rc/rc.cpp b/mpp/codec/rc/rc.cpp index 223e4cf8..dc49c29f 100644 --- a/mpp/codec/rc/rc.cpp +++ b/mpp/codec/rc/rc.cpp @@ -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);