其他分享
首页 > 其他分享> > Firefly1126中rtmp库关联至RKNN

Firefly1126中rtmp库关联至RKNN

作者:互联网

1,移植rtmp推流库

首先需要对于rtmp移植至瑞芯微rv1126环境下,具体移植步骤参考以下博客:

https://www.cnblogs.com/kxqblog/p/16143456.html

2,CMakeList信息添加

在/sdk/external/rkmedia/exapmles下的CMakeList文件中361行中RKNN Module Test部分加入以下CMakeList代码,添加编译信息,保存后退出:

#---------------------------------------------
#  rkmedia_vi_rknn_venc_rtmp_test
#---------------------------------------------
link_directories("/home/kxq/Desktop/rv1126_rv1109_linux_release_20210306/external/rkmedia/examples/librtmp/")
add_executable(rkmedia_vi_rknn_venc_rtmp_test rkmedia_vi_rknn_venc_rtmp_test.c ${COMMON_SRC})
add_dependencies(rkmedia_vi_rknn_venc_rtmp_test easymedia)
target_link_libraries(rkmedia_vi_rknn_venc_rtmp_test easymedia 
rtmp -ldl -lstdc++ -lm 
ssl -ldl -lstdc++ -lm 
crypto -ldl -lstdc++ -lm
rknn_api m rga)
target_include_directories(rkmedia_vi_rknn_venc_rtmp_test PRIVATE ${CMAKE_SOURCE_DIR}/include ${CMAKE_SYSROOT}/usr/include/rknn)
install(TARGETS rkmedia_vi_rknn_venc_rtmp_test RUNTIME DESTINATION "bin")
install(FILES rtsp-nn.cfg DESTINATION share)
install(DIRECTORY rknn_model DESTINATION share)
3,代码编写:

在/sdk/external/rkmedia/exapmles下新建rkmedia_vi_rknn_venc_rtmp_test.c文件,主要参考了rkmedia_vi_rknn_venc_rtsp_test.c与rkmedia_vi_venc_rtmp_test.c,有关这两个代码可以参考以下博客:

https://www.cnblogs.com/kxqblog/p/16143508.html

https://www.cnblogs.com/kxqblog/p/16059165.html

其中,主要为对rkmedia_vi_rknn_venc_rtsp_test.c进行部分修改,修改内容如下:

1,删除对于rtsp代码的调用,对于原代码中的初始化rtsp,调用rtsp相关代码进行删除,主要部分在main函数中,如以下,对于以下部分注释删除,去除rtsp模块部分。:

  // init rtsp
  printf("init rtsp\n");
  g_rtsplive = create_rtsp_demo(554);
  
  printf("rtsp video\n");
  switch (cfg.session_cfg[i].video_type) {
  case RK_CODEC_TYPE_H264:
    rtsp_set_video(cfg.session_cfg[i].session, RTSP_CODEC_ID_VIDEO_H264, NULL,
                     0);
    break;
  case RK_CODEC_TYPE_H265:
    rtsp_set_video(cfg.session_cfg[i].session, RTSP_CODEC_ID_VIDEO_H265, NULL,
                     0);
    break;
  default:
    printf("video codec not support.\n");
    break;
  }
        
  rtsp_sync_video_ts(cfg.session_cfg[i].session, rtsp_get_reltime(),
                     rtsp_get_ntptime());
    
  while (g_flag_run) {
    int j = 0;//for (int j = 0; j < cfg.session_count; j++) {
      MEDIA_BUFFER buffer;
      // send video buffer
      buffer = RK_MPI_SYS_GetMediaBuffer(
          RK_ID_VENC, cfg.session_cfg[j].stVenChn.s32ChnId, 0);
      if (buffer) {
        rtsp_tx_video(cfg.session_cfg[j].session, RK_MPI_MB_GetPtr(buffer),
                      RK_MPI_MB_GetSize(buffer),
                      RK_MPI_MB_GetTimestamp(buffer));
        RK_MPI_MB_ReleaseBuffer(buffer);
      }
    //}
    rtsp_do_event(g_rtsplive);
  }
  
  rtsp_del_demo(g_rtsplive);
  

2,增加对于rtmp代码的调用,将rtmp推流库放入与源代码同一文件夹下,加入头函数库#include "librtmp/srs_librtmp.h",并在main函数外编写rtmp推流代码,如以下所示:

static srs_rtmp_t rtmp = NULL;
static int dts,pts = 0;
//rtmp推流回调函数
void video_packet_cb(MEDIA_BUFFER mb) {
  static RK_S32 packet_cnt = 0;
  double fps_rtmp = 20;
  if (!g_flag_run)
    return;

  const char *nalu_type = "NULL";
  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;
  }

  printf("#Get packet-%d, frametype-%s,size %zu ,ptr:%p, fd:%d ,timestamp:%lld\n", 
                   packet_cnt, nalu_type, RK_MPI_MB_GetSize(mb),RK_MPI_MB_GetPtr(mb), RK_MPI_MB_GetFD(mb),RK_MPI_MB_GetTimestamp(mb));

  push_rtmp_stream(rtmp, mb, dts, pts);

  //推流速度快于编码速度,作一定时间延时
  //usleep(1000);

  RK_MPI_MB_ReleaseBuffer(mb);

  dts += 1000 / fps_rtmp;
  pts = dts;
  packet_cnt++;

}

