Gstreamer Python 으로 Appsink 구현하기
Gstreamer 응용프로그램 개발 시, Python 언어를 사용할 수 있도록 라이브러리를 제공해준다.
makepluscode 의 이전 글에서 mp4 file 을 읽어서 pipeline 을 구현하는 코드를 정리하였다.
2023.02.02 - [프로그래밍/GLibㆍGTKㆍGstreamer] - Gstreamer Python : mp4 filesrc 예제 구현하기
이 코드를 활용하여 비디오 frame buffer 를 획득할 수 있는 Appsink 를 구현해본다. Appsink 는 GStreamer 데이터를 처리할 수 있도록 다양한 방법을 지원하는 싱크 플러그인 이다.
https://gstreamer.freedesktop.org/documentation/app/appsink.html?gi-language=c
아래는 기존 mp4 file 을 읽어서 pipeline 을 구현하는 코드에 appsink 를 추가한 코드 이다. (순서대로) qtdemux - h264parse - avdec_h264 - videoconvert - videorate 를 거쳐서 생성된 비디오 영상이 appsink 를 통해 들어온다.
def create_pipepline(pipeline: Gst.Pipeline):
src = Gst.ElementFactory.make("filesrc", "src")
src.set_property("location", "../video/road.mp4")
demux = Gst.ElementFactory.make("qtdemux", "demux")
parse = Gst.ElementFactory.make("h264parse", "parse")
decode = Gst.ElementFactory.make("avdec_h264", "decode")
convert = Gst.ElementFactory.make("videoconvert", "convert")
videorate = Gst.ElementFactory.make("videorate", "videorate")
caps = Gst.Caps.from_string("video/x-raw, framerate=30/1")
sink = Gst.ElementFactory.make("appsink", "sink")
sink.set_property("emit-signals", True)
sink.set_property("max-buffers", 2)
sink.set_property("drop", True)
sink.set_property("sync", False)
sink.connect("new-sample", on_buffer, sink)
if (not src or not demux or not parse or not decode or not convert or not sink):
print("ERROR: Not all elements could be created.")
sys.exit(1)
pipeline.add(src)
pipeline.add(demux)
pipeline.add(parse)
pipeline.add(decode)
pipeline.add(convert)
pipeline.add(videorate)
pipeline.add(sink)
ret = src.link(demux)
def demuxer_pad_added(demuxer, pad, parse):
if pad.name == 'video_0':
demuxer.link(parse)
demux.connect("pad-added", demuxer_pad_added, parse)
ret = ret and parse.link(decode)
ret = ret and decode.link(convert)
ret = ret and convert.link(videorate)
ret = ret and videorate.link_filtered(sink, caps)
if not ret:
print("ERROR: Elements could not be linked")
sys.exit(1)
else:
print("DONE: Elements could be linked")
return True
appsink 에는 new-sample 이라는 신호가 존재한다. 하나의 frame 이 읽혔을 때, 발생되는 신호 이다. 아래 on_buffer 함수는 new-sample 신호에 의해서 callback 되는 함수 이다.
def on_buffer(sink, data):
global cnt
sample = sink.emit("pull-sample")
buffer = sample.get_buffer()
print("on_buffer: frame count -", cnt)
cnt = cnt + 1
return True
on_buffer 함수에 전달된 sink 객체의 pull-sample 을 통해 buffer 를 읽을 수 있다. 위의 함수 예제는 단순히 buffer 를 읽고 frame 수만 출력한다.
예제 실행하기
python3 를 통해서 구현된 코드를 실행하자. 아래와 같이 appsink 를 통해 들어온 image buffer 를 count 하는 결과를 얻을 수 있다.
전체코드
아래 makepluscode git 저장소에서 전체 코드를 볼수있다.
https://github.com/makepluscode/gstreamer-examples-python/blob/master/05-filesrc-fps-appsink/main.py
참고자료
gst-reamer 파이선 바인딩 관련 소스는 아래 gitlab 을 참고한다.
https://gitlab.freedesktop.org/gstreamer/gst-python
makepluscode 의 launch 를 통한 python gst-reamer 파이프라인 실행 예제
2023.02.02 - [프로그래밍/GLibㆍGTKㆍGstreamer] - Gstreamer Python : pipeline 예제
makepluscode 의 factory 파이프라인 구현하는 예제
2023.02.02 - [프로그래밍/GLibㆍGTKㆍGstreamer] - Gstreamer Python : factory 파이프라인 구현하기
'프로그래밍 > GLibㆍGTKㆍGstreamer' 카테고리의 다른 글
Gstreamer Python : videorate FPS 변경 하기 (0) | 2023.02.02 |
---|---|
Gstreamer Python : mp4 filesrc 예제 구현하기 (0) | 2023.02.02 |
Gstreamer Python : factory 파이프라인 구현하기 (1) | 2023.02.02 |
Gstreamer Python : pipeline 예제 (0) | 2023.02.02 |
윈도우 GNU, MSYS2 개발환경 구축 (0) | 2022.12.03 |
gtk 프로그래밍 ini 설정파일 파싱 예제 (0) | 2022.11.12 |
Gstreamer 로 Jetson 에서 라즈베리파이v2 카메라 테스트 (0) | 2022.07.01 |
GSTShark 로 Gst-reamer pipeline 프로파일링 (0) | 2022.05.30 |