mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-10 17:35:59 +00:00
decklinkaudio/videosrc: Put hardware reference timestamp in a reference timestamp meta
This can be useful to know on multi-channel cards which frames from different channels were captured at the same time.
This commit is contained in:
parent
4b051ea36d
commit
350c56dab4
4 changed files with 44 additions and 8 deletions
|
@ -809,11 +809,13 @@ public:
|
|||
void (*got_video_frame) (GstElement * videosrc,
|
||||
IDeckLinkVideoInputFrame * frame, GstDecklinkModeEnum mode,
|
||||
GstClockTime capture_time, GstClockTime stream_time,
|
||||
GstClockTime stream_duration, IDeckLinkTimecode * dtc, gboolean
|
||||
no_signal) = NULL;
|
||||
GstClockTime stream_duration, GstClockTime hardware_time,
|
||||
GstClockTime hardware_duration, IDeckLinkTimecode * dtc,
|
||||
gboolean no_signal) = NULL;
|
||||
void (*got_audio_packet) (GstElement * videosrc,
|
||||
IDeckLinkAudioInputPacket * packet, GstClockTime capture_time,
|
||||
GstClockTime stream_time, GstClockTime stream_duration,
|
||||
GstClockTime hardware_time, GstClockTime hardware_duration,
|
||||
gboolean no_signal) = NULL;
|
||||
GstDecklinkModeEnum mode;
|
||||
GstClockTime capture_time = GST_CLOCK_TIME_NONE;
|
||||
|
@ -823,6 +825,8 @@ public:
|
|||
HRESULT res;
|
||||
BMDTimeValue stream_time = GST_CLOCK_TIME_NONE;
|
||||
BMDTimeValue stream_duration = GST_CLOCK_TIME_NONE;
|
||||
BMDTimeValue hardware_time = GST_CLOCK_TIME_NONE;
|
||||
BMDTimeValue hardware_duration = GST_CLOCK_TIME_NONE;
|
||||
|
||||
g_mutex_lock (&m_input->lock);
|
||||
if (m_input->videosrc) {
|
||||
|
@ -872,6 +876,15 @@ public:
|
|||
stream_duration = GST_CLOCK_TIME_NONE;
|
||||
}
|
||||
|
||||
res =
|
||||
video_frame->GetHardwareReferenceTimestamp (GST_SECOND,
|
||||
&hardware_time, &hardware_duration);
|
||||
if (res != S_OK) {
|
||||
GST_ERROR ("Failed to get hardware time: 0x%08lx", (unsigned long) res);
|
||||
hardware_time = GST_CLOCK_TIME_NONE;
|
||||
hardware_duration = GST_CLOCK_TIME_NONE;
|
||||
}
|
||||
|
||||
if (m_input->videosrc) {
|
||||
/* FIXME: Avoid circularity between gstdecklink.cpp and
|
||||
* gstdecklinkvideosrc.cpp */
|
||||
|
@ -889,12 +902,14 @@ public:
|
|||
|
||||
/* passing dtc reference */
|
||||
got_video_frame (videosrc, video_frame, mode, capture_time,
|
||||
stream_time, stream_duration, dtc, no_signal);
|
||||
stream_time, stream_duration, hardware_time, hardware_duration, dtc,
|
||||
no_signal);
|
||||
}
|
||||
|
||||
if (got_audio_packet && audiosrc && audio_packet) {
|
||||
m_input->got_audio_packet (audiosrc, audio_packet, capture_time,
|
||||
stream_time, stream_duration, no_signal);
|
||||
stream_time, stream_duration, hardware_time, hardware_duration,
|
||||
no_signal);
|
||||
} else {
|
||||
if (!audio_packet)
|
||||
GST_DEBUG ("Received no audio packet at %" GST_TIME_FORMAT,
|
||||
|
|
|
@ -242,13 +242,13 @@ struct _GstDecklinkInput {
|
|||
GMutex lock;
|
||||
|
||||
/* Set by the video source */
|
||||
void (*got_video_frame) (GstElement *videosrc, IDeckLinkVideoInputFrame * frame, GstDecklinkModeEnum mode, GstClockTime capture_time, GstClockTime stream_time, GstClockTime stream_duration, IDeckLinkTimecode *dtc, gboolean no_signal);
|
||||
void (*got_video_frame) (GstElement *videosrc, IDeckLinkVideoInputFrame * frame, GstDecklinkModeEnum mode, GstClockTime capture_time, GstClockTime stream_time, GstClockTime stream_duration, GstClockTime hardware_time, GstClockTime hardware_duration, IDeckLinkTimecode *dtc, gboolean no_signal);
|
||||
/* Configured mode or NULL */
|
||||
const GstDecklinkMode *mode;
|
||||
BMDPixelFormat format;
|
||||
|
||||
/* Set by the audio source */
|
||||
void (*got_audio_packet) (GstElement *videosrc, IDeckLinkAudioInputPacket * packet, GstClockTime capture_time, GstClockTime stream_time, GstClockTime stream_duration, gboolean no_signal);
|
||||
void (*got_audio_packet) (GstElement *videosrc, IDeckLinkAudioInputPacket * packet, GstClockTime capture_time, GstClockTime stream_time, GstClockTime stream_duration, GstClockTime hardware_time, GstClockTime hardware_duration, gboolean no_signal);
|
||||
|
||||
GstElement *audiosrc;
|
||||
gboolean audio_enabled;
|
||||
|
|
|
@ -63,6 +63,8 @@ typedef struct
|
|||
GstClockTime timestamp;
|
||||
GstClockTime stream_timestamp;
|
||||
GstClockTime stream_duration;
|
||||
GstClockTime hardware_timestamp;
|
||||
GstClockTime hardware_duration;
|
||||
gboolean no_signal;
|
||||
} CapturePacket;
|
||||
|
||||
|
@ -471,7 +473,9 @@ gst_decklink_audio_src_get_caps (GstBaseSrc * bsrc, GstCaps * filter)
|
|||
static void
|
||||
gst_decklink_audio_src_got_packet (GstElement * element,
|
||||
IDeckLinkAudioInputPacket * packet, GstClockTime capture_time,
|
||||
GstClockTime stream_time, GstClockTime stream_duration, gboolean no_signal)
|
||||
GstClockTime stream_time, GstClockTime stream_duration,
|
||||
GstClockTime hardware_time, GstClockTime hardware_duration,
|
||||
gboolean no_signal)
|
||||
{
|
||||
GstDecklinkAudioSrc *self = GST_DECKLINK_AUDIO_SRC_CAST (element);
|
||||
GstClockTime timestamp;
|
||||
|
@ -537,6 +541,8 @@ gst_decklink_audio_src_got_packet (GstElement * element,
|
|||
p.timestamp = timestamp;
|
||||
p.stream_timestamp = stream_time;
|
||||
p.stream_duration = stream_duration;
|
||||
p.hardware_timestamp = hardware_time;
|
||||
p.hardware_duration = hardware_duration;
|
||||
p.no_signal = no_signal;
|
||||
packet->AddRef ();
|
||||
gst_queue_array_push_tail_struct (self->current_packets, &p);
|
||||
|
@ -561,6 +567,8 @@ gst_decklink_audio_src_create (GstPushSrc * bsrc, GstBuffer ** buffer)
|
|||
gboolean discont = FALSE;
|
||||
static GstStaticCaps stream_reference =
|
||||
GST_STATIC_CAPS ("timestamp/x-decklink-stream");
|
||||
static GstStaticCaps hardware_reference =
|
||||
GST_STATIC_CAPS ("timestamp/x-decklink-hardware");
|
||||
|
||||
retry:
|
||||
g_mutex_lock (&self->lock);
|
||||
|
@ -678,6 +686,9 @@ retry:
|
|||
gst_buffer_add_reference_timestamp_meta (*buffer,
|
||||
gst_static_caps_get (&stream_reference), p.stream_timestamp,
|
||||
p.stream_duration);
|
||||
gst_buffer_add_reference_timestamp_meta (*buffer,
|
||||
gst_static_caps_get (&hardware_reference), p.hardware_timestamp,
|
||||
p.hardware_duration);
|
||||
|
||||
GST_DEBUG_OBJECT (self,
|
||||
"Outputting buffer %p with timestamp %" GST_TIME_FORMAT " and duration %"
|
||||
|
|
|
@ -57,6 +57,8 @@ typedef struct
|
|||
GstClockTime timestamp, duration;
|
||||
GstClockTime stream_timestamp;
|
||||
GstClockTime stream_duration;
|
||||
GstClockTime hardware_timestamp;
|
||||
GstClockTime hardware_duration;
|
||||
GstDecklinkModeEnum mode;
|
||||
BMDPixelFormat format;
|
||||
GstVideoTimeCode *tc;
|
||||
|
@ -626,7 +628,8 @@ static void
|
|||
gst_decklink_video_src_got_frame (GstElement * element,
|
||||
IDeckLinkVideoInputFrame * frame, GstDecklinkModeEnum mode,
|
||||
GstClockTime capture_time, GstClockTime stream_time,
|
||||
GstClockTime stream_duration, IDeckLinkTimecode * dtc, gboolean no_signal)
|
||||
GstClockTime stream_duration, GstClockTime hardware_time,
|
||||
GstClockTime hardware_duration, IDeckLinkTimecode * dtc, gboolean no_signal)
|
||||
{
|
||||
GstDecklinkVideoSrc *self = GST_DECKLINK_VIDEO_SRC_CAST (element);
|
||||
GstClockTime timestamp, duration;
|
||||
|
@ -692,6 +695,8 @@ gst_decklink_video_src_got_frame (GstElement * element,
|
|||
f.duration = duration;
|
||||
f.stream_timestamp = stream_time;
|
||||
f.stream_duration = stream_duration;
|
||||
f.hardware_timestamp = hardware_time;
|
||||
f.hardware_duration = hardware_duration;
|
||||
f.mode = mode;
|
||||
f.format = frame->GetPixelFormat ();
|
||||
f.no_signal = no_signal;
|
||||
|
@ -753,6 +758,8 @@ gst_decklink_video_src_create (GstPushSrc * bsrc, GstBuffer ** buffer)
|
|||
const GstDecklinkMode *mode;
|
||||
static GstStaticCaps stream_reference =
|
||||
GST_STATIC_CAPS ("timestamp/x-decklink-stream");
|
||||
static GstStaticCaps hardware_reference =
|
||||
GST_STATIC_CAPS ("timestamp/x-decklink-hardware");
|
||||
|
||||
g_mutex_lock (&self->lock);
|
||||
while (gst_queue_array_is_empty (self->current_frames) && !self->flushing) {
|
||||
|
@ -853,6 +860,9 @@ gst_decklink_video_src_create (GstPushSrc * bsrc, GstBuffer ** buffer)
|
|||
gst_buffer_add_reference_timestamp_meta (*buffer,
|
||||
gst_static_caps_get (&stream_reference), f.stream_timestamp,
|
||||
f.stream_duration);
|
||||
gst_buffer_add_reference_timestamp_meta (*buffer,
|
||||
gst_static_caps_get (&hardware_reference), f.hardware_timestamp,
|
||||
f.hardware_duration);
|
||||
|
||||
mode = gst_decklink_get_mode (self->mode);
|
||||
if (mode->interlaced && mode->tff)
|
||||
|
|
Loading…
Reference in a new issue