srs_rtmp_t rtmp_publish_init(){
  printf("Example for srs-librtmp\n");
  printf("SRS(ossrs) client librtmp library.\n");
  printf("version: %d.%d.%d\n", srs_version_major(), srs_version_minor(), srs_version_revision());
        
  // connect rtmp context
  const char* rtmp_url = "此处添加rtmp推流服务器地址";
  rtmp = srs_rtmp_create(rtmp_url);
    
  if (srs_rtmp_handshake(rtmp) != 0) {
      srs_human_trace("simple handshake failed.");
      srs_rtmp_destroy(rtmp);
      return NULL;
  }
  srs_human_trace("simple handshake success");
    
  if (srs_rtmp_connect_app(rtmp) != 0) {
      srs_human_trace("connect vhost/app failed.");
      srs_rtmp_destroy(rtmp);
      return NULL;
  }
  srs_human_trace("connect vhost/app success");
    
  if (srs_rtmp_publish_stream(rtmp) != 0) {
      srs_human_trace("publish stream failed.");
      srs_rtmp_destroy(rtmp);
      return NULL;
  }
  srs_human_trace("publish stream success");
  
  return rtmp;

}

并在main函数内中,venc码流编码模块下执行rtmp推流的回调函数进行推流,具体代码如下所示:

  printf("init_rtmp\n");
  srs_rtmp_t rtmp_init = rtmp_publish_init();
  
    // VENC create
  printf("VENC create\n");
  cfg.session_cfg[i].stVenChn.enModId = RK_ID_VENC;
  cfg.session_cfg[i].stVenChn.s32ChnId = i;
  cfg.session_cfg[i].stVenChn.s32DevId = i;
  SAMPLE_COMMON_VENC_Start(&cfg.session_cfg[i]);

  //注册回调函数rtmp推流
  int ret = 0;
  ret = RK_MPI_SYS_RegisterOutCb(&cfg.session_cfg[i].stVenChn, video_packet_cb);
  if (ret) {
    printf("ERROR: register output callback for VENC[0] error! ret=%d\n", ret);
    return 0;
  }
  
  srs_rtmp_destroy(rtmp_init);
4,代码编译:

对于rkmedia_vi_rknn_venc_rtmp_test.c文件编写修改完毕后,在/sdk目录下执行以下命令编译代码:

# SDK根目录,选择环境
source envsetup.sh firefly_rv1126_rv1109
# 重编rkmedia源码
make rkmedia-dirclean && make rkmedia

编译完成后,在SDK/buildroot/output/firefly_rv1126_rv1109/oem/usr/bin目录下找到rkmedia_vi_rknn_venc_rtmp_test二进制可执行程序,移动到板子某一个目录下,再进行测试。

同时编写一份配置文件一同移植入开发板,并与rkmedia_vi_rknn_venc_rtmp_test二进制可执行程序放于同一个目录下,配置文件名为rtsp-nn.cfg,内容如下,名字可以更改,但在之后测试语句中也需要一齐更改:

# cfgline:
# path=%s audio_type=%d channels=%u samplerate=%u nbsample=%u alsapath=%s video_type=%s width=%u height=%u image_type=%u video_path=%s
#
# from rkmedia_common.h CODEC_TYPE_E
# audio_type list
##  AAC, 	0
##  MP2, 	1
##  G711A, 	3
##  G711U, 	4
##  G726, 	5
# video_type list
##  H264, 	6
##  H265, 	7

# image_type
## from rkmedia_common.h IMAGE_TYPE_E
## IMAGE_TYPE_NV12, 	4
## IMAGE_TYPE_FBC0, 	8
## IMAGE_TYPE_NV16, 	10
#
# video_path
## rkispp_m_bypass
## rkispp_scale0
## rkispp_scale1
## rkispp_scale2
# example
path=/live/main_stream video_type=6 width=640 height=480 image_type=13 video_path=/dev/video25
5,代码测试:

开发板下终端下运行以下指令:

./rkmedia_vi_rknn_venc_rtmp_test -c ./rtsp-nn.cfg -b /oem/usr/share/rknn_model/box_priors.txt -l /oem/usr/share/rknn_model/coco_labels_list.txt -p /oem/usr/share/rknn_model/ssd_inception_v2_rv1109_rv1126.rknn

开发板串口显示如下:

拉流代码

 vlc rtmp://rtmp推流服务器地址

但是在vlc下存在拉流卡顿的情况,推测为缓存不中的原图,可以用obs拉流调试,就不存在卡顿的情况了,obs拉流调试相关博客可以参考:

https://www.cnblogs.com/kxqblog/p/16143508.html

rkmedia_vi_rknn_venc_rtmp_test.c文件下载地址为:

https://files.cnblogs.com/files/blogs/741465/rkmedia_vi_rknn_venc_rtmp_test.zip?t=1657862575

标签:RKNN,rknn,cfg,rtsp,srs,Firefly1126,rkmedia,rtmp
来源: https://www.cnblogs.com/kxqblog/p/16481079.html