资料的位置
源代码在luckfox-pico/project/app/rkipc/rkipc/src/rv1106_ipc/video/video.c中,使用了rkmpi库,参考资料为"doc/zh/media/Rockchip_Developer_Guide_MPI.pdf"
通道设置设置
H265的通道设置主要由rkipc_pipe_0_init完成,之前要设置好isp,调用RK_MPI_SYS_Init()初始化好rkmpi系统
根据ini文件将参数填上
int rkipc_pipe_0_init() {
int ret;
//int video_width = rk_param_get_int("video.0:width", -1);
video_width = 1920;
//int video_height = rk_param_get_int("video.0:height", -1);
video_height = 1080;
//int buffer_line = rk_param_get_int("video.source:buffer_line", video_height / 4);
int buffer_line = 1080;
//int rotation = rk_param_get_int("video.source:rotation", 0);
int rotation = 180;
int buf_cnt = 2;
//int frame_min_i_qp = rk_param_get_int("video.0:frame_min_i_qp", 26);
int frame_min_i_qp = 26;
//int frame_min_qp = rk_param_get_int("video.0:frame_min_qp", 28);
int frame_min_qp = 28;
//int frame_max_i_qp = rk_param_get_int("video.0:frame_max_i_qp", 51);
int frame_max_i_qp = 51;
//int frame_max_qp = rk_param_get_int("video.0:frame_max_qp", 51);
int frame_max_qp = 51;
//int scalinglist = rk_param_get_int("video.0:scalinglist", 0);
int scalinglist = 0;
// VI
//VI输入通道
//输入通道的参数
VI_CHN_ATTR_S vi_chn_attr;
memset(&vi_chn_attr, 0, sizeof(vi_chn_attr));
//VI_ISP_OPT_S 获取图像为isp处理/直通数据的参数设置。
//RW;输出通道总的缓存块数。2
vi_chn_attr.stIspOpt.u32BufCount = buf_cnt;
//获取图像的V4L2内存类型。
vi_chn_attr.stIspOpt.enMemoryType = VI_V4L2_MEMORY_TYPE_DMABUF;
//ISP的最大宽度
//vi_chn_attr.stIspOpt.stMaxSize.u32Width = rk_param_get_int("video.0:max_width", 2560);
vi_chn_attr.stIspOpt.stMaxSize.u32Width = 1920;
//ISP的最大高度
//vi_chn_attr.stIspOpt.stMaxSize.u32Height = rk_param_get_int("video.0:max_height", 1440);
vi_chn_attr.stIspOpt.stMaxSize.u32Height = 1080;
//通道的宽度 1920
vi_chn_attr.stSize.u32Width = video_width;
//通道高度 1080
vi_chn_attr.stSize.u32Height = video_height;
//目标图像像素格式。
vi_chn_attr.enPixelFormat = RK_FMT_YUV420SP;
//用户获取图像的队列深度。取值范围:[0,8];0不能手动获取
vi_chn_attr.u32Depth = 0;
//目标图像压缩格式。无压缩
vi_chn_attr.enCompressMode = COMPRESS_MODE_NONE;
//设置VI通道
ret = RK_MPI_VI_SetChnAttr(pipe_id_, VIDEO_PIPE_0, &vi_chn_attr);
if (ret) {
LOG_ERROR("ERROR: create VI error! ret=%d\n", ret);
return ret;
}
//使能VI通道
ret = RK_MPI_VI_EnableChn(pipe_id_, VIDEO_PIPE_0);
if (ret) {
LOG_ERROR("ERROR: create VI error! ret=%d\n", ret);
return ret;
}
// VENC
//编码器
//编码器属性结构体
VENC_CHN_ATTR_S venc_chn_attr;
memset(&venc_chn_attr, 0, sizeof(venc_chn_attr));
//tmp_output_data_type = rk_param_get_string("video.0:output_data_type", NULL);
tmp_output_data_type = H.265;
//tmp_rc_mode = rk_param_get_string("video.0:rc_mode", NULL);
//恒定码率
tmp_rc_mode = CBR;
//tmp_h264_profile = rk_param_get_string("video.0:h264_profile", NULL);
tmp_h264_profile = high;
//tmp_rc_mode, tmp_output_data_type 必填
if ((tmp_output_data_type == NULL) || (tmp_rc_mode == NULL)) {
LOG_ERROR("tmp_output_data_type or tmp_rc_mode is NULL\n");
return -1;
}
LOG_DEBUG("tmp_output_data_type is %s, tmp_rc_mode is %s, tmp_h264_profile is %s\n",
tmp_output_data_type, tmp_rc_mode, tmp_h264_profile);
//h264模式的设置
if (!strcmp(tmp_output_data_type, "H.264")) {
//h264的格式 RK_VIDEO_ID_AVC
venc_chn_attr.stVencAttr.enType = RK_VIDEO_ID_AVC;
//图像级别,高100, 主77,基础66,其它的错误
if (!strcmp(tmp_h264_profile, "high"))
venc_chn_attr.stVencAttr.u32Profile = 100;
else if (!strcmp(tmp_h264_profile, "main"))
venc_chn_attr.stVencAttr.u32Profile = 77;
else if (!strcmp(tmp_h264_profile, "baseline"))
venc_chn_attr.stVencAttr.u32Profile = 66;
else
LOG_ERROR("tmp_h264_profile is %s\n", tmp_h264_profile);
//tmp_rc_mode CBR 码率控制为恒定码率
if (!strcmp(tmp_rc_mode, "CBR")) {
//码率控制
//模式恒定码率
venc_chn_attr.stRcAttr.enRcMode = VENC_RC_MODE_H264CBR;
//venc_chn_attr.stRcAttr.stH264Cbr.u32Gop = rk_param_get_int("video.0:gop", -1);
//I帧间隔
venc_chn_attr.stRcAttr.stH264Cbr.u32Gop = 50;
//venc_chn_attr.stRcAttr.stH264Cbr.u32BitRate = rk_param_get_int("video.0:max_rate", -1);
//平均 bitrate,以 kbps 为单位。
venc_chn_attr.stRcAttr.stH264Cbr.u32BitRate = 2048;
//venc_chn_attr.stRcAttr.stH264Cbr.fr32DstFrameRateDen = rk_param_get_int("video.0:dst_frame_rate_den", -1);
//输出帧率分母
venc_chn_attr.stRcAttr.stH264Cbr.fr32DstFrameRateDen = 25;
//venc_chn_attr.stRcAttr.stH264Cbr.fr32DstFrameRateNum = rk_param_get_int("video.0:dst_frame_rate_num", -1);
//输出帧率分子
venc_chn_attr.stRcAttr.stH264Cbr.fr32DstFrameRateNum = 1;
//venc_chn_attr.stRcAttr.stH264Cbr.u32SrcFrameRateDen = rk_param_get_int("video.0:src_frame_rate_den", -1);
//输入帧率分母
venc_chn_attr.stRcAttr.stH264Cbr.u32SrcFrameRateDen = 25;
//venc_chn_attr.stRcAttr.stH264Cbr.u32SrcFrameRateNum = rk_param_get_int("video.0:src_frame_rate_num", -1);
//输入帧率分子
venc_chn_attr.stRcAttr.stH264Cbr.u32SrcFrameRateNum = 1;
} else { //可变码率 多了最大码率和最小码率
venc_chn_attr.stRcAttr.enRcMode = VENC_RC_MODE_H264VBR;
venc_chn_attr.stRcAttr.stH264Vbr.u32Gop = rk_param_get_int("video.0:gop", -1);
venc_chn_attr.stRcAttr.stH264Vbr.u32BitRate = rk_param_get_int("video.0:mid_rate", -1);
venc_chn_attr.stRcAttr.stH264Vbr.u32MaxBitRate =
rk_param_get_int("video.0:max_rate", -1);
venc_chn_attr.stRcAttr.stH264Vbr.u32MinBitRate =
rk_param_get_int("video.0:min_rate", -1);
venc_chn_attr.stRcAttr.stH264Vbr.fr32DstFrameRateDen =
rk_param_get_int("video.0:dst_frame_rate_den", -1);
venc_chn_attr.stRcAttr.stH264Vbr.fr32DstFrameRateNum =
rk_param_get_int("video.0:dst_frame_rate_num", -1);
venc_chn_attr.stRcAttr.stH264Vbr.u32SrcFrameRateDen =
rk_param_get_int("video.0:src_frame_rate_den", -1);
venc_chn_attr.stRcAttr.stH264Vbr.u32SrcFrameRateNum =
rk_param_get_int("video.0:src_frame_rate_num", -1);
}
} else if (!strcmp(tmp_output_data_type, "H.265")) { //h265设置 和h264差不多
venc_chn_attr.stVencAttr.enType = RK_VIDEO_ID_HEVC;
if (!strcmp(tmp_rc_mode, "CBR")) {
venc_chn_attr.stRcAttr.enRcMode = VENC_RC_MODE_H265CBR;
venc_chn_attr.stRcAttr.stH265Cbr.u32Gop = rk_param_get_int("video.0:gop", -1);
venc_chn_attr.stRcAttr.stH265Cbr.u32BitRate = rk_param_get_int("video.0:max_rate", -1);
venc_chn_attr.stRcAttr.stH265Cbr.fr32DstFrameRateDen =
rk_param_get_int("video.0:dst_frame_rate_den", -1);
venc_chn_attr.stRcAttr.stH265Cbr.fr32DstFrameRateNum =
rk_param_get_int("video.0:dst_frame_rate_num", -1);
venc_chn_attr.stRcAttr.stH265Cbr.u32SrcFrameRateDen =
rk_param_get_int("video.0:src_frame_rate_den", -1);
venc_chn_attr.stRcAttr.stH265Cbr.u32SrcFrameRateNum =
rk_param_get_int("video.0:src_frame_rate_num", -1);
} else {
venc_chn_attr.stRcAttr.enRcMode = VENC_RC_MODE_H265VBR;
venc_chn_attr.stRcAttr.stH265Vbr.u32Gop = rk_param_get_int("video.0:gop", -1);
venc_chn_attr.stRcAttr.stH265Vbr.u32BitRate = rk_param_get_int("video.0:mid_rate", -1);
venc_chn_attr.stRcAttr.stH265Vbr.u32MaxBitRate =
rk_param_get_int("video.0:max_rate", -1);
venc_chn_attr.stRcAttr.stH265Vbr.u32MinBitRate =
rk_param_get_int("video.0:min_rate", -1);
venc_chn_attr.stRcAttr.stH265Vbr.fr32DstFrameRateDen =
rk_param_get_int("video.0:dst_frame_rate_den", -1);
venc_chn_attr.stRcAttr.stH265Vbr.fr32DstFrameRateNum =
rk_param_get_int("video.0:dst_frame_rate_num", -1);
venc_chn_attr.stRcAttr.stH265Vbr.u32SrcFrameRateDen =
rk_param_get_int("video.0:src_frame_rate_den", -1);
venc_chn_attr.stRcAttr.stH265Vbr.u32SrcFrameRateNum =
rk_param_get_int("video.0:src_frame_rate_num", -1);
}
} else { //不是h264, h265则错误格式
LOG_ERROR("tmp_output_data_type is %s, not support\n", tmp_output_data_type);
return -1;
}
//tmp_gop_mode = rk_param_get_string("video.0:gop_mode", NULL);
//P帧的设置,一般,智能
tmp_gop_mode = "normalP";
if (!strcmp(tmp_gop_mode, "normalP")) {
venc_chn_attr.stGopAttr.enGopMode = VENC_GOPMODE_NORMALP;
} else if (!strcmp(tmp_gop_mode, "smartP")) {
venc_chn_attr.stGopAttr.enGopMode = VENC_GOPMODE_SMARTP;
venc_chn_attr.stGopAttr.s32VirIdrLen = rk_param_get_int("video.0:smartp_viridrlen", 25);
venc_chn_attr.stGopAttr.u32MaxLtrCount = 1; // long-term reference frame ltr is fixed to 1
} else if (!strcmp(tmp_gop_mode, "TSVC4")) {
venc_chn_attr.stGopAttr.enGopMode = VENC_GOPMODE_TSVC4;
}
// venc_chn_attr.stGopAttr.u32GopSize = rk_param_get_int("video.0:gop", -1);
venc_chn_attr.stVencAttr.enPixelFormat = RK_FMT_YUV420SP;
venc_chn_attr.stVencAttr.u32MaxPicWidth = rk_param_get_int("video.0:max_width", 2560);
venc_chn_attr.stVencAttr.u32MaxPicHeight = rk_param_get_int("video.0:max_height", 1440);
venc_chn_attr.stVencAttr.u32PicWidth = video_width;
venc_chn_attr.stVencAttr.u32PicHeight = video_height;
venc_chn_attr.stVencAttr.u32VirWidth = video_width;
venc_chn_attr.stVencAttr.u32VirHeight = video_height;
venc_chn_attr.stVencAttr.u32StreamBufCnt = rk_param_get_int("video.0:buffer_count", 4);
venc_chn_attr.stVencAttr.u32BufSize = rk_param_get_int("video.0:buffer_size", 1843200);
// venc_chn_attr.stVencAttr.u32Depth = 1;
//创建ENC通道
ret = RK_MPI_VENC_CreateChn(VIDEO_PIPE_0, &venc_chn_attr);
if (ret) {
LOG_ERROR("ERROR: create VENC error! ret=%#x\n", ret);
return -1;
}
//智能编码,看文档,这里是close
tmp_smart = rk_param_get_string("video.0:smart", "close");
if (!strcmp(tmp_smart, "open"))
RK_MPI_VENC_EnableSvc(VIDEO_PIPE_0, 1);
//使能运动去模糊。这里为1 开启智能编码自动开启
if (rk_param_get_int("video.0:enable_motion_deblur", 0)) {
ret = RK_MPI_VENC_EnableMotionDeblur(VIDEO_PIPE_0, true);
if (ret)
LOG_ERROR("RK_MPI_VENC_EnableMotionDeblur error! ret=%#x\n", ret);
}
//静态开关,这里为1
if (rk_param_get_int("video.0:enable_motion_static_switch", 0)) {
ret = RK_MPI_VENC_EnableMotionStaticSwitch(VIDEO_PIPE_0, true);
if (ret)
LOG_ERROR("RK_MPI_VENC_EnableMotionStaticSwitch error! ret=%#x\n", ret);
}
//去除呼吸效应是否使能
VENC_DEBREATHEFFECT_S debfrath_effect;
memset(&debfrath_effect, 0, sizeof(VENC_DEBREATHEFFECT_S));
//这里为关
if (rk_param_get_int("video.0:enable_debreath_effect", 0)) {
debfrath_effect.bEnable = true;
debfrath_effect.s32Strength1 = rk_param_get_int("video.0:debreath_effect_strength", 16);
//设置呼吸效应
ret = RK_MPI_VENC_SetDeBreathEffect(VIDEO_PIPE_0, &debfrath_effect);
if (ret)
LOG_ERROR("RK_MPI_VENC_SetDeBreathEffect error! ret=%#x\n", ret);
}
// VENC_RC_PARAM_S h265_RcParam;
// RK_MPI_VENC_GetRcParam(VIDEO_PIPE_0, &h265_RcParam);
// h265_RcParam.s32FirstFrameStartQp = 26;
// h265_RcParam.stParamH265.u32StepQp = 8;
// h265_RcParam.stParamH265.u32MaxQp = 51;
// h265_RcParam.stParamH265.u32MinQp = 10;
// h265_RcParam.stParamH265.u32MaxIQp = 46;
// h265_RcParam.stParamH265.u32MinIQp = 24;
// h265_RcParam.stParamH265.s32DeltIpQp = -4;
// RK_MPI_VENC_SetRcParam(VIDEO_PIPE_0, &h265_RcParam);
tmp_rc_quality = rk_param_get_string("video.0:rc_quality", NULL);
VENC_RC_PARAM_S venc_rc_param;
RK_MPI_VENC_GetRcParam(VIDEO_PIPE_0, &venc_rc_param);
if (!strcmp(tmp_output_data_type, "H.264")) {
if (!strcmp(tmp_rc_quality, "highest")) {
venc_rc_param.stParamH264.u32MinQp = 10;
} else if (!strcmp(tmp_rc_quality, "higher")) {
venc_rc_param.stParamH264.u32MinQp = 15;
} else if (!strcmp(tmp_rc_quality, "high")) {
venc_rc_param.stParamH264.u32MinQp = 20;
} else if (!strcmp(tmp_rc_quality, "medium")) {
venc_rc_param.stParamH264.u32MinQp = 25;
} else if (!strcmp(tmp_rc_quality, "low")) {
venc_rc_param.stParamH264.u32MinQp = 30;
} else if (!strcmp(tmp_rc_quality, "lower")) {
venc_rc_param.stParamH264.u32MinQp = 35;
} else {
venc_rc_param.stParamH264.u32MinQp = 40;
}
venc_rc_param.stParamH264.u32FrmMinIQp = frame_min_i_qp;
venc_rc_param.stParamH264.u32FrmMinQp = frame_min_qp;
venc_rc_param.stParamH264.u32FrmMaxIQp = frame_max_i_qp;
venc_rc_param.stParamH264.u32FrmMaxQp = frame_max_qp;
} else if (!strcmp(tmp_output_data_type, "H.265")) {
if (!strcmp(tmp_rc_quality, "highest")) {
venc_rc_param.stParamH265.u32MinQp = 10;
} else if (!strcmp(tmp_rc_quality, "higher")) {
venc_rc_param.stParamH265.u32MinQp = 15;
} else if (!strcmp(tmp_rc_quality, "high")) {
venc_rc_param.stParamH265.u32MinQp = 20;
} else if (!strcmp(tmp_rc_quality, "medium")) {
venc_rc_param.stParamH265.u32MinQp = 25;
} else if (!strcmp(tmp_rc_quality, "low")) {
venc_rc_param.stParamH265.u32MinQp = 30;
} else if (!strcmp(tmp_rc_quality, "lower")) {
venc_rc_param.stParamH265.u32MinQp = 35;
} else {
venc_rc_param.stParamH265.u32MinQp = 40;
}
venc_rc_param.stParamH265.u32FrmMinIQp = frame_min_i_qp;
venc_rc_param.stParamH265.u32FrmMinQp = frame_min_qp;
venc_rc_param.stParamH265.u32FrmMaxIQp = frame_max_i_qp;
venc_rc_param.stParamH265.u32FrmMaxQp = frame_max_qp;
} else {
LOG_ERROR("tmp_output_data_type is %s, not support\n", tmp_output_data_type);
return -1;
}
//设置编码通道码率控制器的高级参数。 qp
RK_MPI_VENC_SetRcParam(VIDEO_PIPE_0, &venc_rc_param);
//设置H.264协议编码通道的变换、量化属性。
if (!strcmp(tmp_output_data_type, "H.264")) {
VENC_H264_TRANS_S pstH264Trans;
RK_MPI_VENC_GetH264Trans(VIDEO_PIPE_0, &pstH264Trans);
pstH264Trans.bScalingListValid = scalinglist;
RK_MPI_VENC_SetH264Trans(VIDEO_PIPE_0, &pstH264Trans);
} else if (!strcmp(tmp_output_data_type, "H.265")) {
VENC_H265_TRANS_S pstH265Trans;
RK_MPI_VENC_GetH265Trans(VIDEO_PIPE_0, &pstH265Trans);
pstH265Trans.bScalingListEnabled = scalinglist;
RK_MPI_VENC_SetH265Trans(VIDEO_PIPE_0, &pstH265Trans);
}
//设置编码通道参考帧共享属性。节省内存
VENC_CHN_REF_BUF_SHARE_S stVencChnRefBufShare;
memset(&stVencChnRefBufShare, 0, sizeof(VENC_CHN_REF_BUF_SHARE_S));
stVencChnRefBufShare.bEnable = rk_param_get_int("video.0:enable_refer_buffer_share", 0);
RK_MPI_VENC_SetChnRefBufShareAttr(VIDEO_PIPE_0, &stVencChnRefBufShare);
//旋转
if (rotation == 0) {
RK_MPI_VENC_SetChnRotation(VIDEO_PIPE_0, ROTATION_0);
} else if (rotation == 90) {
RK_MPI_VENC_SetChnRotation(VIDEO_PIPE_0, ROTATION_90);
} else if (rotation == 180) {
RK_MPI_VENC_SetChnRotation(VIDEO_PIPE_0, ROTATION_180);
} else if (rotation == 270) {
RK_MPI_VENC_SetChnRotation(VIDEO_PIPE_0, ROTATION_270);
}
//开始编码通道接收输入图像。
VENC_RECV_PIC_PARAM_S stRecvParam;
memset(&stRecvParam, 0, sizeof(VENC_RECV_PIC_PARAM_S));
//接收帧数,-1表示自动接收不停止
stRecvParam.s32RecvPicNum = -1;
RK_MPI_VENC_StartRecvFrame(VIDEO_PIPE_0, &stRecvParam);
//创建线程获取venc输出数据
pthread_create(&venc_thread_0, NULL, rkipc_get_venc_0, NULL);
// bind
vi_chn.enModId = RK_ID_VI;
vi_chn.s32DevId = 0;
vi_chn.s32ChnId = VIDEO_PIPE_0;
venc_chn.enModId = RK_ID_VENC;
venc_chn.s32DevId = 0;
venc_chn.s32ChnId = VIDEO_PIPE_0;
//vi绑定venc
ret = RK_MPI_SYS_Bind(&vi_chn, &venc_chn);
if (ret)
LOG_ERROR("Bind VI and VENC error! ret=%#x\n", ret);
else
LOG_DEBUG("Bind VI and VENC success\n");
return 0;
}
获取venc0的数据
static void *rkipc_get_venc_0(void *arg) {
LOG_DEBUG("#Start %s thread, arg:%p\n", __func__, arg);
prctl(PR_SET_NAME, "RkipcVenc0", 0, 0, 0);
/*
typedef struct rkVENC_STREAM_S {
VENC_PACK_S ATTRIBUTE* pstPack; //帧码流包结构。
RK_U32 ATTRIBUTE u32PackCount; //一帧码流的所有包的个数。
RK_U32 u32Seq; //码流序列号。按帧获取帧序号;按包获取包序号。
//码流特征信息。
union {
VENC_STREAM_INFO_H264_S stH264Info;
VENC_STREAM_INFO_JPEG_S stJpegInfo;
VENC_STREAM_INFO_H265_S stH265Info;
VENC_STREAM_INFO_PRORES_S stProresInfo;
};
//码流高级特征信息。
union {
VENC_STREAM_ADVANCE_INFO_H264_S stAdvanceH264Info;
VENC_STREAM_ADVANCE_INFO_JPEG_S stAdvanceJpegInfo;
VENC_STREAM_ADVANCE_INFO_H265_S stAdvanceH265Info;
VENC_STREAM_ADVANCE_INFO_PRORES_S stAdvanceProresInfo;
};
} VENC_STREAM_S;
typedef struct rkVENC_PACK_S {
MB_BLK pMbBlk; //码流包缓存块句柄。
RK_U32 u32Len; //码流包长度。
RK_U64 u64PTS; //时间戳。单位:us。
RK_BOOL bFrameEnd; //帧结束标识。取值范围:RK_TRUE:该码流包是该帧的最后一个包RK_FALSE:该码流包不是该帧的最后一个包。
RK_BOOL bStreamEnd; //流结束标识。取值范围:RK_TRUE:该码流包是数据流的最后一个包,编码器将输出编码图像最后一帧码流。RK_FALSE:该码流包不是数据流的最后一个包。
VENC_DATA_TYPE_U DataType; //码流类型,支持 H.264/JPEG/ H.265 协议类型的数据包。
RK_U32 u32Offset; //没用
RK_U32 u32DataNum; //没用
VENC_PACK_INFO_S stPackInfo[8]; //没用
} VENC_PACK_S;
DataType
typedef enum rkH264E_NALU_TYPE_E {
H264E_NALU_BSLICE = 0,
H264E_NALU_PSLICE = 1,
H264E_NALU_ISLICE = 2,
H264E_NALU_IDRSLICE = 5,
H264E_NALU_SEI = 6,
H264E_NALU_SPS = 7,
H264E_NALU_PPS = 8,
H264E_NALU_BUTT
} H264E_NALU_TYPE_E;
*/
VENC_STREAM_S stFrame;
VI_CHN_STATUS_S stChnStatus;
int loopCount = 0;
int ret = 0;
// FILE *fp = fopen("/data/venc.h265", "wb");
stFrame.pstPack = malloc(sizeof(VENC_PACK_S));
while (g_video_run_) {
// 5.get the frame
//获取数据
ret = RK_MPI_VENC_GetStream(VIDEO_PIPE_0, &stFrame, 1000);
if (ret == RK_SUCCESS) {
//获取内存地址
void *data = RK_MPI_MB_Handle2VirAddr(stFrame.pstPack->pMbBlk);
// fwrite(data, 1, stFrame.pstPack->u32Len, fp);
// fflush(fp);
// LOG_DEBUG("Count:%d, Len:%d, PTS is %" PRId64", enH264EType is %d\n", loopCount,
// stFrame.pstPack->u32Len, stFrame.pstPack->u64PTS,
// stFrame.pstPack->DataType.enH264EType);
//发送数据
if (g_rtsplive && g_rtsp_session_0) {
pthread_mutex_lock(&g_rtsp_mutex);
rtsp_tx_video(g_rtsp_session_0, data, stFrame.pstPack->u32Len,
stFrame.pstPack->u64PTS);
rtsp_do_event(g_rtsplive);
pthread_mutex_unlock(&g_rtsp_mutex);
}
if ((stFrame.pstPack->DataType.enH264EType == H264E_NALU_IDRSLICE) ||
(stFrame.pstPack->DataType.enH264EType == H264E_NALU_ISLICE) ||
(stFrame.pstPack->DataType.enH265EType == H265E_NALU_IDRSLICE) ||
(stFrame.pstPack->DataType.enH265EType == H265E_NALU_ISLICE)) {
rk_storage_write_video_frame(0, data, stFrame.pstPack->u32Len,
stFrame.pstPack->u64PTS, 1);
if (enable_rtmp)
rk_rtmp_write_video_frame(0, data, stFrame.pstPack->u32Len,
stFrame.pstPack->u64PTS, 1);
} else {
rk_storage_write_video_frame(0, data, stFrame.pstPack->u32Len,
stFrame.pstPack->u64PTS, 0);
if (enable_rtmp)
rk_rtmp_write_video_frame(0, data, stFrame.pstPack->u32Len,
stFrame.pstPack->u64PTS, 0);
}
// 7.release the frame
ret = RK_MPI_VENC_ReleaseStream(VIDEO_PIPE_0, &stFrame);
if (ret != RK_SUCCESS) {
LOG_ERROR("RK_MPI_VENC_ReleaseStream fail %x\n", ret);
}
loopCount++;
} else {
LOG_ERROR("RK_MPI_VENC_GetStream timeout %x\n", ret);
}
}
if (stFrame.pstPack)
free(stFrame.pstPack);
// if (fp)
// fclose(fp);
return 0;
}