Contents

Embedded:RV1126 媒体管道构建

本文采用知识共享署名 4.0 国际许可协议进行许可,转载时请注明原文链接,图片在使用时请保留全部内容,可适当缩放并在引用处附上图片所在的文章链接。

媒体管道构建

文档路径:/rv1126_rv1109_linux_201230/docs/RV1126_RV1109/Multimedia/Rockchip_Instructions_Linux_Rkmedia_CN.pdf : 14.12媒体管道构建

代码路径:/rv1126_rv1109_linux_201230/external/rkmedia/src/flow.cc

Flow介绍

Flow是作为media功能模块的再次封装,便于实现模块间的数据通信。

Flow 类型

Flow可以分为Source类型、IO类型、Sink类型。

  • Source类型:作为数据源,获取数据(读文件/V4L2节点等)封装为MediaBuff,然后送给下级Flow。不存在上级Flow。如:file_read_flow、source_stream等。
  • IO类型:对输入的MediaBuff进行处理,然后输出给下级Flow。支持多个入口和多个出口。如:file_write_flow、output_stream
  • Sink类型:作为数据通路的最后一级Flow,此类型Flow无下级Flow。

Flow 连接管理

Flow 连接:

Flow使用如下接口将多个Flow串联成一个数据管道(Pipeline)。

1
bool AddDownFlow(std::shared_ptr<Flow> down, int out_slot_index,int in_slot_index_of_down);

参数说明:

down:下级Flow指针

out_slot_index:当前Flow输出接口ID,比如Flow有两个入口,那么ID分别为0,1

in_slot_index_of_down:下级Flow出入接口ID,比如Flow有3个入口,那么ID分别为0,1,2

函数说明:

该接口建立Flow之间的出口与入口绑定关系,通过out_slot_index指定当前Flow选择哪个出口,通过in_slot_index_of_down选择下级Flow的哪个入口,然后将二者连接起来。连接后数据将按照既定连接传递数据。

连接模式

一对一模式

FileSourceFlow -> FileSinkFlow

1
2
// 将file_src_flow的0出口绑定到file_sink_flow的0入口
file_src_flow->AddDownFlow(file_sink_flow, 0, 0);

VideoEncoderFlow -> MuxerFlow; AudioEncoderFlow -> MuxerFlow

1
2
3
4
5
6
// 将video_enc_flow的0出口绑定到muxer_flwo的0入口
// MuxerFlow的0入口为视频码流输入口。
video_enc_flow->AddDownFlow(muxer_flwo, 0, 0);
// 将audio_enc_flow的0出口绑定到muxer_flwo的1入口
// MuxerFlow的1入口为音频码流输入口。
audeo_enc_flow->AddDownFlow(muxer_flwo, 0, 1);

一对多模式

一个FileSourceFlow接两个FileSinkFlow

1
2
3
4
// 将file_src_flow的0出口绑定到file_sink_flow0的0入口
file_src_flow->AddDownFlow(file_sink_flow0, 0, 0);
// 将file_src_flow的0出口绑定到file_sink_flow1的0入口
file_src_flow->AddDownFlow(file_sink_flow1, 0, 0);

这种模式下,FileSourceFlow仅发送一个MediaBuff给下级Flow,下级的两个FileSinkFlow拿到的是同一个MediaBuff,MediaBuff的引用加一。上图使用场景,下级Flow生成了两个相同的上级Flow的副本。

Flow 断开连接:

1
void RemoveDownFlow(std::shared_ptr<Flow> down);

参数说明: down:下级Flow的指针。 注:Flow连接时,为避免丢失数据,最好是最后连接数据源Flow;Flow断开连接时,最好优先断开数据源头Flow

比如FileSourceFlow -> VideoEncFLow -> FileSinkFlow连接:

连接:

1
2
3
VideoEncFLow->AddDownFlow(FileSinkFlow, 0, 0);
// 最后连接数据源头
FileSourceFlow ->AddDownFlow(VideoEncFLow, 0, 0);

断开:

1
2
3
// 优先断开数据源头
FileSourceFlow->RemoveDownFlow(VideoEncFLow);
VideoEncFLow->RemoveDownFlow(FileSinkFlow);

Flow传输模式:

Flow的模式决定了Flow数据传递是否启用线程。支持如下传输模式:

  • 同步模式(SYNC) Flow内部不会创建线程,上级Flow递交数据给当前Flow时,会等待当前Flow处理完毕后才返回。
  • 异步模式(ASYNCCOMMON) Flow内部会创建线程,上级Flow递交的数据直接放当前Flow的输入缓冲区就立即返回。当前Flow创建的线程将从输入缓冲区获取数据,处理后在发给下级Flow。
  • 固定时长异步模式(ASYNCATOMIC) 与“异步模式”类似,但是输入缓冲区只有一个,当前Flow内部的线程会固定时间间隔从输入缓冲区取数据。

多数Flow的传输模式是固定的,少数Flow可通过创建Flow时,指定KEK_THREAD_SYNC_MODEL来选择,比如创建Flow的字符串中加入:“KEK_THREAD_SYNC_MODEL=asynccommon”

Flow 枚举

  • audio_enc 功能:音频编码器封装,支持vorbis/aac/mp2/g711a/g711u/g726 源码:audio_encoder_flow.cc 范例:audio_encoder_flow_test.cc 类型:IO 类型,1入1出
  • file_read_flow 功能:读本地文件 源码:file_flow.cc 范例:video_encoder_flow_test.cc 类型:Source类型,0入1出。
  • file_write_flow 功能:写本地文件。 源码:file_flow.cc 范例:video_encoder_flow_test.cc 类型:Sink类型,1入0出
  • filter 功能:一种IO类型的Flow,对输入数据处理后发送给后级的Flow,支持rga/rknn等 源码:filter_flow.cc 范例:rga_filter_flow_test.cc 类型:IO类型,支持多入多出(根据实际使用场景来定)
  • live555_rtsp_server 功能:基于live555构建的rtsp服务器 源码:rtsp_server.cc 范例:rtsp_multi_server_test.cc# USB Camera 产品 源码:move_detection_flow.cc 范例:move_detection_flow_test.cc 类型:Sink类型,1入0出
  • muxer_flow 功能:媒体封装,支持MP4/AVI/MPEG-PS/MPEG-TS/FLV/MKV源码:muxer_flow.cc 范例:muxer_flow_test.cc 类型:IO类型,2入1出
  • output_stream 功能:封装所有输出源,比如drm_output_stream、alsa_playback_stream等 源码:output_stream_flow.cc 范例:drm_display_test.cc 类型:Sink类型,1入0出。
  • source_stream 功能:封装所有数据发生源,比如alsa_capture_stream、v4l2_capture_stream等 源码:source_stream_flow.cc 范例:audio_loop_test.cc 类型:Source类型,0入1出
  • video_dec 功能:视频解码,支持H265/H264/JPEG 源码:decoder_flow.cc 范例:video_decoder_flow_test.cc 类型:IO类型,1入1出
  • video_enc 功能:视频编码,支持H265/H264/JPEG 源码:video_encoder_flow.cc 范例:video_encoder_flow_test.cc 类型:IO类型,1入1出