mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-19 13:55:41 +00:00
decklink: improve frame handling
Send NEWSEGMENT on start. Send warning instead of error on dropped frames. Signed-off-by: David Schleef <ds@schleef.org>
This commit is contained in:
parent
a18180898f
commit
8f08c610ec
3 changed files with 39 additions and 16 deletions
|
@ -45,7 +45,7 @@ IDeckLink *deckLink;
|
|||
IDeckLinkInput *deckLinkInput;
|
||||
IDeckLinkDisplayModeIterator *displayModeIterator;
|
||||
|
||||
static BMDTimecodeFormat g_timecodeFormat = 0;
|
||||
static BMDTimecodeFormat g_timecodeFormat = (BMDTimecodeFormat)0;
|
||||
|
||||
DeckLinkCaptureDelegate::DeckLinkCaptureDelegate ():m_refCount (0)
|
||||
{
|
||||
|
@ -124,6 +124,10 @@ HRESULT
|
|||
decklinksrc->audio_frame = audioFrame;
|
||||
}
|
||||
}
|
||||
|
||||
/* increment regardless whether frame was dropped or not */
|
||||
decklinksrc->frame_num++;
|
||||
|
||||
g_cond_signal (decklinksrc->cond);
|
||||
g_mutex_unlock (decklinksrc->mutex);
|
||||
}
|
||||
|
|
|
@ -277,6 +277,10 @@ gst_decklink_src_init (GstDecklinkSrc * decklinksrc,
|
|||
decklinksrc->connection = GST_DECKLINK_CONNECTION_SDI;
|
||||
decklinksrc->audio_connection = GST_DECKLINK_AUDIO_CONNECTION_AUTO;
|
||||
|
||||
decklinksrc->stop = FALSE;
|
||||
decklinksrc->dropped_frames = 0;
|
||||
decklinksrc->dropped_frames_old = 0;
|
||||
decklinksrc->frame_num = -1; /* -1 so will be 0 after incrementing */
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -389,7 +393,7 @@ gst_decklink_src_start (GstElement * element)
|
|||
DeckLinkCaptureDelegate *delegate;
|
||||
//IDeckLinkDisplayModeIterator *mode_iterator;
|
||||
//IDeckLinkDisplayMode *mode;
|
||||
int sample_depth;
|
||||
BMDAudioSampleType sample_depth;
|
||||
int channels;
|
||||
HRESULT ret;
|
||||
const GstDecklinkMode *mode;
|
||||
|
@ -520,7 +524,7 @@ gst_decklink_src_start (GstElement * element)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
sample_depth = 16;
|
||||
sample_depth = bmdAudioSampleType16bitInteger;
|
||||
channels = 2;
|
||||
ret = decklinksrc->input->EnableAudioInput (bmdAudioSampleRate48kHz,
|
||||
sample_depth, channels);
|
||||
|
@ -1056,7 +1060,6 @@ gst_decklink_src_task (void *priv)
|
|||
GstBuffer *audio_buffer;
|
||||
IDeckLinkVideoInputFrame *video_frame;
|
||||
IDeckLinkAudioInputPacket *audio_frame;
|
||||
int dropped_frames;
|
||||
void *data;
|
||||
int n_samples;
|
||||
GstFlowReturn ret;
|
||||
|
@ -1070,7 +1073,6 @@ gst_decklink_src_task (void *priv)
|
|||
}
|
||||
video_frame = decklinksrc->video_frame;
|
||||
audio_frame = decklinksrc->audio_frame;
|
||||
dropped_frames = decklinksrc->dropped_frames;
|
||||
decklinksrc->video_frame = NULL;
|
||||
decklinksrc->audio_frame = NULL;
|
||||
g_mutex_unlock (decklinksrc->mutex);
|
||||
|
@ -1080,10 +1082,14 @@ gst_decklink_src_task (void *priv)
|
|||
return;
|
||||
}
|
||||
|
||||
if (dropped_frames > 0) {
|
||||
GST_ELEMENT_ERROR (decklinksrc, RESOURCE, READ, (NULL), (NULL));
|
||||
/* ERROR */
|
||||
return;
|
||||
/* warning on dropped frames */
|
||||
if (decklinksrc->dropped_frames - decklinksrc->dropped_frames_old > 0) {
|
||||
GST_ELEMENT_WARNING (decklinksrc, RESOURCE, READ,
|
||||
("Dropped %d frame(s), for a total of %d frame(s)",
|
||||
decklinksrc->dropped_frames - decklinksrc->dropped_frames_old,
|
||||
decklinksrc->dropped_frames),
|
||||
(NULL));
|
||||
decklinksrc->dropped_frames_old = decklinksrc->dropped_frames;
|
||||
}
|
||||
|
||||
mode = gst_decklink_get_mode (decklinksrc->mode);
|
||||
|
@ -1106,16 +1112,28 @@ gst_decklink_src_task (void *priv)
|
|||
}
|
||||
|
||||
GST_BUFFER_TIMESTAMP (buffer) =
|
||||
gst_util_uint64_scale_int (decklinksrc->num_frames * GST_SECOND,
|
||||
gst_util_uint64_scale_int (decklinksrc->frame_num * GST_SECOND,
|
||||
mode->fps_d, mode->fps_n);
|
||||
GST_BUFFER_DURATION (buffer) =
|
||||
gst_util_uint64_scale_int ((decklinksrc->num_frames + 1) * GST_SECOND,
|
||||
gst_util_uint64_scale_int ((decklinksrc->frame_num + 1) * GST_SECOND,
|
||||
mode->fps_d, mode->fps_n) - GST_BUFFER_TIMESTAMP (buffer);
|
||||
GST_BUFFER_OFFSET (buffer) = decklinksrc->num_frames;
|
||||
if (decklinksrc->num_frames == 0) {
|
||||
GST_BUFFER_OFFSET (buffer) = decklinksrc->frame_num;
|
||||
GST_BUFFER_OFFSET_END (buffer) = decklinksrc->frame_num;
|
||||
if (decklinksrc->frame_num == 0) {
|
||||
GstEvent *event;
|
||||
gboolean ret;
|
||||
|
||||
GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DISCONT);
|
||||
|
||||
event = gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_TIME, 0,
|
||||
GST_CLOCK_TIME_NONE, 0);
|
||||
|
||||
ret = gst_pad_push_event (decklinksrc->videosrcpad, event);
|
||||
if (!ret) {
|
||||
GST_ERROR_OBJECT (decklinksrc, "new segment event ret=%d", ret);
|
||||
return;
|
||||
}
|
||||
}
|
||||
decklinksrc->num_frames++;
|
||||
|
||||
if (decklinksrc->video_caps == NULL) {
|
||||
decklinksrc->video_caps = gst_decklink_mode_get_caps (decklinksrc->mode);
|
||||
|
@ -1144,7 +1162,7 @@ gst_decklink_src_task (void *priv)
|
|||
|
||||
if (decklinksrc->audio_caps == NULL) {
|
||||
decklinksrc->audio_caps = gst_caps_new_simple ("audio/x-raw-int",
|
||||
"endianness", G_TYPE_INT, LITTLE_ENDIAN,
|
||||
"endianness", G_TYPE_INT, G_LITTLE_ENDIAN,
|
||||
"signed", G_TYPE_BOOLEAN, TRUE,
|
||||
"depth", G_TYPE_INT, 16,
|
||||
"width", G_TYPE_INT, 16,
|
||||
|
|
|
@ -50,6 +50,7 @@ struct _GstDecklinkSrc
|
|||
GMutex *mutex;
|
||||
GCond *cond;
|
||||
int dropped_frames;
|
||||
int dropped_frames_old;
|
||||
gboolean stop;
|
||||
IDeckLinkVideoInputFrame *video_frame;
|
||||
IDeckLinkAudioInputPacket * audio_frame;
|
||||
|
@ -60,7 +61,7 @@ struct _GstDecklinkSrc
|
|||
guint64 num_audio_samples;
|
||||
|
||||
GstCaps *video_caps;
|
||||
guint64 num_frames;
|
||||
guint64 frame_num;
|
||||
int fps_n;
|
||||
int fps_d;
|
||||
int width;
|
||||
|
|
Loading…
Reference in a new issue