【小ネタ】GStreamerのtee及び、queueを使って、Kinesis Video Streamsの複数のストリームに同時送信してみました

2020.02.22

1 はじめに

CX事業本部の平内(SIN)です。

Kinesis Video Streamsへの動画の送信は、通常、GStreamerとシンク(kvssink)の組み合わせで行われますが、GStreamerの基本的なエレメントを使用して、同時に、複数のストリームに書き込む要領を試してみました。

2 coreelements (tee及び、queue)

GStreamsには、Linuxのように、基本的な操作を行うエレメントが用意されています。今回は、この中からteequeueを使用しています。

$ gst-inspect-1.0 | grep core
coreelements:  streamiddemux: Streamid Demux
coreelements:  valve: Valve element
coreelements:  multiqueue: MultiQueue
coreelements:  typefind: TypeFind
coreelements:  tee: Tee pipe fitting
coreelements:  filesink: File Sink
coreelements:  queue2: Queue 2
coreelements:  queue: Queue
coreelements:  output-selector: Output selector
coreelements:  input-selector: Input selector
coreelements:  identity: Identity
coreelements:  funnel: Funnel pipe fitting
coreelements:  filesrc: File Source
coreelements:  fdsink: Filedescriptor Sink
coreelements:  fdsrc: Filedescriptor Source
coreelements:  fakesink: Fake Sink
coreelements:  fakesrc: Fake Source
coreelements:  downloadbuffer: DownloadBuffer
coreelements:  dataurisrc: data: URI source element
coreelements:  concat: Concat
coreelements:  capsfilter: CapsFilter
coretracers:  leaks (GstTracerFactory)
coretracers:  stats (GstTracerFactory)
coretracers:  rusage (GstTracerFactory)
coretracers:  log (GstTracerFactory)
coretracers:  latency (GstTracerFactory)

(1) tee

linuxのteeと同じイメージでパイプラインを複数に分けることができます。通常、パラメータnameで名前を付けておき、後述するqueueで処理します。

$ gst-inspect-1.0 tee
Factory Details:
  Rank                     none (0)
  Long-name                Tee pipe fitting
  Klass                    Generic
  Description              1-to-N pipe fitting

(略)

Element Properties:
  name                : The name of the object
                        flags: readable, writable
                        String. Default: "tee0"

(略)

(2) queue

queueを挟むとスレッドを分けることが出来ます。先のteeで分けられたパイプラインを、別スレッドから、引き続き処理するイメージです。

$ gst-inspect-1.0 queue
Factory Details:
  Rank                     none (0)
  Long-name                Queue
  Klass                    Generic
  Description              Simple data queue
(略)

2 パイプラインの分岐

通常のパイプラインは、上記のように一列縦隊で処理が進みます。そして、スレッドを分けると、前段の処理を複数の後段で続けることが出来ます。

下記は、kvssinkを別スレッドで2つ使用して、USBカメラからの入力を、それぞれ、stream1及びstream2というストリームに送っています。

$ gst-launch-1.0 -v v4l2src ! videoconvert ! \
video/x-raw,format=I420,width=640,height=480,framerate=30/1 ! \
omxh264enc periodicty-idr=45 inline-header=FALSE ! h264parse ! \
video/x-h264,stream-format=avc,alignment=au ! tee name=t ! \
queue !  kvssink stream-name=stream1 t. ! \
queue ! kvssink stream-name=stream2

そして、コンソールから2つのストリームを確認している様子です。一気に、2つのストリームに保存できていることが分かります。

作業は、環境変数で認証情報とリージョンを設定した状態で行っています。

export AWS_DEFAULT_REGION=ap-northeast-1
export AWS_ACCESS_KEY_ID=xxxxxxxxxxxxxx
export AWS_SECRET_ACCESS_KEY=xxxxxxxxxxxxxxxxx

また、デバイスはdevice=/dev/video0(v4l2srcでのデフォルト)で認識されてます。

3 最後に

実は、複数のストリームに記録する必要がある場面は、ちょっと思いついてないのですが、teeとqueueの使い方に慣れておくことは、色々な場面で応用が効くかもしれません。