지금까지 미디어 처리를 위한 파이프라인을 생성하는 방법과 이를 실행하는 방법을 살펴보았습니다. 대부분의 애플리케이션 개발자는 미디어 진행 상황에 대해 사용자에게 피드백을 제공하는데 관심이 있습니다. 예를 들어 미디어 플레이어는 노래의 진행 상황을 보여주는 슬라이더와 일반적으로 스트림 길이를 나타내는 레이블도 표시하려고 합니다. 트랜스코딩 애플리케이션은 작업이 얼마나 완료되었는지에 대한 진행률 표시줄을 표시하려고 합니다. GStreamer에는 쿼리라는 개념을 사용하여 이 모든 작업을 수행하는 기능이 내장되어 있습니다. Seeking은 매우 유사하므로 여기서도 논의하겠습니다. Seeking은 이벤트 개념을 사용하여 수행됩니다.
Querying: getting the position or length of a stream
Query는 진행률 추적과 관련된 특정 스트림 속성을 요청하는 것으로 정의됩니다. 여기에는 스트림 길이 (사용 가능한 경우) 가져오기 또는 현재 위치 가져오기가 포함됩니다. 이러한 스트림 속성은 시간, audio samples, video frames 또는 bytes와 같은 다양한 형식으로 검색할 수 있습니다. 이를 위해 가장 일반적으로 사용되는 함수는 gst_element_query()이지만 일부 편리한 wrapper도 제공됩니다 (예: gst_element_query_position() 및 gst_element_query_duration()). 일반적으로 파이프라인을 직접 query할 수 있으며 query할 element와 같은 내부 세부 정보를 파악합니다.
내부적으로 query는 sink로 전송되고 한 element가 이를 처리할 수 있을 때까지 뒤로 "dispatch" 됩니다. 그 결과는 함수 호출자에게 다시 전송됩니다. 일반적으로 그것은 디먹서이지만 라이브 source (웹캠의)의 경우에는 아래 source 자체입니다.
#include <gst/gst.h>
static gboolean
cb_print_position (GstElement *pipeline)
{
gint64 pos, len;
if (gst_element_query_position (pipeline, GST_FORMAT_TIME, &pos)
&& gst_element_query_duration (pipeline, GST_FORMAT_TIME, &len)) {
g_print ("Time: %" GST_TIME_FORMAT " / %" GST_TIME_FORMAT "\r",
GST_TIME_ARGS (pos), GST_TIME_ARGS (len));
}
/* call me again */
return TRUE;
}
gint
main (gint argc,
gchar *argv[])
{
GstElement *pipeline;
[..]
/* run pipeline */
g_timeout_add (200, (GSourceFunc) cb_print_position, pipeline);
g_main_loop_run (loop);
[..]
}
Events: seeking (and more)
이벤트는 query와 매우 유사한 방식으로 작동합니다. 예를 들어 dispatching은 이벤트와 동일하게 작동하며 (또한 동일한 제한 사항이 있음) 최상위 파이프라인으로 전송될 수 있으며 모든 것을 파악합니다. 애플리케이션과 element가 이벤트를 사용하여 상호 작용할 수 있는 방법은 더 많지만 여기서는 seeking에만 중점을 둘 것입니다. 이는 seek-event를 사용하여 수행됩니다. Seek-event에는 재생 속도, seek offset format (따라야 할 offset unit, 예: 시간, audio sample, video frame 또는 byte), optionally seeking-related flags 세트 (예: 내부 버퍼가 플러시됨), seek method (주어진 offset을 기준으로 표시) 및 seek offsets을 포함하고 있습니다.
첫 번째 offset (start)은 탐색할 새 위치이고, 두 번째 offset (stop)은 선택 사항이며 스트리밍이 중지되어야 하는 위치를 지정합니다. 일반적으로 GST_SEEK_TYPE_NONE을 stop_type으로 지정하고 GST_CLOCK_TIME_NONE을 stop offset으로 지정하는 것이 좋습니다.
역방향 재생 (rate < 0)의 경우 start과 stop의 의미가 바뀌며 stop은 찾으려는 위치입니다.
Seek 동작은 gst_element_seek() 및 gst_element_seek_simple()에도 wrapping 되어 있으며 일반적으로 이러한 함수를 사용하여 파이프라인에서 seek을 시작합니다.
static void
seek_to_time (GstElement *pipeline,
gint64 time_nanoseconds)
{
if (!gst_element_seek (pipeline, 1.0, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH,
GST_SEEK_TYPE_SET, time_nanoseconds,
GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE)) {
g_print ("Seek failed!\n");
}
}
GST_SEEK_FLAG_FLUSH를 사용한 seek은 파이프라인이 PAUSED 또는 PLAYING 상태일 때 수행되어야 합니다. Seek 후 새 데이터로 인해 파이프라인이 다시 preroll 될 때까지 파이프라인은 자동으로 preroll 상태로 전환됩니다. 파이프라인이 preroll 된 후에는 seek이 실행 되었을 때의 상태 (PAUSED 또는 PLAYING)로 돌아갑니다. gst_element_get_state()를 사용하여 seek이 완료될 때까지 기다리거나 (blocking) ASYNC_DONE 메시지가 bus에 나타날 때까지 기다릴 수 있습니다.
GST_SEEK_FLAG_FLUSH가 없는 seeking은 파이프라인이 PLAYING 상태일 때만 수행되어야 합니다. PAUSED 상태에서 non-flushing seek을 실행하면 파이프라인 스트리밍 스레드가 sink에서 차단될 수 있으므로 교착 상태가 발생할 수 있습니다.
gst_element_seek() 함수가 반환될 때 seek이 완료된다는 점에서 seek이 즉시 발생하지 않는다는 점을 인식하는 것이 중요합니다. 관련된 특정 element에 따라 실제 seek은 나중에 다른 스레드 (스트리밍 스레드)에서 수행될 수 있으며 새 seek 위치의 버퍼가 sink와 같은 다운스트림 element에 도달할 때까지 짧은 시간이 걸릴 수 있습니다 (seek이 플러시되지 않는 경우 시간이 조금 더 걸릴 수 있습니다.)
슬라이더 움직임에 대한 직접적인 반응과 같이 짧은 시간 간격으로 여러 seek을 수행하는 것이 가능합니다. Seek 후 내부적으로 파이프라인이 일시 중지되고 (재생 중인 경우) 위치가 내부적으로 재설정되고 디먹서와 디코더가 새 위치에서 계속 디코딩되며 이는 모든 sink에 데이터가 다시 포함될 때까지 계속됩니다. 원래 재생 중이었다면 다시 재생되도록 설정됩니다. 새 위치는 비디오 출력에서 즉시 사용할 수 있으므로 파이프라인이 재생 상태가 아니더라도 새 프레임을 볼 수 있습니다.
원문: Position tracking and seeking (gstreamer.freedesktop.org)
Position tracking and seeking
Position tracking and seeking So far, we've looked at how to create a pipeline to do media processing and how to make it run. Most application developers will be interested in providing feedback to the user on media progress. Media players, for example, wi
gstreamer.freedesktop.org
'IT와 개발 > GStreamer Study' 카테고리의 다른 글
Interfaces (3) | 2024.05.31 |
---|---|
Metadata (91) | 2024.05.24 |
Your first application (0) | 2024.05.10 |
Buffers and Events (0) | 2024.05.03 |
Pads and capabilities (1) | 2024.04.26 |