前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Linux平台下RTSP|RTMP播放器如何跟python交互投递RGB数据供视觉算法分析

Linux平台下RTSP|RTMP播放器如何跟python交互投递RGB数据供视觉算法分析

原创
作者头像
音视频牛哥
发布2024-06-30 00:05:00
770
发布2024-06-30 00:05:00
举报

​技术背景

我们在对接Linux平台RTSP播放模块的时候,遇到这样的技术需求,开发者需要把Linux RTSP播放器拉取的数据,除了实时播放外,还要投递给python,用于视觉算法分析。

技术实现

Linux平台RTSP、RTMP直接播放不再赘述,这块我们非常成熟,python需要数据,我们可以在播放的同时,直接把数据回上来。回上来的数据,跟python交互,有多种方式,比如共享内存、或者写bitmap文件,然后python实时读取就好。

本文以写bitmap为例,介绍下大概的实现:

代码语言:cpp
复制
	NT_HANDLE handle = nullptr;

	// 打开一个播放实例,可以Open多个播放实例, 然后播放多路
	if (NT_ERC_OK != player_api.Open(&handle, 0, nullptr))
	{
		player_api.UnInit();

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

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

		return 0;
	}

	player_api.SetEventCallBack(handle, nullptr, &NT_OnSDKEventHandle);
	player_api.SetVideoSizeCallBack(handle, nullptr, &NT_SDKVideoSizeHandle);

	player_api.SetReportDownloadSpeed(handle, 1, 5); // 5秒上报一次下载速度

	player_api.SetRtspTimeout(handle, 15);
	player_api.SetRtspAutoSwitchTcpUdp(handle, 1);

	player_api.SetBuffer(handle, 0); // 设置缓存
	player_api.SetIsOutputAudioDevice(handle, 1);
	player_api.SetAudioOutputLayer(handle, 0); // 使用pluse 或者 alsa播放, 两个可以选择一个
	//player_api.SetAudioVolume(handle, 100);

	player_api.SetURL(handle, player_url_); // 设置播放地址, rtsp或者rtmp地址

	//player_api.SetXDisplayName(handle, NULL);
	player_api.SetXScreenNumber(handle, screen);
	player_api.SetRenderXWindow(handle, sub_wid); // 设置绘制的X窗口
	player_api.SetRenderScaleMode(handle, 1); // 按比例绘制或者全填充
	player_api.SetRenderTextureScaleFilterMode(handle, 3); 

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

#if NEED_SAVE_BITMAP
	// player_api.SetVideoFrameCallBack(handle, NT_SP_E_VIDEO_FRAME_FORMAT_RGB32, nullptr, &NT_SDK_SDKVideoFrameCallBack);

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

#endif

开始播放之前,设置videoframe回调(本文以rgb32为例),videoframe回调,我们有两组接口,一组是原始数据回调,另外一组,是回调缩放后的数据,这里考虑到算法识别对分辨率的要求,我们以缩放的接口为例。

代码语言:cpp
复制
/*
 * nt_linux_smart_player_sdk.h
 * Author: daniusdk.com
 */
/*
设置视频回调, 吐视频数据出来, 可以指定吐出来的视频宽高
*handle: 播放句柄
*scale_width:缩放宽度(必须是偶数,建议是 16 的倍数)
*scale_height:缩放高度(必须是偶数
*scale_filter_mode: 缩放质量, 0 的话 SDK 将使用默认值, 目前可设置范围为[1, 3], 值越大 缩放质量越好,但越耗性能
*frame_format: 只能是NT_SP_E_VIDEO_FRAME_FORMAT_RGB32, NT_SP_E_VIDEO_FRAME_FROMAT_I420
成功返回NT_ERC_OK
*/
NT_UINT32(NT_API *SetVideoFrameCallBackV2)(NT_HANDLE handle,
	NT_INT32 scale_width, NT_INT32 scale_height,
	NT_INT32 scale_filter_mode, NT_INT32 frame_format,
	NT_PVOID call_back_data, SP_SDKVideoFrameCallBack call_back);

开始播放后,video frame数据回调处理如下:

代码语言:cpp
复制
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
}

video frame回调后的数据,直接调研save_bitmap_file()实现bitmap文件写入即可,写bitmap非常简单,这里不再赘述,整体效果如下:

python程序,只需要到指定的文件夹下,读取生成的bitmap即可,实现视频数据视觉算法分析。

总结

Linux平台RTSP、RTMP播放器数据跟python交互,两种方式均可,bitmap实现,也不麻烦,需要注意的时候,由于解码后的单帧数据比较大,建议适当控制导出的bitmap文件数。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • ​技术背景
    • 技术实现
      • 总结
      相关产品与服务
      播放器 SDK
      播放器 SDK 是音视频终端 SDK(腾讯云视立方)的子产品之一,提供直播、点播场景的视频播放能力,支持Web/H5、iOS、Android、Flutter平台。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档