你好
使用core-1126-JD4+配套底板开发时,遇到流媒体推流问题,麻烦看下,谢谢
现象:
在使用core-1126-JD4推流时,用VLC能够打开流媒体,但是流媒体卡在第一张画面上,后面视频看不到
硬件接线:
1、使用一路网口接海康网络摄影头
2、使用另一路网口推流
软件流程:
1、获取rtsp流(使用ffrtsp库)->decode->encode->rtsp推流
测试log:
[root@RV1126_RV1109:/userdata/data/wdg]# ./rtsp_vdec_rga_venc
./rtsp_vdec_rga_venc: /lib/libstdc++.so.6: no version information available (required by /usr/lib/libffrtsp.so)
./rtsp_vdec_rga_venc: /lib/libstdc++.so.6: no version information available (required by /usr/lib/libffrtsp.so)
./rtsp_vdec_rga_venc: /lib/libstdc++.so.6: no version information available (required by /usr/lib/libffrtsp.so)
./rtsp_vdec_rga_venc: /lib/libstdc++.so.6: no version information available (required by /usr/lib/libarcsoft_face_engine.so)
./rtsp_vdec_rga_venc: /lib/libstdc++.so.6: no version information available (required by /usr/lib/libarcsoft_face_engine.so)
./rtsp_vdec_rga_venc: /lib/libstdc++.so.6: no version information available (required by /usr/lib/libarcsoft_face_engine.so)
./rtsp_vdec_rga_venc: /lib/libstdc++.so.6: no version information available (required by /usr/lib/libarcsoft_face_engine.so)
./rtsp_vdec_rga_venc: /lib/libstdc++.so.6: no version information available (required by /usr/lib/libarcsoft_face.so)
./rtsp_vdec_rga_venc: /lib/libstdc++.so.6: no version information available (required by /usr/lib/libarcsoft_face.so)
./rtsp_vdec_rga_venc: /lib/libstdc++.so.6: no version information available (required by /usr/lib/libarcsoft_face.so)
./rtsp_vdec_rga_venc: /lib/libstdc++.so.6: no version information available (required by /usr/lib/libarcsoft_face.so)
./rtsp_vdec_rga_venc: /lib/libstdc++.so.6: no version information available (required by /usr/lib/libarcsoft_face.so)
media get entity by name: rkcif-lvds-subdev is null
media get entity by name: rkcif-lite-lvds-subdev is null
media get entity by name: rkisp-mpfbc-subdev is null
media get entity by name: rkisp_dmapath is null
media get entity by name: rockchip-mipi-dphy-rx is null
Rga built version:1.04 cb973b1+2021-06-01 11:34:20
[INFO rtsp_demo.c:281:rtsp_new_demo] rtsp server demo starting on port 8554
[DEBUG rtsp_demo.c:481:rtsp_new_session] add session path: /live/main_stream
##RKMEDIA Log level: 2
[RKMEDIA][SYS][Info]:text is all=2
[RKMEDIA][SYS][Info]:module is all, log_level is 2
[RKMEDIA][SYS][Info]:RK_MPI_VDEC_CreateChn: Enable VDEC[0] Start...
mpp[2248]: mpp_info: mpp version: 92a7c2a4 author: daijh 2021-04-21 debian: fix patch not found bug
[RKMEDIA][VDEC][Info]:mpi control MPP_DEC_SET_PARSER_SPLIT_MODE ret = 0
mpp[2248]: mpp_rt: NOT found ion allocator
mpp[2248]: mpp_rt: found drm allocator
[RKMEDIA][VDEC][Info]:mpi set group limit = 16
[RKMEDIA][SYS][Info]:RK_MPI_VDEC_CreateChn: Enable VDEC[0] End!
[RKMEDIA][SYS][Info]:RK_MPI_VENC_CreateChn: Enable VENC[0], Type:6 Start...
mpp[2248]: mpp_info: mpp version: 92a7c2a4 author: daijh 2021-04-21 debian: fix patch not found bug
[RKMEDIA][VENC][Info]:MPP Encoder: MPPConfig: cfg init sucess!
[RKMEDIA][VENC][Info]:MPP Encoder: qpMaxi use default value:48
[RKMEDIA][VENC][Info]:MPP Encoder: qpMini use default value:8
[RKMEDIA][VENC][Info]:MPP Encoder: qpMax use default value:48
[RKMEDIA][VENC][Info]:MPP Encoder: qpMin use default value:8
[RKMEDIA][VENC][Info]:MPP Encoder: qpInit use default value:-1
[RKMEDIA][VENC][Info]:MPP Encoder: qpStep use default value:2
[RKMEDIA][VENC][Info]:MPP Encoder: rotaion = 0
[RKMEDIA][VENC][Info]:MPP Encoder: automatically calculate bsp with bps_max
[RKMEDIA][VENC][Info]:MPP Encoder: Set output block mode.
[RKMEDIA][VENC][Info]:MPP Encoder: Set input block mode.
[RKMEDIA][VENC][Info]:MPP Encoder: bps:[4147200,3732480,1036800] fps: [25/1]->[25/1], gop:25 qpInit:-1, qpMin:8, qpMax:48, qpMinI:8, qpMaxI:48.
[RKMEDIA][VENC][Info]:MPP Encoder: H264 profile use defalut value: 100[RKMEDIA][VENC][Info]:MPP Encoder: AVC: encode profile 100 level 0
mpp[2248]: mpp_enc: MPP_ENC_SET_RC_CFG bps 3732480 [1036800 : 4147200] fps [25:25] gop 25
mpp[2248]: h264e_api_v2: MPP_ENC_SET_PREP_CFG w:h [1920:1080] stride [1920:1088]
mpp[2248]: mpp_enc: send header for set cfg change input/format
[RKMEDIA][VENC][Info]:MPP Encoder: w x h(1920[1920] x 1080[1088])
mpp[2248]: mpp_enc: mode cbr bps [1036800:3732480:4147200] fps fix [25/1] -> fix [25/1] gop i [25] v [0]
[RKMEDIA][SYS][Info]:RK_MPI_VENC_CreateChn: Enable VENC[0], Type:6 End...
[RKMEDIA][SYS][Info]:RK_MPI_RGA_CreateChn: Enable RGA[0], Rect<0,0,1920,1080> Start...
[RKMEDIA][SYS][Info]:FilterFlow:rkrga: Enable BufferPool! memtype:hw_mem, memcnt:12
[RKMEDIA][SYS][Info]:Opened DRM device /dev/dri/card0: driver rockchip version 2.0.0.
[RKMEDIA][SYS][Info]:RK_MPI_RGA_CreateChn: Enable RGA[0], Rect<0,0,1920,1080> End...
[RKMEDIA][SYS][Info]:RK_MPI_SYS_Bind: Bind Mode[VDEC]:Chn[0] to Mode[RGA]:Chn[0]...
[RKMEDIA][SYS][Info]:RK_MPI_SYS_Bind: Bind Mode[VDEC]:Chn[0] to Mode[VENC]:Chn[0]...
Created new TCP socket 41 for connection
Connecting to 192.168.1.5, port 554 on socket 41...
...remote connection opened
Sending request: DESCRIBE rtsp://admin:zd123456@192.168.1.5 RTSP/1.0
CSeq: 2
User-Agent: ffrtspGet (LIVE555 Streaming Media v2017.10.28)
Accept: application/sdp
Received 184 new bytes of response data.
Received a complete DESCRIBE response:
RTSP/1.0 401 Unauthorized
CSeq: 2
WWW-Authenticate: Digest realm="IP Camera(F3061)", nonce="cdad57661c65aa2e1ea2d78f3351752a", stale="FALSE"
Date: Mon, Dec 06 2021 22:04:14 GMT
Resending...
Sending request: DESCRIBE rtsp://admin:zd123456@192.168.1.5 RTSP/1.0
CSeq: 3
Authorization: Digest username="admin", realm="IP Camera(F3061)", nonce="cdad57661c65aa2e1ea2d78f3351752a", uri="rtsp://admin:zd123456@192.168.1.5", response="6d2d88caa84c04e93e30b7cbf7ee7c25"
User-Agent: ffrtspGet (LIVE555 Streaming Media v2017.10.28)
Accept: application/sdp
Received 702 new bytes of response data.
Received a complete DESCRIBE response:
RTSP/1.0 200 OK
CSeq: 3
Content-Type: application/sdp
Content-Base: rtsp://admin:zd123456@192.168.1.5/
Content-Length: 572
v=0
o=- 1638828254932574 1638828254932574 IN IP4 192.168.1.5
s=Media Presentation
e=NONE
b=AS:5050
t=0 0
a=control:rtsp://admin:zd123456@192.168.1.5/
m=video 0 RTP/AVP 96
c=IN IP4 0.0.0.0
b=AS:5000
a=recvonly
a=x-dimensions:1920,1080
a=control:rtsp://admin:zd123456@192.168.1.5/trackID=1
a=rtpmap:96 H264/90000
a=fmtp:96 profile-level-id=420029; packetization-mode=1; sprop-parameter-sets=Z00AKpY1QPAET8s3AQEBQAABwgAAV+QB,aO4xsg==
a=Media_header:MEDIAINFO=494D4B48010300000400000100000000000000000000000000000000000000000000000000000000;
a=appversion:1.0
[URL:"rtsp://admin:zd123456@192.168.1.5/"]: Got a SDP description:
v=0
o=- 1638828254932574 1638828254932574 IN IP4 192.168.1.5
s=Media Presentation
e=NONE
b=AS:5050
t=0 0
a=control:rtsp://admin:zd123456@192.168.1.5/
m=video 0 RTP/AVP 96
c=IN IP4 0.0.0.0
b=AS:5000
a=recvonly
a=x-dimensions:1920,1080
a=control:rtsp://admin:zd123456@192.168.1.5/trackID=1
a=rtpmap:96 H264/90000
a=fmtp:96 profile-level-id=420029; packetization-mode=1; sprop-parameter-sets=Z00AKpY1QPAET8s3AQEBQAABwgAAV+QB,aO4xsg==
a=Media_header:MEDIAINFO=494D4B48010300000400000100000000000000000000000000000000000000000000000000000000;
a=appversion:1.0
[URL:"rtsp://admin:zd123456@192.168.1.5/"]: Initiated the "video/H264" subsession (client ports 36746-36747)
Sending request: SETUP rtsp://admin:zd123456@192.168.1.5/trackID=1 RTSP/1.0
CSeq: 4
Authorization: Digest username="admin", realm="IP Camera(F3061)", nonce="cdad57661c65aa2e1ea2d78f3351752a", uri="rtsp://admin:zd123456@192.168.1.5/", response="10c4a1dfcdf2b5c1651238c954e703d1"
User-Agent: ffrtspGet (LIVE555 Streaming Media v2017.10.28)
Transport: RTP/AVP;unicast;client_port=36746-36747
Received 204 new bytes of response data.
Received a complete SETUP response:
RTSP/1.0 200 OK
CSeq: 4
Session: 1383322580;timeout=60
Transport: RTP/AVP;unicast;client_port=36746-36747;server_port=8218-8219;ssrc=32cb7432;mode="play"
Date: Mon, Dec 06 2021 22:04:14 GMT
[URL:"rtsp://admin:zd123456@192.168.1.5/"]: Set up the "video/H264" subsession (client ports 36746-36747)
[URL:"rtsp://admin:zd123456@192.168.1.5/"]: Created a data sink for the "video/H264" subsession
Sending request: PLAY rtsp://admin:zd123456@192.168.1.5/ RTSP/1.0
CSeq: 5
Authorization: Digest username="admin", realm="IP Camera(F3061)", nonce="cdad57661c65aa2e1ea2d78f3351752a", uri="rtsp://admin:zd123456@192.168.1.5/", response="35c213136d0091d0a2f465b9d6650e24"
User-Agent: ffrtspGet (LIVE555 Streaming Media v2017.10.28)
Session: 1383322580
Range: npt=0.000-
Received 179 new bytes of response data.
Received a complete PLAY response:
RTSP/1.0 200 OK
CSeq: 5
Session: 1383322580
RTP-Info: url=rtsp://admin:zd123456@192.168.1.5/trackID=1;seq=1629;rtptime=190893420
Date: Mon, Dec 06 2021 22:04:15 GMT
[URL:"rtsp://admin:zd123456@192.168.1.5/"]: Started playing session...
[RKMEDIA][VDEC][Info]:MppDec Info change get, 1920x1080 in (1920x1088)
[RKMEDIA][RGA][Error]:Src(0Bytes) or Dst(6220800Bytes) Buffer is invalid!
mpp[2248]: mpp_buffer: mpp_buffer_put invalid input: buffer NULL from PrepareMppFrame
mpp[2248]: h264e_sps: set level to 4
[DEBUG utils.c:160:rtsp_codec_data_parse_from_user_h264] sps 27
[DEBUG utils.c:168:rtsp_codec_data_parse_from_user_h264] pps 4
测试代码:
#include <assert.h>
#include <fcntl.h>
#include <pthread.h>
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <sys/time.h>
#include "common/sample_common.h"
#include "rkmedia_api.h"
#include "rkmedia_vdec.h"
#include "ffrtsp/ffrtsp.hh"
#include "librtsp/rtsp_demo.h"
#define full_flow1
#define close_mux1
//视频流处理pipeline
//rtsp->vdec->rga->im2gray->算法处理(测试RGA直接转IMAGE_TYPE_GRAY8)->处理结果添加水印->venc->rtsp推流
// ->venc->保存历史视频(mux测试)
// ->venc->添加水印—>rtsp流(后期流程)
typedef struct rkMuxerHandle {
RK_U32 u32ModeIdx;
RK_U32 u32ChnIdx;
} MuxerHandle;
rtsp_demo_handle g_rtsplive = NULL;
static rtsp_session_handle g_rtsp_session;
static bool quit = false;
static void sigterm_handler(int sig) {
fprintf(stderr, "signal %d\n", sig);
quit = true;
}
static long getCurrentTimeMsec() {
long msec = 0;
char str[20] = {0};
struct timeval stuCurrentTime;
gettimeofday(&stuCurrentTime, NULL);
sprintf(str, "%ld%03ld", stuCurrentTime.tv_sec,(stuCurrentTime.tv_usec) / 1000);
for (size_t i = 0; i < strlen(str); i++) {
msec = msec * 10 + (str[i] - '0');
}
return msec;
}
static RK_U32 gu32FileIdx;
int GetRecordFileName(RK_VOID *pHandle, RK_U32 u32FileCnt,RK_CHAR **pcFileName) {
printf("#%s: Handle:%p, idx:%u ...\n", __func__, pHandle, *((RK_U32 *)pHandle));
for (RK_U32 i = 0; i < u32FileCnt; i++) {
sprintf(pcFileName[i], "/userdata/MuxerCbTest_%u.mp4",*((RK_U32 *)pHandle));
}
printf("#%s: NewRecordFileName:[%s]\n", __func__, pcFileName[0]);
*((RK_U32 *)pHandle) = *((RK_U32 *)pHandle) + 1;
return 0;
}
void muxer_event_cb(RK_VOID *pHandle, RK_VOID *pstEvent) {
RK_S32 s32ModeIdx = -1;
RK_S32 s32ChnIdx = -1;
printf("### %s: Handle:%p, event:%p\n", __func__, pHandle, pstEvent);
if (pHandle) {
MuxerHandle *pstMuxerHandle = (MuxerHandle *)pHandle;
s32ModeIdx = (RK_S32)pstMuxerHandle->u32ModeIdx;
s32ChnIdx = (RK_S32)pstMuxerHandle->u32ChnIdx;
}
if (pstEvent) {
MUXER_EVENT_INFO_S *pstMuxerEvent = (MUXER_EVENT_INFO_S *)pstEvent;
printf("@@@ %s: ModeID:%d, ChnID:%d, EventType:%d, filename:%s, value:%d\n",
__func__, s32ModeIdx, s32ChnIdx, pstMuxerEvent->enEvent,
pstMuxerEvent->unEventInfo.stFileInfo.asFileName,
(int)pstMuxerEvent->unEventInfo.stFileInfo.u32Duration);
}
}
int FFRKMedia_Vdec_Send(u_int8_t* framebuff,unsigned framesize,bool * pquit,int cur_chn)
{
//RTSP流数据送到decode通道
MEDIA_BUFFER mb = RK_MPI_MB_CreateBuffer(framesize, RK_FALSE, 0);
RK_MPI_MB_SetSize(mb, framesize);
memcpy(RK_MPI_MB_GetPtr(mb) ,framebuff , framesize);
RK_MPI_MB_SetSize(mb, framesize);
RK_MPI_SYS_SendMediaBuffer(RK_ID_VDEC, 0, mb);
RK_MPI_MB_ReleaseBuffer(mb);
if (quit)
*pquit = true;
}
void vdec_packet_cb(MEDIA_BUFFER mb) {
// decode 流媒体数据为NV12
int ret;
static RK_U32 jpeg_id = 0;
MB_IMAGE_INFO_S stImageInfo = {0};
ret = RK_MPI_MB_GetImageInfo(mb, &stImageInfo);//指定图像中获取图像信息 ,宽高,图片格式
if (ret) {
printf("Get image info failed! ret = %d\n", ret);
RK_MPI_MB_ReleaseBuffer(mb);
return ;
}
printf("Get Frame:ptr:%p, fd:%d, size:%zu, mode:%d, channel:%d, "
"timestamp:%lld, ImgInfo:<wxh %dx%d, fmt 0x%x>\n",
RK_MPI_MB_GetPtr(mb), RK_MPI_MB_GetFD(mb), RK_MPI_MB_GetSize(mb),
RK_MPI_MB_GetModeID(mb), RK_MPI_MB_GetChannelID(mb),
RK_MPI_MB_GetTimestamp(mb), stImageInfo.u32Width,
stImageInfo.u32Height, stImageInfo.enImgType);
/* char jpeg_path[128];
sprintf(jpeg_path, "/userdata/data/test_yuv%d.yuv", jpeg_id);
FILE *file = fopen(jpeg_path, "w");
if (file) {
fwrite(RK_MPI_MB_GetPtr(mb), 1, RK_MPI_MB_GetSize(mb), file);
fclose(file);
}*/
RK_MPI_MB_ReleaseBuffer(mb);
jpeg_id++;
}
static void *MainStream(void * data) {
MEDIA_BUFFER buffer;
char jpeg_path[128];
static RK_U32 jpeg_id = 0;
while (!quit) {
//printf("%s\n",__func__);
buffer = RK_MPI_SYS_GetMediaBuffer(RK_ID_RGA, 0, -1);
if (!buffer)
continue;
/* sprintf(jpeg_path, "/userdata/data/test%d.jpg", jpeg_id);
FILE *file = fopen(jpeg_path, "w");
if (file) {
fwrite(RK_MPI_MB_GetPtr(buffer), 1, RK_MPI_MB_GetSize(buffer), file);
fclose(file);
}*/
RK_MPI_MB_ReleaseBuffer(buffer);
jpeg_id++;
}
}
static FILE *g_output_file=NULL;
#define video_output_path "/userdata/data/"
#define video_output_length 25*60*3 //fps=25,3分钟一个视频
static void venc_packet_cb(MEDIA_BUFFER mb) {
static RK_S32 packet_cnt = 0;
if (quit)
return;
printf("#Get packet-%d, size %zu\n", packet_cnt, RK_MPI_MB_GetSize(mb));
if (g_rtsplive && g_rtsp_session) {
printf("rtsp push \n");
rtsp_tx_video(g_rtsp_session, (uint8_t*)RK_MPI_MB_GetPtr(mb), RK_MPI_MB_GetSize(mb),
RK_MPI_MB_GetTimestamp(mb)); // RTSP 发送,通过获取 MB 编码数据虚拟地址,大小,时间戳,然后发送
rtsp_do_event(g_rtsplive);
}
RK_MPI_MB_ReleaseBuffer(mb);
packet_cnt++;
/*
static RK_S32 packet_cnt = 0;
char pOutPath[128];
struct tm t;
struct timespec time = { 0, 0 };
printf("%s\n",__func__);
#if 1
if(packet_cnt==0)
{
clock_gettime(CLOCK_REALTIME, &time);
strftime(pOutPath, sizeof(pOutPath), "/userdata/data/%Y-%m-%d-%H-%M-%S.h264", localtime_r(&time.tv_sec, &t));
printf("video file name=%s\n",pOutPath);
if (!g_output_file) {
g_output_file = fopen(pOutPath, "w");
if (!g_output_file) {
printf("ERROR: open file: %s fail, exit\n", pOutPath);
return ;
}
}
}
#endif
#if 1
if (quit)
return;
const char *nalu_type = "Jpeg data";
switch (RK_MPI_MB_GetFlag(mb)) {
case VENC_NALU_IDRSLICE:
nalu_type = "IDR Slice";
break;
case VENC_NALU_PSLICE:
nalu_type = "P Slice";
break;
default:
break;
}
if (g_output_file) {
fwrite(RK_MPI_MB_GetPtr(mb), 1, RK_MPI_MB_GetSize(mb), g_output_file);
printf("#Write packet-%d, %s, size %zu\n", packet_cnt, nalu_type,
RK_MPI_MB_GetSize(mb));
} else {
printf("#Get packet-%d, %s, size %zu\n", packet_cnt, nalu_type,
RK_MPI_MB_GetSize(mb));
}
RK_MPI_MB_TsNodeDump(mb);
RK_MPI_MB_ReleaseBuffer(mb);
#endif
packet_cnt++;
#if 1
if(packet_cnt==video_output_length)
{
if (g_output_file)
fclose(g_output_file);
g_output_file = NULL;
packet_cnt = 0;
}
#endif
*/
}
static void rga_packet_cb(MEDIA_BUFFER mb) {
static RK_U32 jpeg_id = 0;
if (quit)
return;
printf("%s\n",__func__);
/* char jpeg_path[128];
sprintf(jpeg_path, "/userdata/data/test%d.jpg", jpeg_id);
FILE *file = fopen(jpeg_path, "w");
if (file) {
fwrite(RK_MPI_MB_GetPtr(mb), 1, RK_MPI_MB_GetSize(mb), file);
fclose(file);
} */
RK_MPI_MB_TsNodeDump(mb);
RK_MPI_MB_ReleaseBuffer(mb);
jpeg_id++;
}
int main(int argc, char *argv[])
{
int ret=0;
signal(SIGINT, sigterm_handler);
#if 0
RK_CHAR *pOutPath = (char*)"/userdata/data/save.h264";
if (pOutPath) {
g_output_file = fopen(pOutPath, "w");
if (!g_output_file) {
printf("ERROR: open file: %s fail, exit\n", pOutPath);
return 0;
}
}
#endif
//设置rtsp推流属性
g_rtsplive = create_rtsp_demo(554);
if(g_rtsplive==NULL)
printf("g_rtsplive is null\n");
g_rtsp_session = rtsp_new_session(g_rtsplive, "/live/main_stream");
if(g_rtsp_session == NULL)
printf("g_rtsp_session is null\n");
rtsp_set_video(g_rtsp_session, RTSP_CODEC_ID_VIDEO_H264, NULL, 0);
// rtsp_sync_video_ts(g_rtsp_session, rtsp_get_reltime(), rtsp_get_ntptime()); //rtsp 同步当前网络时间
RK_MPI_SYS_Init();//初始化 MPI 系统
//设置decode属性
VDEC_CHN_ATTR_S stVdecAttr;
stVdecAttr.enCodecType = RK_CODEC_TYPE_H264;
stVdecAttr.enMode = VIDEO_MODE_STREAM;
stVdecAttr.enDecodecMode = VIDEO_DECODEC_HADRWARE;
ret = RK_MPI_VDEC_CreateChn(0, &stVdecAttr);
if (ret) {
printf("Create Vdec[0] failed! ret=%d\n", ret);
return -1;
}
//设置decode有数据时 回调
MPP_CHN_S VdecChn; //定义模块设备通道结构体。
VdecChn.enModId = RK_ID_VDEC;
VdecChn.s32DevId = 0;
VdecChn.s32ChnId = 0;
/*ret = RK_MPI_SYS_RegisterOutCb(&VdecChn, vdec_packet_cb); //注册数据输出回调。
if (ret) {
printf("ERROR: register output callback for Vdec[0] error! ret=%d\n", ret);
return 0;
}*/
//设置encode属性
MPP_CHN_S VencChn;
VencChn.enModId = RK_ID_VENC;
VencChn.s32DevId = 0;
VencChn.s32ChnId = 0;
VENC_CHN_ATTR_S venc_chn_attr;
memset(&venc_chn_attr, 0, sizeof(venc_chn_attr));
venc_chn_attr.stVencAttr.enType = RK_CODEC_TYPE_H264;
venc_chn_attr.stRcAttr.enRcMode = VENC_RC_MODE_H264VBR;
venc_chn_attr.stRcAttr.stH264Vbr.u32Gop = 25;
venc_chn_attr.stRcAttr.stH264Vbr.u32MaxBitRate = 1920 * 1080 * 2;
// frame rate: in 30/1, out 30 /1.
venc_chn_attr.stRcAttr.stH264Vbr.fr32DstFrameRateDen = 1;
venc_chn_attr.stRcAttr.stH264Vbr.fr32DstFrameRateNum = 25;
venc_chn_attr.stRcAttr.stH264Vbr.u32SrcFrameRateDen = 1;
venc_chn_attr.stRcAttr.stH264Vbr.u32SrcFrameRateNum = 25;
venc_chn_attr.stVencAttr.imageType = IMAGE_TYPE_NV12; //输入图片的格式,和 VI 输出保持一致
venc_chn_attr.stVencAttr.u32PicWidth = 1920; //编码图像宽度,单位像素点
venc_chn_attr.stVencAttr.u32PicHeight = 1080;//编码图像高度,单位像素点
venc_chn_attr.stVencAttr.u32VirWidth = 1920;//stride 宽度,必须 16 对齐
venc_chn_attr.stVencAttr.u32VirHeight = 1080 + 8;// stride 高度,必须 16 对齐
venc_chn_attr.stVencAttr.u32Profile = 77; //编码等级 77,是中级 66,基础等级,100,高级
ret = RK_MPI_VENC_CreateChn(0, &venc_chn_attr);//创建通道
ret = RK_MPI_SYS_RegisterOutCb(&VencChn, venc_packet_cb); //注册数据输出回调。
if (ret) {
printf("ERROR: register output callback for Vdec[0] error! ret=%d\n", ret);
return 0;
}
#ifdef full_flow
MPP_CHN_S VencChn1;
VencChn1.enModId = RK_ID_VENC;
VencChn1.s32DevId = 0;
VencChn1.s32ChnId = 1;
memset(&venc_chn_attr, 0, sizeof(venc_chn_attr));
venc_chn_attr.stVencAttr.enType = RK_CODEC_TYPE_H264;
venc_chn_attr.stRcAttr.enRcMode = VENC_RC_MODE_H264VBR;
venc_chn_attr.stRcAttr.stH264Vbr.u32Gop = 25;
venc_chn_attr.stRcAttr.stH264Vbr.u32MaxBitRate = 1920 * 1080 * 2;
// frame rate: in 30/1, out 30 /1.
venc_chn_attr.stRcAttr.stH264Vbr.fr32DstFrameRateDen = 1;
venc_chn_attr.stRcAttr.stH264Vbr.fr32DstFrameRateNum = 25;
venc_chn_attr.stRcAttr.stH264Vbr.u32SrcFrameRateDen = 1;
venc_chn_attr.stRcAttr.stH264Vbr.u32SrcFrameRateNum = 25;
venc_chn_attr.stVencAttr.imageType = IMAGE_TYPE_RGB888; //输入图片的格式,和 VI 输出保持一致
venc_chn_attr.stVencAttr.u32PicWidth = 1920; //编码图像宽度,单位像素点
venc_chn_attr.stVencAttr.u32PicHeight = 1080;//编码图像高度,单位像素点
venc_chn_attr.stVencAttr.u32VirWidth = 1920;//stride 宽度,必须 16 对齐
venc_chn_attr.stVencAttr.u32VirHeight = 1080 + 8;// stride 高度,必须 16 对齐
venc_chn_attr.stVencAttr.u32Profile = 77; //编码等级 77,是中级 66,基础等级,100,高级
ret = RK_MPI_VENC_CreateChn(1, &venc_chn_attr);//创建通道
#endif
//设置rga属性
RGA_ATTR_S stRgaAttr;
stRgaAttr.bEnBufPool = RK_TRUE;
stRgaAttr.u16BufPoolCnt = 12;
stRgaAttr.u16Rotaion = 0;
stRgaAttr.stImgIn.u32X = 0;
stRgaAttr.stImgIn.u32Y = 0;
stRgaAttr.stImgIn.imgType = IMAGE_TYPE_NV12;
stRgaAttr.stImgIn.u32Width = 1920;
stRgaAttr.stImgIn.u32Height = 1080;
stRgaAttr.stImgIn.u32HorStride = 1920;
stRgaAttr.stImgIn.u32VirStride = 1080;
stRgaAttr.stImgOut.u32X = 0;
stRgaAttr.stImgOut.u32Y = 0;
//stRgaAttr.stImgOut.imgType = IMAGE_TYPE_JPEG;
stRgaAttr.stImgOut.imgType = IMAGE_TYPE_BGR888;
stRgaAttr.stImgOut.u32Width = 1920;
stRgaAttr.stImgOut.u32Height = 1080;
stRgaAttr.stImgOut.u32HorStride = 1920;
stRgaAttr.stImgOut.u32VirStride = 1080;
ret = RK_MPI_RGA_CreateChn(0, &stRgaAttr);
if (ret) {
printf("Create rga[0] falied! ret=%d\n", ret);
return -1;
}
MPP_CHN_S vRgaChn;
vRgaChn.enModId = RK_ID_RGA;
vRgaChn.s32DevId = 0;
vRgaChn.s32ChnId = 0;
/* ret = RK_MPI_SYS_RegisterOutCb(&vRgaChn, rga_packet_cb); //注册数据输出回调。
if (ret) {
printf("ERROR: register output callback for RGA[0] error! ret=%d\n", ret);
return NULL;
}*/
pthread_t main_stream_thread;
pthread_create(&main_stream_thread, NULL, MainStream, NULL);
#ifdef close_mux
//设置mux属性
MUXER_CHN_ATTR_S stMuxerAttr;
memset(&stMuxerAttr, 0, sizeof(stMuxerAttr));
stMuxerAttr.enMode = MUXER_MODE_AUTOSPLIT;
stMuxerAttr.enType = MUXER_TYPE_MP4;
stMuxerAttr.stSplitAttr.enSplitType = MUXER_SPLIT_TYPE_TIME;
stMuxerAttr.stSplitAttr.u32TimeLenSec = 30;
/*printf("#MuxerTest: use split name auto type...\n");
stMuxerAttr.stSplitAttr.enSplitNameType = MUXER_SPLIT_NAME_TYPE_AUTO;
stMuxerAttr.stSplitAttr.stNameAutoAttr.pcPrefix = (RK_CHAR*)"muxer_test";
stMuxerAttr.stSplitAttr.stNameAutoAttr.pcBaseDir = (RK_CHAR*)"/userdata/data";
// Split File name with timestamp.
// stMuxerAttr.stSplitAttr.stNameAutoAttr.bTimeStampEnable = RK_TRUE;
stMuxerAttr.stSplitAttr.stNameAutoAttr.u16StartIdx = 1;*/
printf("#MuxerTest: use split name callback type, cb:%p, handle:%p...\n",
GetRecordFileName, &gu32FileIdx);
stMuxerAttr.stSplitAttr.enSplitNameType = MUXER_SPLIT_NAME_TYPE_CALLBACK;
stMuxerAttr.stSplitAttr.stNameCallBackAttr.pcbRequestFileNames = GetRecordFileName;
stMuxerAttr.stSplitAttr.stNameCallBackAttr.pCallBackHandle =(RK_VOID *)&gu32FileIdx;
stMuxerAttr.stVideoStreamParam.enCodecType = RK_CODEC_TYPE_H264;
stMuxerAttr.stVideoStreamParam.enImageType = IMAGE_TYPE_NV12;
stMuxerAttr.stVideoStreamParam.u16Fps = 25;
stMuxerAttr.stVideoStreamParam.u16Level = 41; // for h264
stMuxerAttr.stVideoStreamParam.u16Profile = 77; // for h264
stMuxerAttr.stVideoStreamParam.u32BitRate = 1920 * 1080;
stMuxerAttr.stVideoStreamParam.u32Width = 1920;
stMuxerAttr.stVideoStreamParam.u32Height = 1080;
ret = RK_MPI_MUXER_EnableChn(0, &stMuxerAttr);
if (ret) {
printf("Create MUXER[0] failed! ret=%d\n", ret);
return -1;
}
MPP_CHN_S muxerChn;
MUXER_CHN_S stMuxerChn;
muxerChn.enModId = RK_ID_MUXER;
muxerChn.s32DevId = 0;
muxerChn.s32ChnId = 0;
MuxerHandle stMuxerHandle;
stMuxerHandle.u32ChnIdx = 0;
stMuxerHandle.u32ModeIdx = RK_ID_MUXER;
ret = RK_MPI_SYS_RegisterEventCb(&muxerChn, &stMuxerHandle, muxer_event_cb);
if (ret) {
printf("Register event callback failed! ret=%d\n", ret);
return -1;
}
printf("### Start muxer stream...\n");
ret = RK_MPI_MUXER_StreamStart(0);
if (ret) {
printf("Muxer start stream failed! ret=%d\n", ret);
return -1;
}
// Bind VENC[0] to MUXER[0]:VIDEO
VencChn.enModId = RK_ID_VENC;
VencChn.s32DevId = 0;
VencChn.s32ChnId = 0;
stMuxerChn.enModId = RK_ID_MUXER;
stMuxerChn.enChnType = MUXER_CHN_TYPE_VIDEO;
stMuxerChn.s32ChnId = 0;
ret = RK_MPI_MUXER_Bind(&VencChn, &stMuxerChn);
if (ret) {
printf("ERROR: Bind VENC[0] and MUXER[0]:VIDEO error! ret=%d\n", ret);
return 0;
}
#endif
// VDec Bind Rga
ret = RK_MPI_SYS_Bind(&VdecChn, &vRgaChn);
if (ret) {
printf("ERROR: Bind Vdec[0] and VRGA[0] failed! ret=%d\n");
return -1;
}
// VDec Bind VENC for save video
ret = RK_MPI_SYS_Bind(&VdecChn, &VencChn);
if (ret) {
printf("ERROR: Bind Vdec[0] and Venc[0] failed! ret=%d\n");
return -1;
}
#ifdef full_flow
ret = RK_MPI_SYS_Bind(&vRgaChn, &VencChn1);
if (ret) {
printf("ERROR: Bind VRGA[0] and Venc[1] failed! ret=%d\n");
return -1;
}
//连接到rtsp推流上
#endif
//设置流媒体参数
struct FFRTSPGet ffrtsp_get;
ffrtsp_get.callback = FFRKMedia_Vdec_Send;
ffrtsp_get.count = 1;
ffrtsp_get.ffrtsp_get_info[0].url = (char*)"rtsp://admin:zd123456@192.168.1.5";
ffrtspGet(ffrtsp_get);
//设置rtsp推流属性
//g_rtsplive = create_rtsp_demo(554);
//g_rtsp_session = rtsp_new_session(g_rtsplive, "/live/main_stream");
//rtsp_set_video(g_rtsp_session, RTSP_CODEC_ID_VIDEO_H264, NULL, 0);
// rtsp_sync_video_ts(g_rtsp_session, rtsp_get_reltime(), rtsp_get_ntptime()); //rtsp 同步当前网络时间
while(!quit)
{
sleep(1);
}
if (g_rtsplive)
rtsp_del_demo(g_rtsplive);
#ifdef close_mux
printf("### Stop muxer stream...\n");
ret = RK_MPI_MUXER_StreamStop(0);
if (ret) {
printf("Muxer stop stream failed! ret=%d\n", ret);
return -1;
}
// UnBind VENC[0] to MUXER[0]
VencChn.enModId = RK_ID_VENC;
VencChn.s32DevId = 0;
VencChn.s32ChnId = 0;
stMuxerChn.enModId = RK_ID_MUXER;
stMuxerChn.enChnType = MUXER_CHN_TYPE_VIDEO;
stMuxerChn.s32ChnId = 0;
ret = RK_MPI_MUXER_UnBind(&VencChn, &stMuxerChn);
if (ret) {
printf("ERROR: UnBind VENC[0] and MUXER[0] error! ret=%d\n", ret);
return 0;
}
#endif
//释放资源
#ifdef full_flow
RK_MPI_SYS_UnBind(&vRgaChn, &VencChn1);
#endif
RK_MPI_SYS_UnBind(&VdecChn, &vRgaChn);
RK_MPI_SYS_UnBind(&VdecChn, &VencChn);
#ifdef full_flow
RK_MPI_VENC_DestroyChn(1);
#endif
RK_MPI_VENC_DestroyChn(0);
RK_MPI_RGA_DestroyChn(0);
RK_MPI_VDEC_DestroyChn(0);
return 0;
}
