当前位置: 首页 > article >正文

linux平台RTMP|RTSP播放器如何回调SEI数据?

我们在对接Linux平台RTMP|RTSP播放的时候,有遇到这样的技术需求,合作企业在做无人机视觉分析场景的时候,除了需要低延迟的拿到解码后的RGB|YUV数据,然后投递给他们自己的视觉算法处理模块外,还需要播放器支持SEI的回调,拿到无人机通过SEI扩展发送的一些重要信息,比如经纬度、高度或一些监测数据。

实际上,SEI数据回调这块,我们一直都有,我们还有自己的H.264 SEI扩展发送模块,如果需要回调H.264 SEI,只需要在StartPlay之前,调用下SetSEIDataCallBack即可。

具体代码示例如下:

player_api.SetSEIDataCallBack(handle, nullptr, on_player_sdk_sei_data);

on_player_sdk_sei_data设计如下,为了演示方便,我们仅把数据打印出来前面一些字节,实际上,SEI和RGB|YUV数据回调一样,我们也带了timestamp,方便数据帧和SEI对的起来:

extern "C" void on_player_sdk_sei_data(NT_HANDLE handle, NT_PVOID user_data,
	NT_BYTE*  data,
	NT_UINT32 size,
	NT_UINT64 timestamp,
	NT_UINT64 reserve1,
	NT_INT64  reserve2,
	NT_PVOID  reserve3
	) {

	if (!data || size < 1)
		return;

	std::ostringstream ss;
	char buffer[8];

	int print_len = size < 64 ? size : 64;
	for (auto i = 0; i < print_len; ++i) {
		sprintf(buffer, "%02x,", data[i]);
		ss << buffer;
	}

	fprintf(stdout, "on_sdk_sei:size:%d, data:%s\n", size, ss.str().c_str());
	fflush(stdout);
}

如果需要回调RGB数据,设置如下:

/*
 * single_player_demo.cpp
 * Created by daniusdk.com (C) All rights reserved.
 */

//player_api.SetVideoFrameCallBack(handle, NT_SP_E_VIDEO_FRAME_FROMAT_I420, nullptr, &NT_SDK_SDKVideoFrameCallBack);

player_api.SetVideoFrameCallBackV2(handle, 640, 360, 3, NT_SP_E_VIDEO_FRAME_FORMAT_RGB32, nullptr, &NT_SDK_SDKVideoFrameCallBack);

player_api.SetFastStartup(handle, 1);
player_api.SetLowLatencyMode(handle, 0);

if (NT_ERC_OK != player_api.StartPlay(handle))
{
	player_api.Close(handle);
	handle = nullptr;

	player_api.UnInit();
	fprintf(stderr, "player_api.StartPlay failed!\n");

	XDestroyWindow(display, sub_wid);
	XDestroyWindow(display, main_wid_);
	XCloseDisplay(display);

	return 0;
}

可以看到,除了正常的回调yuv或rgb的接口外,我们还有扩展的指定分辨率输出的回调接口设计,方便让开发者更方便的处理数据。

/*
 * single_player_demo.cpp
 * Created by daniusdk.com (C) All rights reserved.
 */

extern "C" void NT_SDK_SDKVideoFrameCallBack(NT_HANDLE handle, NT_PVOID user_data, NT_UINT32 status,
	const NT_SP_VideoFrame* frame)
{
	if (!frame)
		return;

	fprintf(stdout, "OnSDKVideoFrameCallBack handle:%p frame:%p, timestamp:%llu\n", handle, frame, frame->timestamp_);

#if NEED_SAVE_BITMAP

	if (NT_SP_E_VIDEO_FRAME_FORMAT_RGB32 == frame->format_
		|| NT_SP_E_VIDEO_FRAME_FORMAT_ARGB == frame->format_) {

		struct timeval tv;
		if (gettimeofday(&tv, nullptr) != 0) {
			fprintf(stderr, "save bitmap file call gettimeofday failed");
			return;
		}

		uint64_t local_time_us = tv.tv_sec*UINT64_C(1000000) + tv.tv_usec;

		char file_name[128] = { 0 };
		sprintf(file_name, "./outbitmaps/%llu.bmp", (unsigned long long)local_time_us);

		if (!save_bitmap_file(frame->width_, frame->height_, frame->plane0_, frame->stride0_, frame->stride0_*frame->height_, file_name))
			fprintf(stderr, "save bitmap file failed, name:%s", file_name);
		else
			g_bitmap_file_names_.emplace_back(file_name);

		while (g_bitmap_file_names_.size() > 32) {
			remove(g_bitmap_file_names_.front().c_str());
			g_bitmap_file_names_.pop_front();
		}
	}

#endif // NEED_SAVE_BITMAP
}

以RTMP|RTSP播放器为例,Linux平台我们设计的功能如下:

  • 音频:AAC/PCMA/PCMU/SPEEX;
  • 视频:H.264;
  • 播放协议:RTMP;
  • 支持纯音频、纯视频、音视频播放;
  • 支持多实例播放;
  • [RTSP协议]支持RTSP TCP/UDP模式设置;
  • [RTSP协议]支持RTSP TCP、UDP模式自动切换;
  • [RTSP协议]支持RTSP超时时间设置,单位:秒;
  • 支持buffer时间设置,单位:毫秒;
  • 支持超低延迟模式;
  • 断网自动重连,支持视频追赶;
  • 支持视频view实时旋转(0° 90° 180° 270°);
  • 支持视频view水平反转、垂直反转;
  • 支持buffer状态等回调;
  • 支持H.264 SEI扩展数据回调;
  • 支持实时音量调节;
  • 支持实时快照功能;
  • 支持实时录像功能;
  • 支持yuv或rgb数据回调;
  • 支持unity接口;
  • 支持x86_64|aarch64架构(需要glibc-2.21及以上版本的Linux系统, 需要libX11.so.6, 需安装 libstdc++.so.6.0.21、GLIBCXX_3.4.21、 CXXABI_1.3.9)。

http://www.kler.cn/a/514231.html

相关文章:

  • 开篇:吴恩达《机器学习》课程及免费旁听方法
  • 常见Arthas命令与实践
  • Cursor的详细使用指南
  • 他把智能科技引入现代农业领域
  • 小哆啦解题记:如何计算除自身以外数组的乘积
  • 【技术总结类】2024,一场关于海量数据治理以及合理建模的系列写作
  • HTML根元素<html>的语言属性lang:<html lang=“en“>
  • Webrtc (1) - Windows 编译
  • 实操演练第003讲-数据通途:客户端连接SQL Server的完美攻略
  • vue+高德API搭建前段经济页面
  • 1170 Safari Park (25)
  • Unity预制体未即时刷新
  • 【SpringCloud】黑马微服务学习笔记
  • 备战春招—数字IC、FPGA笔试题(2)
  • Docker Load后存储的镜像及更改镜像存储目录的方法
  • Node.js 能做什么
  • 我的创作纪念日,纪念我的第512天
  • 【机器学习】量子机器学习:当量子计算遇上人工智能,颠覆即将来临?
  • 鸿蒙开发(32)arkTS、通过关系型数据库实现数据持久化封装
  • 鸿蒙系统的多端部署
  • 【漫话机器学习系列】052.解释平方和(Explained Sum of Squares, ESS)
  • Leetcode2218:从栈中取出 K 个硬币的最大面值和
  • 单片机基础模块学习——数码管
  • [Day 14]螺旋矩阵
  • 【深度学习】3.损失函数的作用
  • 【前端】HTML标签汇总