rtsp推流问题
你好使用core-1126-JD4+配套底板开发时,遇到流媒体推流问题,麻烦看下,谢谢
现象:
在使用core-1126-JD4推流时,用VLC能够打开流媒体,但是流媒体卡在第一张画面上,后面视频看不到
硬件接线:
1、使用一路网口接海康网络摄影头
2、使用另一路网口推流
软件流程:
1、获取rtsp流(使用ffrtsp库)->decode->encode->rtsp推流
测试log:
# ./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
rtsp server demo starting on port 8554
add session path: /live/main_stream
##RKMEDIA Log level: 2
:text is all=2
:module is all, log_level is 2
:RK_MPI_VDEC_CreateChn: Enable VDEC Start...
mpp: mpp_info: mpp version: 92a7c2a4 author: daijh 2021-04-21 debian: fix patch not found bug
:mpi control MPP_DEC_SET_PARSER_SPLIT_MODE ret = 0
mpp: mpp_rt: NOT found ion allocator
mpp: mpp_rt: found drm allocator
:mpi set group limit = 16
:RK_MPI_VDEC_CreateChn: Enable VDEC End!
:RK_MPI_VENC_CreateChn: Enable VENC, Type:6 Start...
mpp: mpp_info: mpp version: 92a7c2a4 author: daijh 2021-04-21 debian: fix patch not found bug
:MPP Encoder: MPPConfig: cfg init sucess!
:MPP Encoder: qpMaxi use default value:48
:MPP Encoder: qpMini use default value:8
:MPP Encoder: qpMax use default value:48
:MPP Encoder: qpMin use default value:8
:MPP Encoder: qpInit use default value:-1
:MPP Encoder: qpStep use default value:2
:MPP Encoder: rotaion = 0
:MPP Encoder: automatically calculate bsp with bps_max
:MPP Encoder: Set output block mode.
:MPP Encoder: Set input block mode.
:MPP Encoder: bps: fps: ->, gop:25 qpInit:-1, qpMin:8, qpMax:48, qpMinI:8, qpMaxI:48.
:MPP Encoder: H264 profile use defalut value: 100:MPP Encoder: AVC: encode profile 100 level 0
mpp: mpp_enc: MPP_ENC_SET_RC_CFG bps 3732480 fps gop 25
mpp: h264e_api_v2: MPP_ENC_SET_PREP_CFG w:h stride
mpp: mpp_enc: send header for set cfg change input/format
:MPP Encoder: w x h(1920 x 1080)
mpp: mpp_enc: mode cbr bps fps fix -> fix gop i v
:RK_MPI_VENC_CreateChn: Enable VENC, Type:6 End...
:RK_MPI_RGA_CreateChn: Enable RGA, Rect<0,0,1920,1080> Start...
:FilterFlow:rkrga: Enable BufferPool! memtype:hw_mem, memcnt:12
:Opened DRM device /dev/dri/card0: driver rockchip version 2.0.0.
:RK_MPI_RGA_CreateChn: Enable RGA, Rect<0,0,1920,1080> End...
:RK_MPI_SYS_Bind: Bind Mode:Chn to Mode:Chn...
:RK_MPI_SYS_Bind: Bind Mode:Chn to Mode:Chn...
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
: 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
: 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
: Set up the "video/H264" subsession (client ports 36746-36747)
: 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
: Started playing session...
:MppDec Info change get, 1920x1080 in (1920x1088)
:Src(0Bytes) or Dst(6220800Bytes) Buffer is invalid!
mpp: mpp_buffer: mpp_buffer_put invalid input: buffer NULL from PrepareMppFrame
mpp: h264e_sps: set level to 4
sps 27
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"
#definefull_flow1
#defineclose_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 = {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 - '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, "/userdata/MuxerCbTest_%u.mp4",*((RK_U32 *)pHandle));
}
printf("#%s: NewRecordFileName:[%s]\n", __func__, pcFileName);
*((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;
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;
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;
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;
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 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 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 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 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 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 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 to MUXER: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 and MUXER: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 and VRGA 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 and Venc failed! ret=%d\n");
return -1;
}
#ifdef full_flow
ret = RK_MPI_SYS_Bind(&vRgaChn, &VencChn1);
if (ret) {
printf("ERROR: Bind VRGA and Venc 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.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 to MUXER
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 and MUXER 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;
}
补充张图片,图片上时间戳,静止不动
你是用 librtsp.a 吧?这个是 rockchip 提供的库,好像是有问题,只要输入源不是 VI 就会出现这种情况,但是因为 rockchip 只提供了静态库文件具体什么问题我们也不得而知。你可以自己实现 rtsp 推流,或者用我们的 libffrtsp.so 试一下 板蓝根 发表于 2021-12-8 09:28
你是用 librtsp.a 吧?这个是 rockchip 提供的库,好像是有问题,只要输入源不是 VI 就会出现这种情况,但 ...
使用ffrtsp用VLC打开也卡住了,硬件IP地址配置如下
1、eth0接IP camera设置IP地址192.168.1.25,camera ip为192.168.1.5
2、eth1接PC,设置IP地址10.0.0.6,pc IP为10.0.0.4
3、用VLC打卡地址rtsp://10.0.0.6:8554/H264_stream_0 卡住没有图像。
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"
struct RTSP_PUSH_INFO ffrtsp_push;
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 = {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 - '0');
}
return msec;
}
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);
//printf("%s\n",__func__);
if(ffrtsp_push.fp == NULL) {
continue;
}
//printf("%s 1\n",__func__);
if (RK_MPI_MB_GetPtr(mb) != NULL) {
printf("%s\n",__func__);
fwrite(RK_MPI_MB_GetPtr(mb), RK_MPI_MB_GetSize(mb), 1, ffrtsp_push.fp);
}
RK_MPI_MB_ReleaseBuffer(mb);
if (quit)
*pquit = true;
}
static void *rtsppushbuff(void *data) {
printf("%s\n",__func__);
((struct RTSP_PUSH_INFO *)data)->type = RTSP_CODEC_H264;
ffrtsph264Push((struct RTSP_PUSH_INFO *)data);
}
int main(int argc, char *argv[])
{
int ret=0;
signal(SIGINT, sigterm_handler);
pthread_t rtsppush_thread;
ffrtsp_push.idex = 0;
ffrtsp_push.port = 8554;
ffrtsp_push.type = RK_CODEC_TYPE_H264;
// RTSP 推流线程
pthread_create(&rtsppush_thread, NULL, rtsppushbuff, (void *)&ffrtsp_push);
//设置流媒体参数
struct FFRTSPGet ffrtsp_get;
ffrtsp_get.callback = FFRKMedia_Vdec_Send;
ffrtsp_get.count = 1;
ffrtsp_get.ffrtsp_get_info.url = (char*)"rtsp://admin:zd123456@192.168.1.5";
ffrtspGet(ffrtsp_get);
while(!quit)
{
sleep(1);
}
return 0;
}
5、log如下:
./rtsp_test1
./rtsp_test1: /lib/libstdc++.so.6: no version information available (required by /usr/lib/libffrtsp.so)
./rtsp_test1: /lib/libstdc++.so.6: no version information available (required by /usr/lib/libffrtsp.so)
./rtsp_test1: /lib/libstdc++.so.6: no version information available (required by /usr/lib/libffrtsp.so)
./rtsp_test1: /lib/libstdc++.so.6: no version information available (required by /usr/lib/libarcsoft_face_engine.so)
./rtsp_test1: /lib/libstdc++.so.6: no version information available (required by /usr/lib/libarcsoft_face_engine.so)
./rtsp_test1: /lib/libstdc++.so.6: no version information available (required by /usr/lib/libarcsoft_face_engine.so)
./rtsp_test1: /lib/libstdc++.so.6: no version information available (required by /usr/lib/libarcsoft_face_engine.so)
./rtsp_test1: /lib/libstdc++.so.6: no version information available (required by /usr/lib/libarcsoft_face.so)
./rtsp_test1: /lib/libstdc++.so.6: no version information available (required by /usr/lib/libarcsoft_face.so)
./rtsp_test1: /lib/libstdc++.so.6: no version information available (required by /usr/lib/libarcsoft_face.so)
./rtsp_test1: /lib/libstdc++.so.6: no version information available (required by /usr/lib/libarcsoft_face.so)
./rtsp_test1: /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
rtsppushbuff
Created new TCP socket 8 for connection
Connecting to 192.168.1.5, port 554 on socket 8...
Play this stream using the URL "rtsp://10.0.0.6:8554/H264_stream_0"
Beginning streaming...
...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="32be1bc1d9706735c8a7d0ddeb8fa885", stale="FALSE"
Date:Mon, Dec 13 2021 22:48:44 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="32be1bc1d9706735c8a7d0ddeb8fa885", uri="rtsp://admin:zd123456@192.168.1.5", response="7ca4546c386098f11bc4bc79352c5576"
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=- 1639435724717783 1639435724717783 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
: Got a SDP description:
v=0
o=- 1639435724717783 1639435724717783 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
: Initiated the "video/H264" subsession (client ports 59324-59325)
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="32be1bc1d9706735c8a7d0ddeb8fa885", uri="rtsp://admin:zd123456@192.168.1.5/", response="9347da75e78d0d7f8950b6dab8316ab7"
User-Agent: ffrtspGet (LIVE555 Streaming Media v2017.10.28)
Transport: RTP/AVP;unicast;client_port=59324-59325
Received 204 new bytes of response data.
Received a complete SETUP response:
RTSP/1.0 200 OK
CSeq: 4
Session: 448226533;timeout=60
Transport: RTP/AVP;unicast;client_port=59324-59325;server_port=8222-8223;ssrc=777d88c7;mode="play"
Date:Mon, Dec 13 2021 22:48:44 GMT
: Set up the "video/H264" subsession (client ports 59324-59325)
: 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="32be1bc1d9706735c8a7d0ddeb8fa885", uri="rtsp://admin:zd123456@192.168.1.5/", response="e2935df5aea2223cfe6517b08beb150c"
User-Agent: ffrtspGet (LIVE555 Streaming Media v2017.10.28)
Session: 448226533
Range: npt=0.000-
Received 180 new bytes of response data.
Received a complete PLAY response:
RTSP/1.0 200 OK
CSeq: 5
Session: 448226533
RTP-Info: url=rtsp://admin:zd123456@192.168.1.5/trackID=1;seq=47568;rtptime=417018600
Date:Mon, Dec 13 2021 22:48:44 GMT
: Started playing session...
FFRKMedia_Vdec_Send
FFRKMedia_Vdec_Send
FFRKMedia_Vdec_Send
FFRKMedia_Vdec_Send
FFRKMedia_Vdec_Send
FFRKMedia_Vdec_Send
FFRKMedia_Vdec_Send
FFRKMedia_Vdec_Send
FFRKMedia_Vdec_Send
FFRKMedia_Vdec_Send
FFRKMedia_Vdec_Send
FFRKMedia_Vdec_Send
FFRKMedia_Vdec_Send
FFRKMedia_Vdec_Send
FFRKMedia_Vdec_Send
FFRKMedia_Vdec_Send
FFRKMedia_Vdec_Send
FFRKMedia_Vdec_Send
FFRKMedia_Vdec_Send
FFRKMedia_Vdec_Send
FFRKMedia_Vdec_Send
FFRKMedia_Vdec_Send
FFRKMedia_Vdec_Send
FFRKMedia_Vdec_Send
FFRKMedia_Vdec_Send
FFRKMedia_Vdec_Send
FFRKMedia_Vdec_Send
FFRKMedia_Vdec_Send
FFRKMedia_Vdec_Send
FFRKMedia_Vdec_Send
FFRKMedia_Vdec_Send
FFRKMedia_Vdec_Send
FFRKMedia_Vdec_Send
FFRKMedia_Vdec_Send
FFRKMedia_Vdec_Send
FFRKMedia_Vdec_Send
没看到有解码器初始化和流发送啊,代码是不是贴漏了?先从下面方式排查一下。
1. 去掉解码步骤,ffrtsp_get 回调获取到的 buff 直接额送到 ffrtsp_push,确认一下是不是 rtsp 配置问题。ffrtsp_demo_test.cpp
2. ffrtsp 后直接保留 h264 文件/ Vdec 解码后保留 NV12 / VENC 编码后保留 H264 来确认哪个步骤出了问题 板蓝根 发表于 2021-12-14 09:41
没看到有解码器初始化和流发送啊,代码是不是贴漏了?先从下面方式排查一下。
1. 去掉解码步骤,ffrtsp_ge ...
没用解码器,IP camera获得的流就是H264编码,NV12的,直接推流到另一个网口的 ffrtsp_get 之后 fwrite 本地文件保存的文件可以播放吗? 直接跑 ffrtsp_demo_test 可以出流吗? 其次可以用 gdb 等调试手段调式一下呀 板蓝根 发表于 2021-12-15 09:31
ffrtsp_get 之后 fwrite 本地文件保存的文件可以播放吗? 直接跑 ffrtsp_demo_test 可以出流吗? 其次可以 ...
使用ffrtsp_demo_test测试也是出不了流,请教下2个问题
1、我打开了SAVE_FILE配置保存为test_rtsp_0,用什么工具打开,我直接拖到VLC上打不开
2、我刚开始的测试代码,偶尔也打开过,想问下是不是需要 网口需要设置路由之类,请问下你们网卡怎么配置的,我在开机启动上以下命令:ifconfig eth0 10.0.0.6 netmask 255.255.255.0;ifconfig eth1 192.168.1.25 netmask 255.255.255.0 1. ffplay 和 vlc 都可以播放,ffplay 要把文件后缀改成 .264 才可以。
2. 双网卡的话有可能是网关的问题,建议你先把一张网卡down 掉,PC 先 ping 通在测试。 chien126 发表于 2021-12-26 22:46
使用ffrtsp_demo_test测试也是出不了流,请教下2个问题
1、我打开了SAVE_FILE配置保存为test_rtsp_0,用 ...
这个可以拉音频么~
页:
[1]
2