mirror of
https://github.com/nyanmisaka/mpp.git
synced 2025-10-06 09:36:49 +08:00
commit the avc encode code, now avc encode process is ok
git-svn-id: https://10.10.10.66:8443/svn/MediaProcessPlatform/trunk/mpp@1048 6e48237b-75ef-9749-8fc9-41990f28c85a
This commit is contained in:
@@ -71,6 +71,10 @@ endif()
|
||||
# System architecture detection
|
||||
# ----------------------------------------------------------------------------
|
||||
string(TOLOWER "${CMAKE_SYSTEM_PROCESSOR}" SYSPROC)
|
||||
if (ARMLINUX)
|
||||
set(SYSPROC "armv7-a")
|
||||
message(STATUS "CMAKE_SYSTEM_PROCESSOR=${SYSPROC}")
|
||||
endif()
|
||||
set(X86_ALIASES x86 i386 i686 x86_64 amd64)
|
||||
list(FIND X86_ALIASES "${SYSPROC}" X86MATCH)
|
||||
if("${SYSPROC}" STREQUAL "" OR X86MATCH GREATER "-1")
|
||||
@@ -172,8 +176,8 @@ if(GCC)
|
||||
if(ARM)
|
||||
if(ARMEABI_V6)
|
||||
add_definitions(-march=armv6 -mfloat-abi=hard -mfpu=vfp)
|
||||
elseif(ARMEABI_V7A)
|
||||
add_definitions(-march=armv7-a -mfloat-abi=softfp -mfpu=neon)
|
||||
# elseif(ARMEABI_V7A)
|
||||
# add_definitions(-march=armv7-a -mfloat-abi=softfp -mfpu=neon)
|
||||
endif()
|
||||
endif()
|
||||
# disable multichar warning
|
||||
|
@@ -82,6 +82,8 @@ typedef enum {
|
||||
MPP_DEC_GET_STREAM_COUNT,
|
||||
|
||||
MPP_ENC_CMD_BASE = 0x50000,
|
||||
MPP_ENC_SET_EXTRA_INFO,
|
||||
MPP_ENC_GET_EXTRA_INFO,
|
||||
MPP_ENC_SETCFG,
|
||||
MPP_ENC_GETCFG,
|
||||
MPP_ENC_SETFORMAT,
|
||||
@@ -201,7 +203,7 @@ typedef struct MppApi_t {
|
||||
// control interface
|
||||
MPP_RET (*reset)(MppCtx ctx);
|
||||
MPP_RET (*control)(MppCtx ctx, MpiCmd cmd, MppParam param);
|
||||
MPP_RET (*config)(MppCtx ctx, MppEncConfig cfg);
|
||||
MPP_RET (*config)(MppCtx ctx, MpiCmd cmd, MppEncConfig cfg);
|
||||
|
||||
RK_U32 reserv[16];
|
||||
} MppApi;
|
||||
@@ -227,6 +229,8 @@ MPP_RET mpp_destroy(MppCtx ctx);
|
||||
// coding type format function
|
||||
MPP_RET mpp_check_support_format(MppCtxType type, MppCodingType coding);
|
||||
void mpp_show_support_format();
|
||||
RK_U8 *mpp_enc_get_extra_data(MppCtx ctx);
|
||||
RK_U32 mpp_enc_get_extra_data_size(MppCtx ctx);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@@ -48,6 +48,7 @@ typedef enum {
|
||||
VPU_DEC_PP = 0x3,
|
||||
VPU_DEC_HEVC = 0x4,
|
||||
VPU_DEC_RKV = 0x5,
|
||||
VPU_ENC_RKV = 0x6,
|
||||
VPU_TYPE_BUTT ,
|
||||
|
||||
} VPU_CLIENT_TYPE;
|
||||
|
@@ -5,6 +5,7 @@
|
||||
# ----------------------------------------------------------------------------
|
||||
add_library(mpp_codec STATIC
|
||||
mpp_enc.cpp
|
||||
mpp_controller.cpp
|
||||
mpp_dec.cpp
|
||||
mpp_parser.cpp
|
||||
)
|
||||
@@ -23,6 +24,7 @@ target_link_libraries(mpp_codec
|
||||
codec_mpg4d
|
||||
codec_vp8d
|
||||
codec_vp9d
|
||||
codec_h264e
|
||||
codec_dummy_enc
|
||||
codec_dummy_dec
|
||||
mpp_base)
|
||||
|
@@ -2,4 +2,4 @@
|
||||
|
||||
add_subdirectory(dummy)
|
||||
|
||||
#add_subdirectory(h264)
|
||||
add_subdirectory(h264)
|
@@ -15,8 +15,6 @@ set(H264E_COMMON
|
||||
set(H264E_HDR
|
||||
include/basetype.h
|
||||
include/EncGetOption.h
|
||||
include/H264Cabac.h
|
||||
include/H264CabacContext.h
|
||||
include/H264CodeFrame.h
|
||||
include/H264Init.h
|
||||
include/H264Instance.h
|
||||
@@ -42,7 +40,6 @@ set(H264E_HDR
|
||||
# h264 encoder sourse
|
||||
set(H264E_SRC
|
||||
src/EncGetOption.c
|
||||
src/H264Cabac.c
|
||||
src/H264CodeFrame.c
|
||||
src/H264EncApi.c
|
||||
src/H264Init.c
|
||||
|
@@ -169,7 +169,6 @@ typedef struct {
|
||||
u32 riceEnable;
|
||||
u32 riceReadBase;
|
||||
u32 riceWriteBase;
|
||||
u32 cabacCtxBase;
|
||||
u32 colorConversionCoeffA;
|
||||
u32 colorConversionCoeffB;
|
||||
u32 colorConversionCoeffC;
|
||||
@@ -210,7 +209,6 @@ typedef struct {
|
||||
MppBufferGroup asicDataBufferGroup;
|
||||
MppBuffer internalImageLuma[2];
|
||||
MppBuffer internalImageChroma[2];
|
||||
MppBuffer cabacCtx;
|
||||
MppBuffer riceRead;
|
||||
MppBuffer riceWrite;
|
||||
u32 sizeTblSize;
|
||||
|
@@ -41,7 +41,6 @@
|
||||
#include "H264CodeFrame.h"
|
||||
#include "H264Sei.h"
|
||||
#include "H264RateControl.h"
|
||||
#include "H264Cabac.h"
|
||||
#define LOG_TAG "H264_ENC"
|
||||
//#include <utils/Log.h> // mask by lance 2016.05.05
|
||||
#ifdef INTERNAL_TEST
|
||||
@@ -1010,16 +1009,6 @@ H264EncRet H264EncStrmStart(H264EncInst inst, const H264EncIn * pEncIn,
|
||||
rc->virtualBuffer.bufferSize);
|
||||
}
|
||||
|
||||
/* Initialize cabac context tables for HW */
|
||||
if (pEncInst->picParameterSet.entropyCodingMode == ENCHW_YES) {
|
||||
// mask and add by lance 2016.05.05
|
||||
/*VPUMemInvalidate(&pEncInst->asic.cabacCtx);
|
||||
H264CabacInit(pEncInst->asic.cabacCtx.vir_addr,
|
||||
pEncInst->slice.cabacInitIdc);
|
||||
VPUMemClean(&pEncInst->asic.cabacCtx);*/
|
||||
H264CabacInit((u32*)(mpp_buffer_get_ptr(pEncInst->asic.cabacCtx)),
|
||||
pEncInst->slice.cabacInitIdc);
|
||||
}
|
||||
/* Use the first frame QP in the PPS */
|
||||
pEncInst->picParameterSet.picInitQpMinus26 = (i32) (rc->qpHdr) - 26;
|
||||
|
||||
|
@@ -150,7 +150,6 @@ i32 EncAsicControllerInit(asicData_s * asic)
|
||||
asic->internalImageChroma[0] = NULL; // modify by lance 2016.05.05
|
||||
asic->internalImageLuma[1] = NULL; // modify by lance 2016.05.05
|
||||
asic->internalImageChroma[1] = NULL;
|
||||
asic->cabacCtx = NULL;
|
||||
asic->riceRead = NULL;
|
||||
asic->riceWrite = NULL;
|
||||
|
||||
@@ -437,7 +436,6 @@ void EncAsicFrameStart(void * inst, /*const void *ewl, */regValues_s * val, h264
|
||||
|
||||
val->regMirror[80] = val->riceWriteBase;
|
||||
|
||||
val->regMirror[81] = val->cabacCtxBase;
|
||||
//roi1 area
|
||||
val->regMirror[82] = (val->roi1Top & 0xff) << 24;
|
||||
val->regMirror[82] |= (val->roi1Bottom & 0xff) << 16;
|
||||
@@ -609,7 +607,6 @@ void EncAsicFrameStart(void * inst, /*const void *ewl, */regValues_s * val, h264
|
||||
fprintf(valCompareFile, "val->constrainedIntraPrediction 0x%08X\n", val->constrainedIntraPrediction);
|
||||
fprintf(valCompareFile, "val->vsNextLumaBase 0x%08X\n", val->vsNextLumaBase);
|
||||
fprintf(valCompareFile, "val->riceWriteBase 0x%08X\n", val->riceWriteBase);
|
||||
fprintf(valCompareFile, "val->cabacCtxBase 0x%08X\n", val->cabacCtxBase);
|
||||
fprintf(valCompareFile, "val->roi1Top 0x%08X\n", val->roi1Top);
|
||||
fprintf(valCompareFile, "val->roi1Bottom 0x%08X\n", val->roi1Bottom);
|
||||
fprintf(valCompareFile, "val->roi1Left 0x%08X\n", val->roi1Left);
|
||||
@@ -682,7 +679,6 @@ void EncAsicFrameStart(void * inst, /*const void *ewl, */regValues_s * val, h264
|
||||
}
|
||||
syntax_data->output_strm_limit_size = val->outputStrmSize;
|
||||
syntax_data->output_strm_addr = val->outputStrmBase;
|
||||
syntax_data->cabac_table_addr = val->cabacCtxBase;
|
||||
syntax_data->pic_luma_width = instH264Encoder->preProcess.lumWidth;
|
||||
syntax_data->pic_luma_height = instH264Encoder->preProcess.lumHeight;
|
||||
syntax_data->ref_luma_addr = val->internalImageLumBaseR; // need to talk with kesheng by lance 2016.05.07
|
||||
|
@@ -177,21 +177,6 @@ i32 EncAsicMemAlloc_V2(asicData_s * asic, u32 width, u32 height,
|
||||
return ENCHW_NOK;
|
||||
}
|
||||
|
||||
/* CABAC context tables: all qps, intra+inter, 464 bytes/table */
|
||||
// mask and add by lance 2016.05.05
|
||||
/*if (VPUMallocLinear(&asic->cabacCtx, 52 * 2 * 464) != EWL_OK) {
|
||||
EncAsicMemFree_V2(asic);
|
||||
return ENCHW_NOK;
|
||||
}
|
||||
regs->cabacCtxBase = asic->cabacCtx.phy_addr;*/
|
||||
if (asic->cabacCtx == NULL) {
|
||||
if (mpp_buffer_get(asic->asicDataBufferGroup, &(asic->cabacCtx), (52 * 2 * 464)) != MPP_OK) {
|
||||
mpp_err("asic->cabacCtx alloc failed!\n");
|
||||
return ENCHW_NOK;
|
||||
}
|
||||
}
|
||||
regs->cabacCtxBase = mpp_buffer_get_fd(asic->cabacCtx);
|
||||
|
||||
// mask and add by lance 2016.05.05
|
||||
/*if (regs->riceEnable) {
|
||||
u32 bytes = ((width + 11) / 12 * (height * 2 - 1)) * 8;
|
||||
@@ -295,11 +280,6 @@ void EncAsicMemFree_V2(asicData_s * asic)
|
||||
asic->sizeTbl.nal = NULL;
|
||||
}
|
||||
|
||||
if (asic->cabacCtx != NULL) {
|
||||
mpp_buffer_put(asic->cabacCtx);
|
||||
asic->cabacCtx = NULL;
|
||||
}
|
||||
|
||||
if (asic->riceRead != NULL) {
|
||||
mpp_buffer_put(asic->riceRead);
|
||||
asic->riceRead = NULL;
|
||||
|
79
mpp/codec/inc/encoder_codec_api.h
Normal file
79
mpp/codec/inc/encoder_codec_api.h
Normal file
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright 2010 Rockchip Electronics S.LSI 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 __CONTROL_API_H__
|
||||
#define __CONTROL_API_H__
|
||||
|
||||
#include "rk_mpi.h"
|
||||
#include "mpp_buf_slot.h"
|
||||
#include "hal_task.h"
|
||||
|
||||
// TODO
|
||||
#include "../enc/h264/include/h264encapi.h"
|
||||
|
||||
// config cmd
|
||||
typedef enum EncCfgCmd_t {
|
||||
GET_OUTPUT_STREAM_SIZE,
|
||||
} EncCfgCmd;
|
||||
|
||||
/*
|
||||
* the reset wait for extension
|
||||
*/
|
||||
typedef struct EncControllerInitCfg_t {
|
||||
H264EncConfig encCfg;
|
||||
|
||||
// input
|
||||
MppCodingType coding;
|
||||
|
||||
// output
|
||||
RK_S32 task_count;
|
||||
IOInterruptCB notify_cb;
|
||||
} ControllerCfg;
|
||||
|
||||
/*
|
||||
* ControlApi is the data structure provided from different encoders
|
||||
*
|
||||
* They will be static register to mpp_enc for scaning
|
||||
* name - encoder name
|
||||
* coding - encoder coding type
|
||||
* ctx_size - encoder context size, mpp_dec will use this to malloc memory
|
||||
* flag - reserve
|
||||
*
|
||||
* init - encoder initialization function
|
||||
* deinit - encoder de-initialization function
|
||||
* encoder - encoder main working function, mpp_dec will input packet and get output syntax
|
||||
* reset - encoder reset function
|
||||
* flush - encoder output all frames
|
||||
* control - encoder configure function
|
||||
*/
|
||||
typedef struct ControlApi_t {
|
||||
char *name;
|
||||
MppCodingType coding;
|
||||
RK_U32 ctx_size;
|
||||
RK_U32 flag;
|
||||
|
||||
MPP_RET (*init)(void *ctx, ControllerCfg *ctrlCfg);
|
||||
MPP_RET (*deinit)(void *ctx);
|
||||
|
||||
MPP_RET (*encode)(void *ctx, /*HalEncTask **/void *task); // TODO
|
||||
|
||||
MPP_RET (*reset)(void *ctx);
|
||||
MPP_RET (*flush)(void *ctx);
|
||||
MPP_RET (*config)(void *ctx, RK_S32 cmd, void *param);
|
||||
MPP_RET (*callback)(void *ctx, void *feedback);
|
||||
} ControlApi;
|
||||
|
||||
#endif /*__CONTROL_API_H__*/
|
@@ -17,6 +17,24 @@
|
||||
#ifndef __H264E_API_H__
|
||||
#define __H264E_API_H__
|
||||
|
||||
#include "encoder_codec_api.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern const ControlApi api_h264e_controller;
|
||||
|
||||
MPP_RET h264e_init(void *ctx, ControllerCfg *ctrlCfg);
|
||||
MPP_RET h264e_deinit(void *ctx);
|
||||
MPP_RET h264e_encode(void *ctx, /*HalEncTask **/void *task);
|
||||
MPP_RET h264e_reset(void *ctx);
|
||||
MPP_RET h264e_flush(void *ctx);
|
||||
MPP_RET h264e_config(void *ctx, RK_S32 cmd, void *param);
|
||||
MPP_RET h264e_callback(void *ctx, void *feedback);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*__H264E_API_H__*/
|
85
mpp/codec/inc/mpp_controller.h
Normal file
85
mpp/codec/inc/mpp_controller.h
Normal file
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright 2010 Rockchip Electronics S.LSI 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 __ENCODER_CONTROLLER_API_H__
|
||||
#define __ENCODER_CONTROLLER_API_H__
|
||||
|
||||
#include "encoder_codec_api.h"
|
||||
|
||||
typedef void* Controller;
|
||||
|
||||
typedef union ControllerTaskWait_u {
|
||||
RK_U32 val;
|
||||
struct {
|
||||
RK_U32 task_hnd : 1;
|
||||
RK_U32 mpp_pkt_in : 1;
|
||||
RK_U32 enc_pkt_idx : 1;
|
||||
RK_U32 enc_pkt_buf : 1;
|
||||
RK_U32 prev_task : 1;
|
||||
RK_U32 info_change : 1;
|
||||
RK_U32 enc_pic_buf : 1;
|
||||
};
|
||||
} ControllerTaskWait;
|
||||
|
||||
typedef union EncTaskStatus_u {
|
||||
RK_U32 val;
|
||||
struct {
|
||||
RK_U32 task_hnd_rdy : 1;
|
||||
RK_U32 mpp_pkt_in_rdy : 1;
|
||||
RK_U32 enc_pkt_idx_rdy : 1;
|
||||
RK_U32 enc_pkt_buf_rdy : 1;
|
||||
RK_U32 task_valid_rdy : 1;
|
||||
RK_U32 enc_pkt_copy_rdy : 1;
|
||||
RK_U32 prev_task_rdy : 1;
|
||||
RK_U32 info_task_gen_rdy : 1;
|
||||
RK_U32 curr_task_rdy : 1;
|
||||
RK_U32 task_controled_rdy : 1;
|
||||
};
|
||||
} EncTaskStatus;
|
||||
|
||||
|
||||
typedef struct EncTask_t {
|
||||
HalTaskHnd hnd;
|
||||
|
||||
EncTaskStatus status;
|
||||
ControllerTaskWait wait;
|
||||
|
||||
RK_S32 hal_frm_idx_in;
|
||||
RK_S32 hal_pkt_idx_out;
|
||||
|
||||
MppBuffer ctrl_frm_buf_in;
|
||||
MppBuffer ctrl_pkt_buf_out;
|
||||
|
||||
h264e_syntax syntax_data;
|
||||
|
||||
HalTaskInfo info;
|
||||
} EncTask;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
MPP_RET controller_init(Controller *ctrller, ControllerCfg *cfg);
|
||||
MPP_RET controller_deinit(Controller ctrller);
|
||||
MPP_RET controller_encode(Controller ctrller, /*HalEncTask **/EncTask *task);
|
||||
MPP_RET controller_config(Controller ctrller, RK_S32 cmd, void *para);
|
||||
MPP_RET hal_enc_callback(void* ctrller, void *err_info);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*__ENCODER_CONTROLLER_API_H__*/
|
@@ -17,19 +17,28 @@
|
||||
#ifndef __MPP_ENC_H__
|
||||
#define __MPP_ENC_H__
|
||||
|
||||
#include "rk_mpi.h"
|
||||
#include "mpp_controller.h"
|
||||
#include "mpp_hal.h"
|
||||
|
||||
typedef struct MppEnc_t MppEnc;
|
||||
|
||||
struct MppEnc_t {
|
||||
MppCodingType coding;
|
||||
|
||||
Controller controller;
|
||||
MppHal hal;
|
||||
|
||||
// common resource
|
||||
MppBufSlots frame_slots;
|
||||
MppBufSlots packet_slots;
|
||||
HalTaskGroup tasks;
|
||||
|
||||
RK_U32 reset_flag;
|
||||
void *mpp;
|
||||
|
||||
H264EncConfig encCfg;
|
||||
h264e_control_extra_info_cfg extra_info_cfg;
|
||||
h264e_control_extra_info extra_info;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -42,10 +51,10 @@ extern "C" {
|
||||
void *mpp_enc_control_thread(void *data);
|
||||
void *mpp_enc_hal_thread(void *data);
|
||||
|
||||
|
||||
MPP_RET mpp_enc_init(MppEnc **enc, MppCodingType coding);
|
||||
MPP_RET mpp_enc_init(MppEnc *enc, MppCodingType coding);
|
||||
MPP_RET mpp_enc_deinit(MppEnc *enc);
|
||||
|
||||
MPP_RET mpp_enc_config(MppEnc *enc, MpiCmd cmd, void *param);
|
||||
MPP_RET mpp_enc_notify(void *ctx, void *info);
|
||||
MPP_RET mpp_enc_reset(MppEnc *enc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
133
mpp/codec/mpp_controller.cpp
Normal file
133
mpp/codec/mpp_controller.cpp
Normal file
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* Copyright 2010 Rockchip Electronics S.LSI 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.
|
||||
*/
|
||||
|
||||
#define MODULE_TAG "mpp_enc"
|
||||
|
||||
#include "mpp_mem.h"
|
||||
#include "mpp_log.h"
|
||||
#include "mpp_common.h"
|
||||
#include "h264e_api.h"
|
||||
#include "mpp_controller.h"
|
||||
|
||||
/*
|
||||
* all decoder static register here
|
||||
*/
|
||||
static const ControlApi *controllers[] = {
|
||||
&api_h264e_controller,
|
||||
};
|
||||
|
||||
typedef struct ControllerImpl_t {
|
||||
ControllerCfg cfg;
|
||||
const ControlApi *api;
|
||||
void *ctx;
|
||||
} ControllerImpl;
|
||||
|
||||
MPP_RET controller_encode(Controller ctrller, /*HalEncTask **/EncTask *task)
|
||||
{
|
||||
if (NULL == ctrller || NULL == task) {
|
||||
mpp_err_f("found NULL input\n");
|
||||
return MPP_ERR_NULL_PTR;
|
||||
}
|
||||
|
||||
ControllerImpl *p = (ControllerImpl *)ctrller;
|
||||
if (!p->api->encode)
|
||||
return MPP_OK;
|
||||
|
||||
return p->api->encode(p->ctx, (void*)task);
|
||||
}
|
||||
|
||||
MPP_RET controller_init(Controller *ctrl, ControllerCfg *cfg)
|
||||
{
|
||||
if (NULL == ctrl || NULL == cfg) {
|
||||
mpp_err_f("found NULL input controller %p config %p\n", ctrl, cfg);
|
||||
return MPP_ERR_NULL_PTR;
|
||||
}
|
||||
|
||||
*ctrl = NULL;
|
||||
|
||||
RK_U32 i;
|
||||
for (i = 0; i < MPP_ARRAY_ELEMS(controllers); i++) {
|
||||
const ControlApi *api = controllers[i];
|
||||
if (cfg->coding == api->coding) {
|
||||
ControllerImpl *p = mpp_calloc(ControllerImpl, 1);
|
||||
void *ctx = mpp_calloc_size(void, api->ctx_size);
|
||||
if (NULL == ctx || NULL == p) {
|
||||
mpp_err_f("failed to alloc parser context\n");
|
||||
mpp_free(p);
|
||||
mpp_free(ctx);
|
||||
return MPP_ERR_MALLOC;
|
||||
}
|
||||
|
||||
MPP_RET ret = api->init(ctx, cfg); // FIXME need to be thinked by lance 2016.05.18
|
||||
if (MPP_OK != ret) {
|
||||
mpp_err_f("failed to init controller\n");
|
||||
mpp_free(p);
|
||||
mpp_free(ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
p->cfg = *cfg;
|
||||
p->api = api;
|
||||
p->ctx = ctx;
|
||||
*ctrl = p;
|
||||
return MPP_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return MPP_NOK;
|
||||
}
|
||||
|
||||
MPP_RET controller_deinit(Controller ctrl)
|
||||
{
|
||||
if (NULL == ctrl) {
|
||||
mpp_err_f("found NULL input\n");
|
||||
return MPP_ERR_NULL_PTR;
|
||||
}
|
||||
|
||||
ControllerImpl *p = (ControllerImpl *)ctrl;
|
||||
if (p->api->deinit)
|
||||
p->api->deinit(p->ctx);
|
||||
|
||||
mpp_free(p->ctx);
|
||||
mpp_free(p);
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
MPP_RET hal_enc_callback(void *ctrller, void *err_info)
|
||||
{
|
||||
if (NULL == ctrller) {
|
||||
mpp_err_f("found NULL input\n");
|
||||
return MPP_ERR_NULL_PTR;
|
||||
}
|
||||
ControllerImpl *p = (ControllerImpl *)ctrller;
|
||||
if (!p->api->callback)
|
||||
return MPP_OK;
|
||||
return p->api->callback(p->ctx, err_info);
|
||||
}
|
||||
|
||||
MPP_RET controller_config(Controller ctrller, RK_S32 cmd, void *para)
|
||||
{
|
||||
if (NULL == ctrller) {
|
||||
mpp_err_f("found NULL input\n");
|
||||
return MPP_ERR_NULL_PTR;
|
||||
}
|
||||
|
||||
ControllerImpl *p = (ControllerImpl *)ctrller;
|
||||
if (!p->api->config)
|
||||
return MPP_OK;
|
||||
|
||||
return p->api->config(p->ctx, cmd, para);
|
||||
}
|
@@ -16,6 +16,8 @@
|
||||
|
||||
#define MODULE_TAG "mpp_enc"
|
||||
|
||||
#include "string.h"
|
||||
|
||||
#include "mpp_log.h"
|
||||
#include "mpp_mem.h"
|
||||
|
||||
@@ -24,45 +26,63 @@
|
||||
#include "mpp_frame_impl.h"
|
||||
#include "mpp_packet.h"
|
||||
#include "mpp_packet_impl.h"
|
||||
#include "hal_h264e_api.h"
|
||||
|
||||
void *mpp_enc_control_thread(void *data)
|
||||
{
|
||||
Mpp *mpp = (Mpp*)data;
|
||||
MppThread *thd_enc = mpp->mThreadCodec;
|
||||
EncTask task; // TODO
|
||||
HalTaskInfo task_info;
|
||||
MppPort input = mpp_task_queue_get_port(mpp->mInputTaskQueue, MPP_PORT_OUTPUT);
|
||||
MppPort output = mpp_task_queue_get_port(mpp->mOutputTaskQueue, MPP_PORT_INPUT);
|
||||
MppTask task = NULL;
|
||||
MppTask mpp_task = NULL;
|
||||
MPP_RET ret = MPP_OK;
|
||||
|
||||
memset(&task_info, 0, sizeof(HalTaskInfo));
|
||||
|
||||
while (MPP_THREAD_RUNNING == thd_enc->get_status()) {
|
||||
thd_enc->lock();
|
||||
ret = mpp_port_dequeue(input, &task);
|
||||
if (ret || NULL == task)
|
||||
ret = mpp_port_dequeue(input, &mpp_task);
|
||||
if (ret || NULL == mpp_task) {
|
||||
thd_enc->wait();
|
||||
}
|
||||
thd_enc->unlock();
|
||||
|
||||
if (task) {
|
||||
MppFrame frame = NULL;
|
||||
MppPacket packet = NULL;
|
||||
if (mpp_task != NULL) {
|
||||
MppFrame mpp_frame = NULL;
|
||||
MppPacket mpp_packet = NULL;
|
||||
// task process here
|
||||
|
||||
|
||||
// enqueue task back to input input
|
||||
mpp_task_meta_get_frame (task, MPP_META_KEY_INPUT_FRM, &frame);
|
||||
mpp_task_meta_get_packet(task, MPP_META_KEY_OUTPUT_PKT, &packet);
|
||||
mpp_task_meta_get_frame (mpp_task, MPP_META_KEY_INPUT_FRM, &mpp_frame);
|
||||
mpp_task_meta_get_packet(mpp_task, MPP_META_KEY_OUTPUT_PKT, &mpp_packet);
|
||||
|
||||
mpp_port_enqueue(input, task);
|
||||
task = NULL;
|
||||
mpp_port_enqueue(input, mpp_task);
|
||||
mpp_task = NULL;
|
||||
|
||||
memset(&task, 0, sizeof(EncTask));
|
||||
task.ctrl_frm_buf_in = mpp_frame_get_buffer(mpp_frame);
|
||||
task.ctrl_pkt_buf_out = mpp_packet_get_buffer(mpp_packet);
|
||||
controller_encode(mpp->mEnc->controller, &task);
|
||||
|
||||
task_info.enc.syntax.data = (void *)(&(task.syntax_data));
|
||||
mpp_hal_reg_gen((mpp->mEnc->hal), &task_info);
|
||||
mpp_hal_hw_start((mpp->mEnc->hal), &task_info);
|
||||
/*vpuWaitResult = */mpp_hal_hw_wait((mpp->mEnc->hal), &task_info); // TODO need to check the return value
|
||||
|
||||
|
||||
RK_U32 outputStreamSize = 0;
|
||||
controller_config(mpp->mEnc->controller, GET_OUTPUT_STREAM_SIZE, (void*)&outputStreamSize);
|
||||
|
||||
mpp_packet_set_length(mpp_packet, outputStreamSize);
|
||||
// send finished task to output port
|
||||
mpp_port_dequeue(output, &task);
|
||||
|
||||
mpp_task_meta_set_frame(task, MPP_META_KEY_INPUT_FRM, frame);
|
||||
mpp_task_meta_set_packet(task, MPP_META_KEY_OUTPUT_PKT, packet);
|
||||
|
||||
mpp_port_dequeue(output, &mpp_task);
|
||||
mpp_task_meta_set_frame(mpp_task, MPP_META_KEY_INPUT_FRM, mpp_frame);
|
||||
mpp_task_meta_set_packet(mpp_task, MPP_META_KEY_OUTPUT_PKT, mpp_packet);
|
||||
// setup output task here
|
||||
mpp_port_enqueue(output, task);
|
||||
task = NULL;
|
||||
mpp_port_enqueue(output, mpp_task);
|
||||
mpp_task = NULL;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
@@ -131,40 +151,107 @@ void *mpp_enc_hal_thread(void *data)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
MPP_RET mpp_enc_init(MppEnc **enc, MppCodingType coding)
|
||||
static MPP_RET mpp_extra_info_generate(h264e_control_extra_info_cfg *info, const H264EncConfig *encCfg)
|
||||
{
|
||||
MppEnc *p = mpp_calloc(MppEnc, 1);
|
||||
info->chroma_qp_index_offset = encCfg->chroma_qp_index_offset;
|
||||
info->enable_cabac = encCfg->enable_cabac;
|
||||
info->pic_init_qp = encCfg->pic_init_qp;
|
||||
info->pic_luma_height = encCfg->height;
|
||||
info->pic_luma_width = encCfg->width;
|
||||
info->transform8x8_mode = encCfg->transform8x8_mode;
|
||||
|
||||
info->input_image_format = encCfg->input_image_format;
|
||||
info->profile_idc = encCfg->profile;
|
||||
info->level_idc = encCfg->level;
|
||||
info->keyframe_max_interval = encCfg->keyframe_max_interval;
|
||||
info->second_chroma_qp_index_offset = encCfg->second_chroma_qp_index_offset;
|
||||
info->pps_id = encCfg->pps_id;
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
MPP_RET mpp_enc_init(MppEnc *enc, MppCodingType coding)
|
||||
{
|
||||
MPP_RET ret;
|
||||
MppBufSlots frame_slots = NULL;
|
||||
MppBufSlots packet_slots = NULL;
|
||||
Controller controller = NULL;
|
||||
MppHal hal = NULL;
|
||||
MppEnc *p = enc;
|
||||
RK_S32 task_count = 2;
|
||||
IOInterruptCB cb = {NULL, NULL};
|
||||
|
||||
if (NULL == p) {
|
||||
mpp_err_f("failed to malloc context\n");
|
||||
return MPP_ERR_NULL_PTR;
|
||||
}
|
||||
|
||||
MPP_RET ret = MPP_NOK;
|
||||
MppHal hal = NULL;
|
||||
do {
|
||||
ret = mpp_buf_slot_init(&frame_slots);
|
||||
if (ret) {
|
||||
mpp_err_f("could not init frame buffer slot\n");
|
||||
break;
|
||||
}
|
||||
|
||||
ret = mpp_buf_slot_init(&packet_slots);
|
||||
if (ret) {
|
||||
mpp_err_f("could not init packet buffer slot\n");
|
||||
break;
|
||||
}
|
||||
|
||||
mpp_buf_slot_setup(packet_slots, task_count);
|
||||
cb.callBack = mpp_enc_notify;
|
||||
cb.opaque = enc;
|
||||
|
||||
ControllerCfg controller_cfg = {
|
||||
enc->encCfg,
|
||||
coding,
|
||||
task_count,
|
||||
cb,
|
||||
};
|
||||
|
||||
ret = controller_init(&controller, &controller_cfg);
|
||||
if (ret) {
|
||||
mpp_err_f("could not init parser\n");
|
||||
break;
|
||||
}
|
||||
cb.callBack = hal_enc_callback;
|
||||
cb.opaque = controller;
|
||||
// then init hal with task count from parser
|
||||
MppHalCfg hal_cfg = {
|
||||
MPP_CTX_ENC,
|
||||
coding,
|
||||
HAL_MODE_LIBVPU,
|
||||
HAL_RKVDEC,
|
||||
HAL_VEPU,
|
||||
frame_slots,
|
||||
packet_slots,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
2,
|
||||
1/*controller_cfg.task_count*/, // TODO
|
||||
0,
|
||||
NULL,
|
||||
cb,
|
||||
};
|
||||
|
||||
ret = mpp_hal_init(&hal, &hal_cfg);
|
||||
if (ret) {
|
||||
mpp_err_f("could not init hal\n");
|
||||
break;
|
||||
}
|
||||
|
||||
mpp_extra_info_generate(&(enc->extra_info_cfg), &(enc->encCfg));
|
||||
mpp_hal_control(hal, MPP_ENC_SET_EXTRA_INFO, (void*)(&(enc->extra_info_cfg)));
|
||||
mpp_hal_control(hal, MPP_ENC_GET_EXTRA_INFO, (void*)(&(enc->extra_info)));
|
||||
|
||||
p->coding = coding;
|
||||
|
||||
*enc = p;
|
||||
|
||||
p->controller = controller;
|
||||
p->hal = hal;
|
||||
p->tasks = hal_cfg.tasks;
|
||||
p->frame_slots = frame_slots;
|
||||
p->packet_slots = packet_slots;
|
||||
return MPP_OK;
|
||||
} while (0);
|
||||
|
||||
mpp_enc_deinit(p);
|
||||
return MPP_NOK;
|
||||
|
||||
}
|
||||
|
||||
MPP_RET mpp_enc_deinit(MppEnc *enc)
|
||||
@@ -174,10 +261,26 @@ MPP_RET mpp_enc_deinit(MppEnc *enc)
|
||||
return MPP_ERR_NULL_PTR;
|
||||
}
|
||||
|
||||
MPP_RET ret = mpp_hal_deinit(enc->hal);
|
||||
if (ret) {
|
||||
mpp_err_f("mpp enc hal deinit failed\n");
|
||||
if (enc->controller) {
|
||||
controller_deinit(enc->controller);
|
||||
enc->controller = NULL;
|
||||
}
|
||||
|
||||
if (enc->hal) {
|
||||
mpp_hal_deinit(enc->hal);
|
||||
enc->hal = NULL;
|
||||
}
|
||||
|
||||
if (enc->frame_slots) {
|
||||
mpp_buf_slot_deinit(enc->frame_slots);
|
||||
enc->frame_slots = NULL;
|
||||
}
|
||||
|
||||
if (enc->packet_slots) {
|
||||
mpp_buf_slot_deinit(enc->packet_slots);
|
||||
enc->packet_slots = NULL;
|
||||
}
|
||||
|
||||
mpp_free(enc);
|
||||
return MPP_OK;
|
||||
}
|
||||
@@ -188,4 +291,69 @@ MPP_RET mpp_enc_reset(MppEnc *enc)
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
MPP_RET mpp_enc_notify(void *ctx, void *info)
|
||||
{
|
||||
// TODO
|
||||
(void)ctx;
|
||||
(void)info;
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
MPP_RET mpp_enc_config(MppEnc *enc, MpiCmd cmd, void *param)
|
||||
{
|
||||
if (NULL == enc) {
|
||||
mpp_err_f("found NULL input enc %p\n", enc);
|
||||
return MPP_ERR_NULL_PTR;
|
||||
}
|
||||
|
||||
// TODO
|
||||
MppEncConfig *mppCfg = (MppEncConfig*)param;
|
||||
H264EncConfig *encCfg = &(enc->encCfg);
|
||||
|
||||
switch (cmd) {
|
||||
case MPP_ENC_SETCFG:
|
||||
encCfg->streamType = H264ENC_BYTE_STREAM;//H264ENC_NAL_UNIT_STREAM; // decide whether stream start with start code,e.g."00 00 00 01"
|
||||
encCfg->frameRateDenom = 1;
|
||||
if (0 != mppCfg->profile)
|
||||
encCfg->profile = (h264e_profile)mppCfg->profile;
|
||||
else
|
||||
encCfg->profile = H264_PROFILE_BASELINE;
|
||||
if (0 != mppCfg->level)
|
||||
encCfg->level = (H264EncLevel)mppCfg->level;
|
||||
else
|
||||
encCfg->level = H264ENC_LEVEL_4_0;
|
||||
if (0 != mppCfg->width && 0 != mppCfg->height) {
|
||||
encCfg->width = mppCfg->width;
|
||||
encCfg->height = mppCfg->height;
|
||||
mpp_log("widthxheight %dx%d", encCfg->width, encCfg->height);
|
||||
} else
|
||||
mpp_err("Width or height is not set, width %d height %d", mppCfg->width, mppCfg->height);
|
||||
if (0 != mppCfg->fps_in)
|
||||
encCfg->frameRateNum = mppCfg->fps_in;
|
||||
else
|
||||
encCfg->frameRateNum = 30;
|
||||
if (mppCfg->gop > 0)
|
||||
encCfg->intraPicRate = mppCfg->gop;
|
||||
else
|
||||
encCfg->intraPicRate = 30;
|
||||
if (0 != mppCfg->cabac_en)
|
||||
encCfg->enable_cabac = mppCfg->cabac_en; // TODO
|
||||
else
|
||||
encCfg->enable_cabac = 0;
|
||||
if (0 != mppCfg->trans8x8_en)
|
||||
encCfg->transform8x8_mode = mppCfg->trans8x8_en; // TODO
|
||||
else
|
||||
encCfg->transform8x8_mode = 0;
|
||||
encCfg->chroma_qp_index_offset = 2; // TODO
|
||||
encCfg->pic_init_qp = 26; // TODO
|
||||
encCfg->keyframe_max_interval = 150; // TODO
|
||||
encCfg->second_chroma_qp_index_offset = 2; // TODO
|
||||
encCfg->pps_id = 0; // TODO
|
||||
encCfg->input_image_format = H264ENC_YUV420_SEMIPLANAR; // TODO
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return MPP_OK;
|
||||
}
|
||||
|
124
mpp/common/h264e_syntax.h
Normal file
124
mpp/common/h264e_syntax.h
Normal file
@@ -0,0 +1,124 @@
|
||||
#ifndef __H264E_SYNTAX_H__
|
||||
#define __H264E_SYNTAX_H__
|
||||
#include "rk_type.h"
|
||||
|
||||
#define H264_BIT_DEPTH 8
|
||||
#define H264_QP_BD_OFFSET (6*(H264_BIT_DEPTH-8))
|
||||
|
||||
typedef enum h264e_profile_t {
|
||||
H264_PROFILE_BASELINE = 66,
|
||||
H264_PROFILE_MAIN = 77,
|
||||
H264_PROFILE_HIGH = 100,
|
||||
H264_PROFILE_HIGH10 = 110,
|
||||
H264_PROFILE_HIGH422 = 122,
|
||||
H264_PROFILE_HIGH444_PREDICTIVE = 244,
|
||||
} h264e_profile;
|
||||
|
||||
typedef struct h264e_osd_pos_t {
|
||||
RK_U32 lt_pos_x : 8;
|
||||
RK_U32 lt_pos_y : 8;
|
||||
RK_U32 rd_pos_x : 8;
|
||||
RK_U32 rd_pos_y : 8;
|
||||
} h264e_osd_pos; //OSD_POS0-7
|
||||
|
||||
typedef struct h264e_syntax_t {
|
||||
RK_U32 frame_coding_type; //(VEPU)0: inter, 1: intra (RKVENC)RKVENC_FRAME_TYPE_*
|
||||
RK_U32 slice_type;
|
||||
RK_S32 pic_init_qp; //COMB, TODO: merge with swreg59.pic_init_qp
|
||||
RK_S32 slice_alpha_offset; //COMB TODO: merge with swreg62.sli_beta_ofst
|
||||
RK_S32 slice_beta_offset; //COMB TODO: merge with swreg62.sli_alph_ofst
|
||||
RK_S32 chroma_qp_index_offset; //COMB
|
||||
RK_S32 second_chroma_qp_index_offset; //TODO: may be removed later, get from sps/pps instead
|
||||
RK_S32 deblocking_filter_control; //COMB
|
||||
RK_S32 disable_deblocking_filter_idc;
|
||||
RK_S32 filter_disable; //TODO: merge width disable_deblocking_filter_idc above
|
||||
RK_U16 idr_pic_id; //COMB
|
||||
RK_S32 pps_id; //COMB TODO: merge with swreg60.pps_id //TODO: may be removed later, get from sps/pps instead
|
||||
RK_S32 frame_num; //COMB TODO: swreg60.frm_num
|
||||
RK_S32 slice_size_mb_rows;
|
||||
RK_S32 h264_inter4x4_disabled; //COMB
|
||||
RK_S32 enable_cabac; //COMB
|
||||
RK_S32 transform8x8_mode; //COMB
|
||||
RK_S32 cabac_init_idc; //COMB TODO: merge with swreg60.cbc_init_idc
|
||||
RK_S32 pic_order_cnt_lsb;
|
||||
|
||||
/* rate control relevant */
|
||||
RK_S32 qp;
|
||||
RK_S32 mad_qp_delta;
|
||||
RK_S32 mad_threshold;
|
||||
RK_S32 qp_min; //COMB, TODO: merge width swreg54.rc_min_qp
|
||||
RK_S32 qp_max; //COMB, TODO: merge width swreg54.rc_max_qp
|
||||
RK_S32 cp_distance_mbs;
|
||||
RK_S32 cp_target[10];
|
||||
RK_S32 target_error[7];
|
||||
RK_S32 delta_qp[7];
|
||||
|
||||
|
||||
RK_U32 output_strm_limit_size; // outputStrmSize
|
||||
RK_U32 output_strm_addr; // outputStrmBase
|
||||
RK_U32 pic_luma_width; // preProcess->lumWidth
|
||||
RK_U32 pic_luma_height; // preProcess->lumHeight
|
||||
RK_U32 input_luma_addr; // inputLumBase
|
||||
RK_U32 input_cb_addr; // inputCbBase
|
||||
RK_U32 input_cr_addr; // inputCrBase
|
||||
RK_U32 input_image_format; // inputImageFormat
|
||||
RK_U32 color_conversion_coeff_a; //colorConversionCoeffA
|
||||
RK_U32 color_conversion_coeff_b; //colorConversionCoeffB
|
||||
RK_U32 color_conversion_coeff_c; //colorConversionCoeffC
|
||||
RK_U32 color_conversion_coeff_e; //colorConversionCoeffE
|
||||
RK_U32 color_conversion_coeff_f; //colorConversionCoeffF
|
||||
RK_U32 color_conversion_r_mask_msb; //rMaskMsb
|
||||
RK_U32 color_conversion_g_mask_msb; //gMaskMsb
|
||||
RK_U32 color_conversion_b_mask_msb; //bMaskMsb
|
||||
|
||||
/* RKVENC extra syntax below */
|
||||
RK_S32 profile_idc; //TODO: may be removed later, get from sps/pps instead
|
||||
RK_S32 level_idc; //TODO: may be removed later, get from sps/pps instead
|
||||
RK_S32 link_table_en;
|
||||
RK_S32 keyframe_max_interval;
|
||||
|
||||
/* remove later */
|
||||
RK_U32 ref_luma_addr; // internalImageLumBaseR
|
||||
RK_U32 ref_chroma_addr; // internalImageChrBaseR
|
||||
RK_U32 recon_luma_addr; // internalImageLumBaseW
|
||||
RK_U32 recon_chroma_addr; // internalImageChrBaseW
|
||||
RK_U32 nal_size_table_addr; //
|
||||
} h264e_syntax;
|
||||
|
||||
typedef struct h264e_feedback_t {
|
||||
/* rc */
|
||||
RK_U32 hw_status;
|
||||
RK_S32 qp_sum;
|
||||
RK_S32 cp[10];
|
||||
RK_S32 mad_count;
|
||||
RK_S32 rlc_count;
|
||||
RK_U32 out_strm_size;
|
||||
} h264e_feedback;
|
||||
|
||||
|
||||
typedef struct h264e_control_extra_info_cfg_t {
|
||||
/* common cfg */
|
||||
RK_U32 pic_luma_width;
|
||||
RK_U32 pic_luma_height;
|
||||
RK_S32 enable_cabac;
|
||||
RK_S32 transform8x8_mode;
|
||||
RK_S32 chroma_qp_index_offset;
|
||||
RK_S32 pic_init_qp;
|
||||
//RK_S32 rotation_enable; //0: 0/180 degrees, 1: 90/270 degrees //TODO: add rotation
|
||||
|
||||
/* additional cfg only for rkv */
|
||||
RK_U32 input_image_format;
|
||||
RK_S32 profile_idc;
|
||||
RK_S32 level_idc; //TODO: may be removed later, get from sps/pps instead
|
||||
RK_S32 keyframe_max_interval;
|
||||
RK_S32 second_chroma_qp_index_offset;
|
||||
RK_S32 pps_id; //TODO: may be removed later, get from sps/pps instead
|
||||
} h264e_control_extra_info_cfg;
|
||||
|
||||
|
||||
typedef struct h264e_control_extra_info_t {
|
||||
RK_U32 size; // preProcess->lumWidth
|
||||
RK_U8 buf[256]; // preProcess->
|
||||
} h264e_control_extra_info;
|
||||
|
||||
#endif
|
@@ -30,6 +30,8 @@ add_subdirectory(vpu/mpg4d)
|
||||
|
||||
add_subdirectory(vpu/vp8d)
|
||||
|
||||
add_subdirectory(rkenc/h264e)
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# add hardware worker implement
|
||||
# ----------------------------------------------------------------------------
|
||||
@@ -50,6 +52,7 @@ target_link_libraries(mpp_hal
|
||||
hal_mpg4d
|
||||
hal_vp8d
|
||||
hal_vp9d
|
||||
hal_h264e
|
||||
hal_dummy
|
||||
${RKPLAT_VPU}
|
||||
)
|
||||
|
25
mpp/hal/inc/hal_h264e_api.h
Normal file
25
mpp/hal/inc/hal_h264e_api.h
Normal file
@@ -0,0 +1,25 @@
|
||||
#ifndef __HAL_H264E_API_H__
|
||||
#define __HAL_H264E_API_H__
|
||||
|
||||
#include "mpp_hal.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern const MppHalApi hal_api_h264e;
|
||||
|
||||
MPP_RET hal_h264e_init (void *hal, MppHalCfg *cfg);
|
||||
MPP_RET hal_h264e_deinit (void *hal);
|
||||
MPP_RET hal_h264e_gen_regs(void *hal, HalTaskInfo *task);
|
||||
MPP_RET hal_h264e_start (void *hal, HalTaskInfo *task);
|
||||
MPP_RET hal_h264e_wait (void *hal, HalTaskInfo *task);
|
||||
MPP_RET hal_h264e_reset (void *hal);
|
||||
MPP_RET hal_h264e_flush (void *hal);
|
||||
MPP_RET hal_h264e_control (void *hal, RK_S32 cmd_type, void *param);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@@ -31,6 +31,7 @@ typedef enum MppHalHardType_e {
|
||||
HAL_VDPU, //!< vpu combined decoder
|
||||
HAL_VEPU, //!< vpu combined encoder
|
||||
HAL_RKVDEC, //!< rock-chip h264 h265 vp9 combined decoder
|
||||
HAL_RKVENC, //!< rock-chip h264 h265 combined encoder
|
||||
HAL_DEVICE_BUTT,
|
||||
} HalDeviceId;
|
||||
|
||||
|
@@ -33,6 +33,7 @@
|
||||
#include "hal_m2vd_api.h"
|
||||
#include "hal_mpg4d_api.h"
|
||||
#include "hal_vp8d_api.h"
|
||||
#include "hal_h264e_api.h"
|
||||
|
||||
// for test and demo
|
||||
#include "hal_dummy_dec_api.h"
|
||||
@@ -50,6 +51,7 @@ static const MppHalApi *hw_apis[] = {
|
||||
&hal_api_mpg4d,
|
||||
&hal_api_vp8d,
|
||||
&hal_api_vp9d,
|
||||
&hal_api_h264e,
|
||||
&hal_api_dummy_dec,
|
||||
&hal_api_dummy_enc,
|
||||
};
|
||||
|
@@ -28,13 +28,11 @@ add_library(hal_h264e STATIC
|
||||
${HAL_H264E_SRC}
|
||||
)
|
||||
if(ANDROID)
|
||||
target_link_libraries(hal_h264e vpu mpp_base)
|
||||
target_link_libraries(hal_h264e worker_vpu mpp_base)
|
||||
else()
|
||||
target_link_libraries(hal_h264e mpp_base)
|
||||
endif()
|
||||
target_link_libraries(hal_h264e
|
||||
mpp
|
||||
)
|
||||
|
||||
set_target_properties(hal_h264e PROPERTIES FOLDER "mpp/hal")
|
||||
|
||||
add_subdirectory(test)
|
||||
|
@@ -348,7 +348,11 @@ RK_S32 vpu_close_context(VpuCodecContext **ctx)
|
||||
delete api;
|
||||
s->vpuApiObj = NULL;
|
||||
}
|
||||
mpp_free(s->extradata);
|
||||
//mpp_free(s->extradata); // TODO
|
||||
if (s->extradata_size > 0) { // TODO
|
||||
s->extradata_size = 0;
|
||||
s->extradata = NULL;
|
||||
}
|
||||
mpp_free(s->private_data);
|
||||
mpp_free(s);
|
||||
*ctx = s = NULL;
|
||||
|
@@ -30,7 +30,9 @@
|
||||
#define MAX_WRITE_HEIGHT (480)
|
||||
#define MAX_WRITE_WIDTH (960)
|
||||
|
||||
VpuApiLegacy::VpuApiLegacy()
|
||||
VpuApiLegacy::VpuApiLegacy() :
|
||||
use_fd_flag(0),
|
||||
task(NULL)
|
||||
{
|
||||
mpp_log_f("in\n");
|
||||
mpp_ctx = NULL;
|
||||
@@ -42,6 +44,7 @@ VpuApiLegacy::VpuApiLegacy()
|
||||
vpu_api_debug = 0;
|
||||
fp = NULL;
|
||||
fp_buf = NULL;
|
||||
outData = NULL;
|
||||
mpp_env_get_u32("vpu_api_debug", &vpu_api_debug, 0);
|
||||
if (vpu_api_debug & VPU_API_DBG_DUMP_YUV) {
|
||||
fp = fopen("/sdcard/rk_mpp_dump.yuv", "wb");
|
||||
@@ -62,6 +65,14 @@ VpuApiLegacy::~VpuApiLegacy()
|
||||
mpp_free(fp_buf);
|
||||
fp_buf = NULL;
|
||||
}
|
||||
if (memGroup != NULL) {
|
||||
mpp_err("memGroup deInit");
|
||||
mpp_buffer_group_put(memGroup);
|
||||
}
|
||||
if (outData != NULL) {
|
||||
free(outData);
|
||||
outData = NULL;
|
||||
}
|
||||
mpp_destroy(mpp_ctx);
|
||||
mpp_log_f("ok\n");
|
||||
}
|
||||
@@ -76,6 +87,27 @@ RK_S32 VpuApiLegacy::init(VpuCodecContext *ctx, RK_U8 *extraData, RK_U32 extra_s
|
||||
if (CODEC_DECODER == ctx->codecType) {
|
||||
type = MPP_CTX_DEC;
|
||||
} else if (CODEC_ENCODER == ctx->codecType) {
|
||||
memGroup = NULL;
|
||||
pictureMem = NULL;
|
||||
outbufMem = NULL;
|
||||
inputFrame = NULL;
|
||||
outputPakcet = NULL;
|
||||
if (memGroup == NULL) {
|
||||
ret = mpp_buffer_group_get_internal(&memGroup, MPP_BUFFER_TYPE_ION);
|
||||
if (MPP_OK != ret) {
|
||||
mpp_err("memGroup mpp_buffer_group_get failed\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
// TODO set control cmd
|
||||
MppParam param = NULL;
|
||||
RK_U32 output_block = 1;
|
||||
param = &output_block;
|
||||
ret = mpi->control(mpp_ctx, MPP_SET_OUTPUT_BLOCK, param);
|
||||
if (MPP_OK != ret) {
|
||||
mpp_err("mpi->control MPP_SET_OUTPUT_BLOCK failed\n");
|
||||
}
|
||||
|
||||
type = MPP_CTX_ENC;
|
||||
} else {
|
||||
return MPP_ERR_VPU_CODEC_INIT;
|
||||
@@ -85,16 +117,47 @@ RK_S32 VpuApiLegacy::init(VpuCodecContext *ctx, RK_U8 *extraData, RK_U32 extra_s
|
||||
mpp_err("found invalid context input");
|
||||
return MPP_ERR_NULL_PTR;
|
||||
}
|
||||
|
||||
if (MPP_CTX_ENC == type) {
|
||||
EncParameter_t *encParam = (EncParameter_t*)ctx->private_data;
|
||||
MppEncConfig encCfg;
|
||||
memset(&encCfg, 0, sizeof(MppEncConfig));
|
||||
// TODO
|
||||
if (0 != encParam->width && 0 != encParam->height) {
|
||||
encCfg.width = encParam->width;
|
||||
encCfg.height = encParam->height;
|
||||
} else
|
||||
mpp_err("Width and height is not set.");
|
||||
outData = (RK_U8*)malloc(encParam->width * encParam->height);
|
||||
if (0 != encParam->levelIdc)
|
||||
encCfg.level = encParam->levelIdc;
|
||||
if (0 != encParam->framerate)
|
||||
encCfg.fps_in = encParam->framerate;
|
||||
if (0 != encParam->framerateout)
|
||||
encCfg.fps_out = encParam->framerateout;
|
||||
else
|
||||
encCfg.fps_out = encParam->framerate;
|
||||
if (0 != encParam->intraPicRate)
|
||||
encCfg.gop = encParam->intraPicRate;
|
||||
mpi->config(mpp_ctx, MPP_ENC_SETCFG, encCfg); // input parameter config
|
||||
}
|
||||
ret = mpp_init(mpp_ctx, type, (MppCodingType)ctx->videoCoding);
|
||||
if (ret) {
|
||||
mpp_err_f(" init error. \n");
|
||||
return ret;
|
||||
}
|
||||
// TODO
|
||||
if (mpp_enc_get_extra_data_size(mpp_ctx) > 0) {
|
||||
ctx->extradata_size = mpp_enc_get_extra_data_size(mpp_ctx);
|
||||
ctx->extradata = mpp_enc_get_extra_data(mpp_ctx);
|
||||
mpp_log("Mpp generate extra data!");
|
||||
} else
|
||||
mpp_err("No extra data generate!");
|
||||
|
||||
VPU_GENERIC vpug;
|
||||
vpug.CodecType = ctx->codecType;
|
||||
vpug.ImgWidth = ctx->width;
|
||||
vpug.ImgHeight = ctx->height;
|
||||
if (MPP_CTX_ENC != type)
|
||||
control(ctx, VPU_API_SET_DEFAULT_WIDTH_HEIGH, &vpug);
|
||||
if (extraData != NULL) {
|
||||
mpp_packet_init(&pkt, extraData, extra_size);
|
||||
@@ -309,8 +372,8 @@ RK_S32 VpuApiLegacy:: decode_getoutframe(DecoderOut_t *aDecOut)
|
||||
|
||||
RK_S32 VpuApiLegacy::encode(VpuCodecContext *ctx, EncInputStream_t *aEncInStrm, EncoderOut_t *aEncOut)
|
||||
{
|
||||
MPP_RET ret = MPP_OK;
|
||||
mpp_log_f("in\n");
|
||||
RK_S32 ret = MPP_OK;
|
||||
|
||||
if (!init_ok) {
|
||||
return VPU_API_ERR_VPU_CODEC_INIT;
|
||||
@@ -319,8 +382,160 @@ RK_S32 VpuApiLegacy::encode(VpuCodecContext *ctx, EncInputStream_t *aEncInStrm,
|
||||
(void)ctx;
|
||||
(void)aEncInStrm;
|
||||
(void)aEncOut;
|
||||
// TODO
|
||||
if (1) {
|
||||
ret = mpp_frame_init(&inputFrame);
|
||||
if (MPP_OK != ret) {
|
||||
mpp_err("mpp_frame_init failed\n");
|
||||
goto ENCODE_FAIL;
|
||||
}
|
||||
RK_U32 width = ctx->width;
|
||||
RK_U32 height = ctx->height;
|
||||
RK_U32 horStride = MPP_ALIGN(width, 16);
|
||||
RK_U32 verStride = MPP_ALIGN(height, 16);
|
||||
mpp_frame_set_width(inputFrame, width);
|
||||
mpp_frame_set_height(inputFrame, height);
|
||||
mpp_frame_set_hor_stride(inputFrame, horStride);
|
||||
mpp_frame_set_ver_stride(inputFrame, verStride);
|
||||
|
||||
if (!use_fd_flag) {
|
||||
RK_U32 outputBufferSize = horStride * verStride;
|
||||
ret = mpp_buffer_get(memGroup, &pictureMem, aEncInStrm->size);
|
||||
if (ret != MPP_OK) {
|
||||
mpp_err( "Failed to allocate pictureMem buffer!\n");
|
||||
pictureMem = NULL;
|
||||
return ret;
|
||||
}
|
||||
memcpy((RK_U8*) mpp_buffer_get_ptr(pictureMem), aEncInStrm->buf, aEncInStrm->size);
|
||||
ret = mpp_buffer_get(memGroup, &outbufMem, outputBufferSize);
|
||||
if (ret != MPP_OK) {
|
||||
mpp_err( "Failed to allocate output buffer!\n");
|
||||
outbufMem = NULL;
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
MppBufferInfo inputCommit;
|
||||
MppBufferInfo outputCommit;
|
||||
memset(&inputCommit, 0, sizeof(inputCommit));
|
||||
memset(&outputCommit, 0, sizeof(outputCommit));
|
||||
inputCommit.type = MPP_BUFFER_TYPE_ION;
|
||||
inputCommit.size = aEncInStrm->size;
|
||||
inputCommit.fd = aEncInStrm->bufPhyAddr;
|
||||
outputCommit.type = MPP_BUFFER_TYPE_ION;
|
||||
outputCommit.size = horStride * verStride; // TODO
|
||||
outputCommit.fd = aEncOut->keyFrame/*bufferFd*/;
|
||||
outputCommit.ptr = (void*)aEncOut->data;
|
||||
mpp_log_f(" new ffmpeg provide fd input fd %d output fd %d", aEncInStrm->bufPhyAddr, aEncOut->keyFrame/*bufferFd*/);
|
||||
ret = mpp_buffer_import(&pictureMem, &inputCommit);
|
||||
if (MPP_OK != ret) {
|
||||
mpp_err("mpp_buffer_test mpp_buffer_commit failed\n");
|
||||
//goto ??; // TODO
|
||||
}
|
||||
|
||||
ret = mpp_buffer_import(&outbufMem, &outputCommit);
|
||||
if (MPP_OK != ret) {
|
||||
mpp_err("mpp_buffer_test mpp_buffer_commit failed\n");
|
||||
}
|
||||
mpp_log_f("mpp import input fd %d output fd %d",
|
||||
mpp_buffer_get_fd(pictureMem), mpp_buffer_get_fd(outbufMem)/*(((MppBufferImpl*)pictureMem)->info.fd), (((MppBufferImpl*)outbufMem)->info.fd)*/);
|
||||
}
|
||||
|
||||
//mpp_packet_init(&outputPakcet, outbufMem, aEncOut->size);
|
||||
mpp_frame_set_buffer(inputFrame, pictureMem);
|
||||
mpp_packet_init_with_buffer(&outputPakcet, outbufMem);
|
||||
|
||||
do {
|
||||
ret = mpi->dequeue(mpp_ctx, MPP_PORT_INPUT, &task);
|
||||
if (ret) {
|
||||
mpp_err("mpp task input dequeue failed\n");
|
||||
goto ENCODE_FAIL;
|
||||
}
|
||||
if (task == NULL) {
|
||||
mpp_log("mpi dequeue from MPP_PORT_INPUT fail, task equal with NULL!");
|
||||
usleep(3000);
|
||||
} else
|
||||
break;
|
||||
} while (1);
|
||||
|
||||
mpp_task_meta_set_frame (task, MPP_META_KEY_INPUT_FRM, inputFrame);
|
||||
mpp_task_meta_set_packet(task, MPP_META_KEY_OUTPUT_PKT, outputPakcet);
|
||||
|
||||
if (mpi != NULL) {
|
||||
ret = mpi->enqueue(mpp_ctx, MPP_PORT_INPUT, task);
|
||||
if (ret) {
|
||||
mpp_err("mpp task input enqueue failed\n");
|
||||
goto ENCODE_FAIL;
|
||||
}
|
||||
task = NULL;
|
||||
|
||||
do {
|
||||
ret = mpi->dequeue(mpp_ctx, MPP_PORT_OUTPUT, &task);
|
||||
if (ret) {
|
||||
mpp_err("ret %d mpp task output dequeue failed\n", ret);
|
||||
goto ENCODE_FAIL;
|
||||
}
|
||||
|
||||
if (task) {
|
||||
MppFrame frame_out = NULL;
|
||||
MppFrame packet_out = NULL;
|
||||
|
||||
mpp_task_meta_get_frame (task, MPP_META_KEY_INPUT_FRM, &frame_out);
|
||||
mpp_task_meta_get_packet(task, MPP_META_KEY_OUTPUT_PKT, &packet_out);
|
||||
|
||||
mpp_assert(packet_out == outputPakcet);
|
||||
mpp_assert(frame_out == inputFrame);
|
||||
mpp_log_f("encoded frame %d\n", frame_count);
|
||||
frame_count++;
|
||||
|
||||
ret = mpi->enqueue(mpp_ctx, MPP_PORT_OUTPUT, task);
|
||||
if (ret) {
|
||||
mpp_err("mpp task output enqueue failed\n");
|
||||
goto ENCODE_FAIL;
|
||||
}
|
||||
task = NULL;
|
||||
break;
|
||||
}
|
||||
usleep(3000);
|
||||
} while (1);
|
||||
} else {
|
||||
mpp_err("mpi pointer is NULL, failed!");
|
||||
}
|
||||
|
||||
// copy encoded stream into output buffer, and set outpub stream size
|
||||
if (outputPakcet != NULL) {
|
||||
aEncOut->size = mpp_packet_get_length(outputPakcet);
|
||||
if (!use_fd_flag)
|
||||
memcpy(aEncOut->data, (RK_U8*) mpp_buffer_get_ptr(outbufMem), aEncOut->size);
|
||||
mpp_buffer_put(outbufMem);
|
||||
mpp_packet_deinit(&outputPakcet);
|
||||
} else {
|
||||
mpp_log("outputPacket is NULL!");
|
||||
}
|
||||
|
||||
if (inputFrame) {
|
||||
mpp_frame_deinit(&inputFrame);
|
||||
inputFrame = NULL;
|
||||
}
|
||||
} else {
|
||||
aEncOut->data[0] = 0x00;
|
||||
aEncOut->data[1] = 0x00;
|
||||
aEncOut->data[2] = 0x00;
|
||||
aEncOut->data[3] = 0x01;
|
||||
memset(aEncOut->data + 4, 0xFF, 500 - 4);
|
||||
aEncOut->size = 500;
|
||||
}
|
||||
mpp_log_f("ok\n");
|
||||
return ret;
|
||||
|
||||
ENCODE_FAIL:
|
||||
|
||||
if (inputFrame != NULL)
|
||||
mpp_frame_deinit(&inputFrame);
|
||||
|
||||
if (outputPakcet != NULL)
|
||||
mpp_packet_deinit(&outputPakcet);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
RK_S32 VpuApiLegacy::encoder_sendframe(VpuCodecContext *ctx, EncInputStream_t *aEncInStrm)
|
||||
|
@@ -52,6 +52,14 @@ private:
|
||||
RK_U32 vpu_api_debug;
|
||||
FILE *fp;
|
||||
RK_U8 *fp_buf;
|
||||
MppBufferGroup memGroup;
|
||||
MppBuffer pictureMem;
|
||||
MppBuffer outbufMem;
|
||||
MppFrame inputFrame;
|
||||
MppPacket outputPakcet;
|
||||
RK_U8* outData;
|
||||
RK_U32 use_fd_flag;
|
||||
MppTask task;
|
||||
};
|
||||
|
||||
#endif /*_VPU_API_H_*/
|
||||
|
24
mpp/mpi.cpp
24
mpp/mpi.cpp
@@ -43,7 +43,7 @@ static MppCodingTypeInfo support_list[] = {
|
||||
{ MPP_CTX_DEC, MPP_VIDEO_CodingVP8, "dec", "vp8", },
|
||||
{ MPP_CTX_DEC, MPP_VIDEO_CodingVP9, "dec", "VP9", },
|
||||
{ MPP_CTX_DEC, MPP_VIDEO_CodingAVS, "dec", "avs+", },
|
||||
// { MPP_CTX_ENC, MPP_VIDEO_CodingAVC, "enc", "h.264/AVC", },
|
||||
{ MPP_CTX_ENC, MPP_VIDEO_CodingAVC, "enc", "h.264/AVC", },
|
||||
};
|
||||
|
||||
#define check_mpp_ctx(ctx) _check_mpp_ctx(ctx, __FUNCTION__)
|
||||
@@ -57,7 +57,7 @@ static MPP_RET _check_mpp_ctx(MpiImpl *p, const char *caller)
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
static MPP_RET mpi_config(MppCtx ctx, MppEncConfig cfg)
|
||||
static MPP_RET mpi_config(MppCtx ctx, MpiCmd cmd, MppEncConfig cfg)
|
||||
{
|
||||
MPP_RET ret = MPP_NOK;
|
||||
MpiImpl *p = (MpiImpl *)ctx;
|
||||
@@ -68,7 +68,7 @@ static MPP_RET mpi_config(MppCtx ctx, MppEncConfig cfg)
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
// TODO: do config here
|
||||
ret = p->ctx->config(cmd, cfg); // configure parameter set
|
||||
} while (0);
|
||||
|
||||
mpi_dbg_func("leave ret %d\n", ret);
|
||||
@@ -478,3 +478,21 @@ void mpp_show_support_format()
|
||||
}
|
||||
}
|
||||
|
||||
RK_U32 mpp_enc_get_extra_data_size(MppCtx ctx)
|
||||
{
|
||||
mpi_dbg_func("enter ctx %p\n", ctx);
|
||||
MpiImpl *p = (MpiImpl*)ctx;
|
||||
RK_U32 ret = p->ctx->mEnc->extra_info.size;
|
||||
mpi_dbg_func("leave\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
RK_U8 *mpp_enc_get_extra_data(MppCtx ctx)
|
||||
{
|
||||
mpi_dbg_func("enter ctx %p\n", ctx);
|
||||
MpiImpl *p = (MpiImpl*)ctx;
|
||||
RK_U8 *extra_data = p->ctx->mEnc->extra_info.buf;
|
||||
mpp_log("Mpp get extra data now!");
|
||||
mpi_dbg_func("leave\n");
|
||||
return extra_data;
|
||||
}
|
||||
|
34
mpp/mpp.cpp
34
mpp/mpp.cpp
@@ -101,9 +101,9 @@ MPP_RET Mpp::init(MppCtxType type, MppCodingType coding)
|
||||
mPackets = new mpp_list((node_destructor)mpp_packet_deinit);
|
||||
mTasks = new mpp_list((node_destructor)NULL);
|
||||
|
||||
mpp_enc_init(&mEnc, coding);
|
||||
mpp_enc_init(mEnc, coding);
|
||||
mThreadCodec = new MppThread(mpp_enc_control_thread, this, "mpp_enc_ctrl");
|
||||
mThreadHal = new MppThread(mpp_enc_hal_thread, this, "mpp_enc_hal");
|
||||
//mThreadHal = new MppThread(mpp_enc_hal_thread, this, "mpp_enc_hal");
|
||||
|
||||
mpp_buffer_group_get_internal(&mPacketGroup, MPP_BUFFER_TYPE_NORMAL);
|
||||
mpp_buffer_group_get_external(&mFrameGroup, MPP_BUFFER_TYPE_ION);
|
||||
@@ -122,12 +122,19 @@ MPP_RET Mpp::init(MppCtxType type, MppCodingType coding)
|
||||
mOutputPort = mpp_task_queue_get_port(mOutputTaskQueue, MPP_PORT_OUTPUT);
|
||||
|
||||
if (mFrames && mPackets &&
|
||||
(mDec || mEnc) &&
|
||||
(mDec) &&
|
||||
mThreadCodec && mThreadHal &&
|
||||
mPacketGroup) {
|
||||
mThreadCodec->start();
|
||||
mThreadHal->start();
|
||||
mInitDone = 1;
|
||||
} else if (mFrames && mPackets &&
|
||||
(mEnc) &&
|
||||
mThreadCodec/* && mThreadHal */ &&
|
||||
mPacketGroup) {
|
||||
mThreadCodec->start();
|
||||
//mThreadHal->start(); // TODO
|
||||
mInitDone = 1;
|
||||
} else {
|
||||
mpp_err("error found on mpp initialization\n");
|
||||
clear();
|
||||
@@ -420,6 +427,27 @@ MPP_RET Mpp::control(MpiCmd cmd, MppParam param)
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
MPP_RET Mpp::config(MpiCmd cmd, MppEncConfig cfg)
|
||||
{
|
||||
switch (cmd) {
|
||||
case MPP_ENC_SETCFG:
|
||||
mEnc = mpp_calloc(MppEnc, 1);
|
||||
if (NULL == mEnc) {
|
||||
mpp_err_f("failed to malloc context\n");
|
||||
return MPP_ERR_NULL_PTR;
|
||||
}
|
||||
mEnc->mpp = this; // TODO put these code into config function
|
||||
|
||||
mpp_enc_config(mEnc, cmd, &cfg);
|
||||
break;
|
||||
default:
|
||||
mpp_log("MpiCmd is not found in mpi_config.");
|
||||
break;
|
||||
}
|
||||
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
MPP_RET Mpp::reset()
|
||||
{
|
||||
if (!mInitDone)
|
||||
|
@@ -76,6 +76,7 @@ public:
|
||||
|
||||
MPP_RET reset();
|
||||
MPP_RET control(MpiCmd cmd, MppParam param);
|
||||
MPP_RET config(MpiCmd cmd, MppEncConfig cfg);
|
||||
|
||||
mpp_list *mPackets;
|
||||
mpp_list *mFrames;
|
||||
|
@@ -45,7 +45,8 @@ int pthread_setname_np(pthread_t thread, const char *name);
|
||||
#include <semaphore.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#if defined(ANDROID)
|
||||
#ifdef ARMLINUX
|
||||
#elif defined(ANDROID)
|
||||
#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP PTHREAD_RECURSIVE_MUTEX_INITIALIZER
|
||||
#endif
|
||||
|
||||
|
@@ -58,9 +58,11 @@ void MppThread::start()
|
||||
// NOTE: set status here first to avoid unexpected loop quit racing condition
|
||||
mStatus = MPP_THREAD_RUNNING;
|
||||
if (0 == pthread_create(&mThread, &attr, mFunction, mContext)) {
|
||||
#ifndef ARMLINUX
|
||||
RK_S32 ret = pthread_setname_np(mThread, mName);
|
||||
if (ret)
|
||||
mpp_err("thread %p setname %s failed\n", mFunction, mName);
|
||||
#endif
|
||||
|
||||
thread_dbg(MPP_THREAD_DBG_FUNCTION, "thread %s %p context %p create success\n",
|
||||
mName, mFunction, mContext);
|
||||
@@ -120,6 +122,7 @@ void SetThreadName(DWORD dwThreadID, const char* threadName)
|
||||
}
|
||||
|
||||
|
||||
#ifndef ARMLINUX
|
||||
/*
|
||||
* add pthread_setname_np for windows
|
||||
*/
|
||||
@@ -129,6 +132,7 @@ int pthread_setname_np(pthread_t thread, const char *name)
|
||||
SetThreadName(dwThreadID, name);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
@@ -192,7 +192,7 @@ int mpi_test()
|
||||
|
||||
memset(&cfg, 0, sizeof(cfg));
|
||||
|
||||
ret = mpi->config(ctx, cfg);
|
||||
ret = mpi->config(ctx, MPP_ENC_SETCFG, cfg);
|
||||
if (MPP_OK != ret) {
|
||||
mpp_err("mpi->config failed\n");
|
||||
goto MPP_TEST_FAILED;
|
||||
|
@@ -26,6 +26,8 @@
|
||||
#include "vpu_api.h"
|
||||
#include "utils.h"
|
||||
|
||||
#define FOR_TEST_ENCODE 1
|
||||
|
||||
static RK_U32 VPU_API_DEMO_DEBUG_DISABLE = 0;
|
||||
|
||||
#define BSWAP32(x) \
|
||||
@@ -241,6 +243,7 @@ static RK_S32 vpu_encode_demo(VpuApiDemoCmdContext_t *cmd)
|
||||
struct VpuCodecContext *ctx = NULL;
|
||||
RK_S32 nal = 0x00000001;
|
||||
RK_S32 fileSize, ret, size;
|
||||
RK_U32 readOneFrameSize = 0;
|
||||
EncoderOut_t enc_out_yuv;
|
||||
EncoderOut_t *enc_out = NULL;
|
||||
VpuApiEncInput enc_in_strm;
|
||||
@@ -251,7 +254,16 @@ static RK_S32 vpu_encode_demo(VpuApiDemoCmdContext_t *cmd)
|
||||
RK_U32 w_align = 0;
|
||||
RK_U32 h_align = 0;
|
||||
|
||||
int Format = VPU_H264ENC_YUV420_SEMIPLANAR;
|
||||
#ifdef FOR_TEST_ENCODE
|
||||
ctx = (struct VpuCodecContext*)malloc(sizeof(struct VpuCodecContext));
|
||||
if (!ctx) {
|
||||
mpp_err("Input context has not been properly allocated");
|
||||
return -1;
|
||||
}
|
||||
memset(ctx, 0, sizeof(struct VpuCodecContext));
|
||||
#endif
|
||||
|
||||
int Format = VPU_H264ENC_YUV420_PLANAR;//VPU_H264ENC_YUV420_SEMIPLANAR;
|
||||
|
||||
if (cmd == NULL) {
|
||||
return -1;
|
||||
@@ -288,6 +300,12 @@ static RK_S32 vpu_encode_demo(VpuApiDemoCmdContext_t *cmd)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef FOR_TEST_ENCODE
|
||||
ctx->videoCoding = OMX_RK_VIDEO_CodingAVC;
|
||||
ctx->codecType = CODEC_ENCODER;
|
||||
ctx->width = cmd->width;
|
||||
ctx->height = cmd->height;
|
||||
#endif
|
||||
fseek(pInFile, 0L, SEEK_END);
|
||||
fileSize = ftell(pInFile);
|
||||
fseek(pInFile, 0L, SEEK_SET);
|
||||
@@ -362,6 +380,8 @@ static RK_S32 vpu_encode_demo(VpuApiDemoCmdContext_t *cmd)
|
||||
w_align = ((ctx->width + 15) & (~15));
|
||||
h_align = ((ctx->height + 15) & (~15));
|
||||
size = w_align * h_align * 3 / 2;
|
||||
readOneFrameSize = ctx->width * ctx->height * 3 / 2;
|
||||
mpp_log("%d %d %d %d %d", ctx->width, ctx->height, w_align, h_align, size);
|
||||
nal = BSWAP32(nal);
|
||||
|
||||
do {
|
||||
@@ -387,7 +407,7 @@ static RK_S32 vpu_encode_demo(VpuApiDemoCmdContext_t *cmd)
|
||||
api_enc_in->capability = size;
|
||||
}
|
||||
|
||||
if (readBytesFromFile(enc_in->buf, size, pInFile)) {
|
||||
if (readBytesFromFile(enc_in->buf, readOneFrameSize, pInFile)) {
|
||||
break;
|
||||
} else {
|
||||
enc_in->size = size;
|
||||
@@ -402,6 +422,7 @@ static RK_S32 vpu_encode_demo(VpuApiDemoCmdContext_t *cmd)
|
||||
if ((ret = ctx->encode(ctx, enc_in, enc_out)) < 0) {
|
||||
ENCODE_ERR_RET(ERROR_VPU_DECODE);
|
||||
} else {
|
||||
enc_in->size = 0; // TODO encode completely, and set enc_in->size to 0
|
||||
mpp_log("vpu encode one frame, out len: %d, left size: %d\n",
|
||||
enc_out->size, enc_in->size);
|
||||
|
||||
@@ -413,7 +434,7 @@ static RK_S32 vpu_encode_demo(VpuApiDemoCmdContext_t *cmd)
|
||||
if (pOutFile) {
|
||||
mpp_log("dump %d bytes enc output stream to file\n",
|
||||
enc_out->size);
|
||||
fwrite((RK_U8*)&nal, 1, 4, pOutFile);
|
||||
//fwrite((RK_U8*)&nal, 1, 4, pOutFile); // because output stream have start code, so here mask this code
|
||||
fwrite(enc_out->data, 1, enc_out->size, pOutFile);
|
||||
fflush(pOutFile);
|
||||
}
|
||||
|
Reference in New Issue
Block a user