2018-11-05 14:24:58 +00:00
|
|
|
/*
|
|
|
|
* GStreamer
|
|
|
|
* Copyright (C) 2018 Sebastian Dröge <sebastian@centricular.com>
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Library General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Library General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Library General Public
|
|
|
|
* License along with this library; if not, write to the
|
|
|
|
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
|
|
|
* Boston, MA 02110-1301, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include <config.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <gst/gst.h>
|
|
|
|
#include <gst/base/base.h>
|
|
|
|
#include <gst/video/video.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
2022-05-12 03:19:58 +00:00
|
|
|
#include "ccutils.h"
|
2018-11-05 14:24:58 +00:00
|
|
|
#include "gstcccombiner.h"
|
|
|
|
|
|
|
|
GST_DEBUG_CATEGORY_STATIC (gst_cc_combiner_debug);
|
|
|
|
#define GST_CAT_DEFAULT gst_cc_combiner_debug
|
|
|
|
|
|
|
|
static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
|
|
|
|
GST_PAD_SINK,
|
|
|
|
GST_PAD_ALWAYS,
|
|
|
|
GST_STATIC_CAPS_ANY);
|
|
|
|
|
|
|
|
static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
|
|
|
|
GST_PAD_SRC,
|
|
|
|
GST_PAD_ALWAYS,
|
|
|
|
GST_STATIC_CAPS_ANY);
|
|
|
|
|
|
|
|
static GstStaticPadTemplate captiontemplate =
|
|
|
|
GST_STATIC_PAD_TEMPLATE ("caption",
|
|
|
|
GST_PAD_SINK,
|
|
|
|
GST_PAD_REQUEST,
|
|
|
|
GST_STATIC_CAPS
|
2018-12-10 13:54:49 +00:00
|
|
|
("closedcaption/x-cea-608,format={ (string) raw, (string) s334-1a}; "
|
2018-11-05 14:24:58 +00:00
|
|
|
"closedcaption/x-cea-708,format={ (string) cc_data, (string) cdp }"));
|
|
|
|
|
|
|
|
#define parent_class gst_cc_combiner_parent_class
|
2021-02-17 10:31:35 +00:00
|
|
|
G_DEFINE_TYPE (GstCCCombiner, gst_cc_combiner, GST_TYPE_AGGREGATOR);
|
|
|
|
GST_ELEMENT_REGISTER_DEFINE (cccombiner, "cccombiner",
|
|
|
|
GST_RANK_NONE, GST_TYPE_CCCOMBINER);
|
2018-11-05 14:24:58 +00:00
|
|
|
|
cccombiner: implement scheduling
Prior to that, cccombiner's behaviour was essentially that of
a funnel: it strictly looked at input timestamps to associate
together video and caption buffers.
This patch instead exposes a "schedule" property, with a default
of TRUE, to control whether caption buffers should be smoothly
scheduled, in order to have exactly one per output video buffer.
This can involve rewriting input captions, for example when the
input is CDP sequence counters are rewritten, time codes are dropped
and potentially re-injected if the input video frame had a time code
meta.
Caption buffers may also get split up in order to assign captions to
the correct field when the input is interlaced.
This can also imply that the input will drift from synchronization,
when there isn't enough padding in the input stream to catch up. In
that case the element will start dropping old caption buffers once
the number of buffers in its internal queue reaches a certain limit
(configurable).
The property is exposed so that existing users of cccombiner can
revert back to the original behaviour, but should eventually be
removed, as that behaviour was simply inadequate.
This commit also disallows changing the input caption type, as
this would needlessly complicate implementation, and removes
the corresponding test.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2076>
2021-03-09 12:22:10 +00:00
|
|
|
enum
|
|
|
|
{
|
|
|
|
PROP_0,
|
|
|
|
PROP_SCHEDULE,
|
2022-02-01 22:46:43 +00:00
|
|
|
PROP_OUTPUT_PADDING,
|
cccombiner: implement scheduling
Prior to that, cccombiner's behaviour was essentially that of
a funnel: it strictly looked at input timestamps to associate
together video and caption buffers.
This patch instead exposes a "schedule" property, with a default
of TRUE, to control whether caption buffers should be smoothly
scheduled, in order to have exactly one per output video buffer.
This can involve rewriting input captions, for example when the
input is CDP sequence counters are rewritten, time codes are dropped
and potentially re-injected if the input video frame had a time code
meta.
Caption buffers may also get split up in order to assign captions to
the correct field when the input is interlaced.
This can also imply that the input will drift from synchronization,
when there isn't enough padding in the input stream to catch up. In
that case the element will start dropping old caption buffers once
the number of buffers in its internal queue reaches a certain limit
(configurable).
The property is exposed so that existing users of cccombiner can
revert back to the original behaviour, but should eventually be
removed, as that behaviour was simply inadequate.
This commit also disallows changing the input caption type, as
this would needlessly complicate implementation, and removes
the corresponding test.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2076>
2021-03-09 12:22:10 +00:00
|
|
|
PROP_MAX_SCHEDULED,
|
2024-03-08 07:22:53 +00:00
|
|
|
PROP_CEA608_PADDING_STRATEGY,
|
|
|
|
PROP_CEA608_VALID_PADDING_TIMEOUT,
|
2024-03-12 03:25:31 +00:00
|
|
|
PROP_SCHEDULE_TIMEOUT,
|
2024-02-01 17:45:01 +00:00
|
|
|
PROP_INPUT_META_PROCESSING,
|
cccombiner: implement scheduling
Prior to that, cccombiner's behaviour was essentially that of
a funnel: it strictly looked at input timestamps to associate
together video and caption buffers.
This patch instead exposes a "schedule" property, with a default
of TRUE, to control whether caption buffers should be smoothly
scheduled, in order to have exactly one per output video buffer.
This can involve rewriting input captions, for example when the
input is CDP sequence counters are rewritten, time codes are dropped
and potentially re-injected if the input video frame had a time code
meta.
Caption buffers may also get split up in order to assign captions to
the correct field when the input is interlaced.
This can also imply that the input will drift from synchronization,
when there isn't enough padding in the input stream to catch up. In
that case the element will start dropping old caption buffers once
the number of buffers in its internal queue reaches a certain limit
(configurable).
The property is exposed so that existing users of cccombiner can
revert back to the original behaviour, but should eventually be
removed, as that behaviour was simply inadequate.
This commit also disallows changing the input caption type, as
this would needlessly complicate implementation, and removes
the corresponding test.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2076>
2021-03-09 12:22:10 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
#define DEFAULT_MAX_SCHEDULED 30
|
|
|
|
#define DEFAULT_SCHEDULE TRUE
|
2022-02-01 22:46:43 +00:00
|
|
|
#define DEFAULT_OUTPUT_PADDING TRUE
|
2024-03-08 07:22:53 +00:00
|
|
|
#define DEFAULT_CEA608_PADDING_STRATEGY CC_BUFFER_CEA608_PADDING_STRATEGY_VALID
|
|
|
|
#define DEFAULT_CEA608_VALID_PADDING_TIMEOUT GST_CLOCK_TIME_NONE
|
2024-03-12 03:25:31 +00:00
|
|
|
#define DEFAULT_SCHEDULE_TIMEOUT GST_CLOCK_TIME_NONE
|
2024-02-01 17:45:01 +00:00
|
|
|
#define DEFAULT_INPUT_META_PROCESSING CCCOMBINER_INPUT_PROCESSING_APPEND
|
|
|
|
|
|
|
|
#define GST_TYPE_CCCOMBINER_INPUT_META_PROCESSING (gst_cccombiner_input_meta_processing_get_type())
|
|
|
|
static GType
|
|
|
|
gst_cccombiner_input_meta_processing_get_type (void)
|
|
|
|
{
|
|
|
|
static GType cccombiner_input_meta_processing_type = 0;
|
|
|
|
static const GEnumValue cccombiner_input_meta_processing[] = {
|
|
|
|
{CCCOMBINER_INPUT_PROCESSING_APPEND,
|
|
|
|
"append aggregated CC to existing metas on video buffer", "append"},
|
|
|
|
{CCCOMBINER_INPUT_PROCESSING_DROP,
|
|
|
|
"drop existing CC metas on input video buffer", "drop"},
|
|
|
|
{CCCOMBINER_INPUT_PROCESSING_FAVOR,
|
|
|
|
"discard aggregated CC when input video buffers hold CC metas already",
|
|
|
|
"favor"},
|
2024-12-06 18:13:50 +00:00
|
|
|
{CCCOMBINER_INPUT_PROCESSING_FORCE,
|
|
|
|
"discard aggregated CC even when input video buffers do not hold CC",
|
|
|
|
"force"},
|
2024-02-01 17:45:01 +00:00
|
|
|
{0, NULL, NULL},
|
|
|
|
};
|
|
|
|
|
|
|
|
if (!cccombiner_input_meta_processing_type) {
|
|
|
|
cccombiner_input_meta_processing_type =
|
|
|
|
g_enum_register_static ("GstCCCombinerInputProcessing",
|
|
|
|
cccombiner_input_meta_processing);
|
|
|
|
}
|
|
|
|
return cccombiner_input_meta_processing_type;
|
|
|
|
}
|
cccombiner: implement scheduling
Prior to that, cccombiner's behaviour was essentially that of
a funnel: it strictly looked at input timestamps to associate
together video and caption buffers.
This patch instead exposes a "schedule" property, with a default
of TRUE, to control whether caption buffers should be smoothly
scheduled, in order to have exactly one per output video buffer.
This can involve rewriting input captions, for example when the
input is CDP sequence counters are rewritten, time codes are dropped
and potentially re-injected if the input video frame had a time code
meta.
Caption buffers may also get split up in order to assign captions to
the correct field when the input is interlaced.
This can also imply that the input will drift from synchronization,
when there isn't enough padding in the input stream to catch up. In
that case the element will start dropping old caption buffers once
the number of buffers in its internal queue reaches a certain limit
(configurable).
The property is exposed so that existing users of cccombiner can
revert back to the original behaviour, but should eventually be
removed, as that behaviour was simply inadequate.
This commit also disallows changing the input caption type, as
this would needlessly complicate implementation, and removes
the corresponding test.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2076>
2021-03-09 12:22:10 +00:00
|
|
|
|
2018-11-05 14:24:58 +00:00
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
GstVideoCaptionType caption_type;
|
|
|
|
GstBuffer *buffer;
|
|
|
|
} CaptionData;
|
|
|
|
|
cccombiner: implement scheduling
Prior to that, cccombiner's behaviour was essentially that of
a funnel: it strictly looked at input timestamps to associate
together video and caption buffers.
This patch instead exposes a "schedule" property, with a default
of TRUE, to control whether caption buffers should be smoothly
scheduled, in order to have exactly one per output video buffer.
This can involve rewriting input captions, for example when the
input is CDP sequence counters are rewritten, time codes are dropped
and potentially re-injected if the input video frame had a time code
meta.
Caption buffers may also get split up in order to assign captions to
the correct field when the input is interlaced.
This can also imply that the input will drift from synchronization,
when there isn't enough padding in the input stream to catch up. In
that case the element will start dropping old caption buffers once
the number of buffers in its internal queue reaches a certain limit
(configurable).
The property is exposed so that existing users of cccombiner can
revert back to the original behaviour, but should eventually be
removed, as that behaviour was simply inadequate.
This commit also disallows changing the input caption type, as
this would needlessly complicate implementation, and removes
the corresponding test.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2076>
2021-03-09 12:22:10 +00:00
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
GstBuffer *buffer;
|
|
|
|
GstClockTime running_time;
|
|
|
|
GstClockTime stream_time;
|
|
|
|
} CaptionQueueItem;
|
|
|
|
|
2018-11-05 14:24:58 +00:00
|
|
|
static void
|
|
|
|
caption_data_clear (CaptionData * data)
|
|
|
|
{
|
|
|
|
gst_buffer_unref (data->buffer);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gst_cc_combiner_finalize (GObject * object)
|
|
|
|
{
|
|
|
|
GstCCCombiner *self = GST_CCCOMBINER (object);
|
|
|
|
|
2022-02-18 16:06:44 +00:00
|
|
|
gst_clear_object (&self->caption_pad);
|
|
|
|
|
2018-11-05 14:24:58 +00:00
|
|
|
g_array_unref (self->current_frame_captions);
|
|
|
|
self->current_frame_captions = NULL;
|
|
|
|
|
2022-06-01 11:24:41 +00:00
|
|
|
gst_clear_object (&self->cc_buffer);
|
|
|
|
|
2018-11-05 14:24:58 +00:00
|
|
|
G_OBJECT_CLASS (parent_class)->finalize (object);
|
|
|
|
}
|
|
|
|
|
|
|
|
#define GST_FLOW_NEED_DATA GST_FLOW_CUSTOM_SUCCESS
|
|
|
|
|
2022-05-30 11:39:13 +00:00
|
|
|
static guint
|
|
|
|
extract_cdp (GstCCCombiner * self, const guint8 * cdp, guint cdp_len,
|
|
|
|
guint8 * cc_data)
|
cccombiner: implement scheduling
Prior to that, cccombiner's behaviour was essentially that of
a funnel: it strictly looked at input timestamps to associate
together video and caption buffers.
This patch instead exposes a "schedule" property, with a default
of TRUE, to control whether caption buffers should be smoothly
scheduled, in order to have exactly one per output video buffer.
This can involve rewriting input captions, for example when the
input is CDP sequence counters are rewritten, time codes are dropped
and potentially re-injected if the input video frame had a time code
meta.
Caption buffers may also get split up in order to assign captions to
the correct field when the input is interlaced.
This can also imply that the input will drift from synchronization,
when there isn't enough padding in the input stream to catch up. In
that case the element will start dropping old caption buffers once
the number of buffers in its internal queue reaches a certain limit
(configurable).
The property is exposed so that existing users of cccombiner can
revert back to the original behaviour, but should eventually be
removed, as that behaviour was simply inadequate.
This commit also disallows changing the input caption type, as
this would needlessly complicate implementation, and removes
the corresponding test.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2076>
2021-03-09 12:22:10 +00:00
|
|
|
{
|
2022-05-30 11:39:13 +00:00
|
|
|
const struct cdp_fps_entry *out_fps_entry;
|
|
|
|
GstVideoTimeCode tc = GST_VIDEO_TIME_CODE_INIT;
|
cccombiner: implement scheduling
Prior to that, cccombiner's behaviour was essentially that of
a funnel: it strictly looked at input timestamps to associate
together video and caption buffers.
This patch instead exposes a "schedule" property, with a default
of TRUE, to control whether caption buffers should be smoothly
scheduled, in order to have exactly one per output video buffer.
This can involve rewriting input captions, for example when the
input is CDP sequence counters are rewritten, time codes are dropped
and potentially re-injected if the input video frame had a time code
meta.
Caption buffers may also get split up in order to assign captions to
the correct field when the input is interlaced.
This can also imply that the input will drift from synchronization,
when there isn't enough padding in the input stream to catch up. In
that case the element will start dropping old caption buffers once
the number of buffers in its internal queue reaches a certain limit
(configurable).
The property is exposed so that existing users of cccombiner can
revert back to the original behaviour, but should eventually be
removed, as that behaviour was simply inadequate.
This commit also disallows changing the input caption type, as
this would needlessly complicate implementation, and removes
the corresponding test.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2076>
2021-03-09 12:22:10 +00:00
|
|
|
|
2022-05-30 11:39:13 +00:00
|
|
|
return convert_cea708_cdp_to_cc_data (GST_OBJECT (self), cdp, cdp_len,
|
|
|
|
cc_data, &tc, &out_fps_entry);
|
cccombiner: implement scheduling
Prior to that, cccombiner's behaviour was essentially that of
a funnel: it strictly looked at input timestamps to associate
together video and caption buffers.
This patch instead exposes a "schedule" property, with a default
of TRUE, to control whether caption buffers should be smoothly
scheduled, in order to have exactly one per output video buffer.
This can involve rewriting input captions, for example when the
input is CDP sequence counters are rewritten, time codes are dropped
and potentially re-injected if the input video frame had a time code
meta.
Caption buffers may also get split up in order to assign captions to
the correct field when the input is interlaced.
This can also imply that the input will drift from synchronization,
when there isn't enough padding in the input stream to catch up. In
that case the element will start dropping old caption buffers once
the number of buffers in its internal queue reaches a certain limit
(configurable).
The property is exposed so that existing users of cccombiner can
revert back to the original behaviour, but should eventually be
removed, as that behaviour was simply inadequate.
This commit also disallows changing the input caption type, as
this would needlessly complicate implementation, and removes
the corresponding test.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2076>
2021-03-09 12:22:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#define MAX_CEA608_LEN 32
|
2022-05-13 05:19:43 +00:00
|
|
|
#define CDP_MODE (GST_CC_CDP_MODE_CC_DATA | GST_CC_CDP_MODE_TIME_CODE)
|
cccombiner: implement scheduling
Prior to that, cccombiner's behaviour was essentially that of
a funnel: it strictly looked at input timestamps to associate
together video and caption buffers.
This patch instead exposes a "schedule" property, with a default
of TRUE, to control whether caption buffers should be smoothly
scheduled, in order to have exactly one per output video buffer.
This can involve rewriting input captions, for example when the
input is CDP sequence counters are rewritten, time codes are dropped
and potentially re-injected if the input video frame had a time code
meta.
Caption buffers may also get split up in order to assign captions to
the correct field when the input is interlaced.
This can also imply that the input will drift from synchronization,
when there isn't enough padding in the input stream to catch up. In
that case the element will start dropping old caption buffers once
the number of buffers in its internal queue reaches a certain limit
(configurable).
The property is exposed so that existing users of cccombiner can
revert back to the original behaviour, but should eventually be
removed, as that behaviour was simply inadequate.
This commit also disallows changing the input caption type, as
this would needlessly complicate implementation, and removes
the corresponding test.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2076>
2021-03-09 12:22:10 +00:00
|
|
|
|
|
|
|
static GstBuffer *
|
2022-06-01 11:24:41 +00:00
|
|
|
make_cdp_buffer (GstCCCombiner * self, const guint8 * cc_data,
|
|
|
|
guint cc_data_len, const struct cdp_fps_entry *fps_entry,
|
|
|
|
const GstVideoTimeCode * tc)
|
cccombiner: implement scheduling
Prior to that, cccombiner's behaviour was essentially that of
a funnel: it strictly looked at input timestamps to associate
together video and caption buffers.
This patch instead exposes a "schedule" property, with a default
of TRUE, to control whether caption buffers should be smoothly
scheduled, in order to have exactly one per output video buffer.
This can involve rewriting input captions, for example when the
input is CDP sequence counters are rewritten, time codes are dropped
and potentially re-injected if the input video frame had a time code
meta.
Caption buffers may also get split up in order to assign captions to
the correct field when the input is interlaced.
This can also imply that the input will drift from synchronization,
when there isn't enough padding in the input stream to catch up. In
that case the element will start dropping old caption buffers once
the number of buffers in its internal queue reaches a certain limit
(configurable).
The property is exposed so that existing users of cccombiner can
revert back to the original behaviour, but should eventually be
removed, as that behaviour was simply inadequate.
This commit also disallows changing the input caption type, as
this would needlessly complicate implementation, and removes
the corresponding test.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2076>
2021-03-09 12:22:10 +00:00
|
|
|
{
|
2022-05-13 05:19:43 +00:00
|
|
|
guint len;
|
cccombiner: implement scheduling
Prior to that, cccombiner's behaviour was essentially that of
a funnel: it strictly looked at input timestamps to associate
together video and caption buffers.
This patch instead exposes a "schedule" property, with a default
of TRUE, to control whether caption buffers should be smoothly
scheduled, in order to have exactly one per output video buffer.
This can involve rewriting input captions, for example when the
input is CDP sequence counters are rewritten, time codes are dropped
and potentially re-injected if the input video frame had a time code
meta.
Caption buffers may also get split up in order to assign captions to
the correct field when the input is interlaced.
This can also imply that the input will drift from synchronization,
when there isn't enough padding in the input stream to catch up. In
that case the element will start dropping old caption buffers once
the number of buffers in its internal queue reaches a certain limit
(configurable).
The property is exposed so that existing users of cccombiner can
revert back to the original behaviour, but should eventually be
removed, as that behaviour was simply inadequate.
This commit also disallows changing the input caption type, as
this would needlessly complicate implementation, and removes
the corresponding test.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2076>
2021-03-09 12:22:10 +00:00
|
|
|
GstBuffer *ret = gst_buffer_new_allocate (NULL, MAX_CDP_PACKET_LEN, NULL);
|
|
|
|
GstMapInfo map;
|
|
|
|
|
|
|
|
gst_buffer_map (ret, &map, GST_MAP_WRITE);
|
|
|
|
|
2022-05-13 05:19:43 +00:00
|
|
|
len = convert_cea708_cc_data_to_cdp (GST_OBJECT (self), CDP_MODE,
|
|
|
|
self->cdp_hdr_sequence_cntr, cc_data, cc_data_len, map.data, map.size,
|
|
|
|
tc, fps_entry);
|
cccombiner: implement scheduling
Prior to that, cccombiner's behaviour was essentially that of
a funnel: it strictly looked at input timestamps to associate
together video and caption buffers.
This patch instead exposes a "schedule" property, with a default
of TRUE, to control whether caption buffers should be smoothly
scheduled, in order to have exactly one per output video buffer.
This can involve rewriting input captions, for example when the
input is CDP sequence counters are rewritten, time codes are dropped
and potentially re-injected if the input video frame had a time code
meta.
Caption buffers may also get split up in order to assign captions to
the correct field when the input is interlaced.
This can also imply that the input will drift from synchronization,
when there isn't enough padding in the input stream to catch up. In
that case the element will start dropping old caption buffers once
the number of buffers in its internal queue reaches a certain limit
(configurable).
The property is exposed so that existing users of cccombiner can
revert back to the original behaviour, but should eventually be
removed, as that behaviour was simply inadequate.
This commit also disallows changing the input caption type, as
this would needlessly complicate implementation, and removes
the corresponding test.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2076>
2021-03-09 12:22:10 +00:00
|
|
|
self->cdp_hdr_sequence_cntr++;
|
|
|
|
|
|
|
|
gst_buffer_unmap (ret, &map);
|
|
|
|
|
|
|
|
gst_buffer_set_size (ret, len);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static GstBuffer *
|
2022-06-01 11:24:41 +00:00
|
|
|
make_buffer (GstCCCombiner * self, const guint8 * cc_data, guint cc_data_len)
|
cccombiner: implement scheduling
Prior to that, cccombiner's behaviour was essentially that of
a funnel: it strictly looked at input timestamps to associate
together video and caption buffers.
This patch instead exposes a "schedule" property, with a default
of TRUE, to control whether caption buffers should be smoothly
scheduled, in order to have exactly one per output video buffer.
This can involve rewriting input captions, for example when the
input is CDP sequence counters are rewritten, time codes are dropped
and potentially re-injected if the input video frame had a time code
meta.
Caption buffers may also get split up in order to assign captions to
the correct field when the input is interlaced.
This can also imply that the input will drift from synchronization,
when there isn't enough padding in the input stream to catch up. In
that case the element will start dropping old caption buffers once
the number of buffers in its internal queue reaches a certain limit
(configurable).
The property is exposed so that existing users of cccombiner can
revert back to the original behaviour, but should eventually be
removed, as that behaviour was simply inadequate.
This commit also disallows changing the input caption type, as
this would needlessly complicate implementation, and removes
the corresponding test.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2076>
2021-03-09 12:22:10 +00:00
|
|
|
{
|
2022-06-01 11:24:41 +00:00
|
|
|
GstBuffer *ret = gst_buffer_new_allocate (NULL, cc_data_len, NULL);
|
|
|
|
gst_buffer_fill (ret, 0, cc_data, cc_data_len);
|
|
|
|
return ret;
|
|
|
|
}
|
cccombiner: implement scheduling
Prior to that, cccombiner's behaviour was essentially that of
a funnel: it strictly looked at input timestamps to associate
together video and caption buffers.
This patch instead exposes a "schedule" property, with a default
of TRUE, to control whether caption buffers should be smoothly
scheduled, in order to have exactly one per output video buffer.
This can involve rewriting input captions, for example when the
input is CDP sequence counters are rewritten, time codes are dropped
and potentially re-injected if the input video frame had a time code
meta.
Caption buffers may also get split up in order to assign captions to
the correct field when the input is interlaced.
This can also imply that the input will drift from synchronization,
when there isn't enough padding in the input stream to catch up. In
that case the element will start dropping old caption buffers once
the number of buffers in its internal queue reaches a certain limit
(configurable).
The property is exposed so that existing users of cccombiner can
revert back to the original behaviour, but should eventually be
removed, as that behaviour was simply inadequate.
This commit also disallows changing the input caption type, as
this would needlessly complicate implementation, and removes
the corresponding test.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2076>
2021-03-09 12:22:10 +00:00
|
|
|
|
2022-06-01 11:24:41 +00:00
|
|
|
static void
|
|
|
|
write_cc_data_to (GstCCCombiner * self, GstBuffer * buffer)
|
|
|
|
{
|
|
|
|
GstMapInfo map;
|
|
|
|
guint len;
|
cccombiner: implement scheduling
Prior to that, cccombiner's behaviour was essentially that of
a funnel: it strictly looked at input timestamps to associate
together video and caption buffers.
This patch instead exposes a "schedule" property, with a default
of TRUE, to control whether caption buffers should be smoothly
scheduled, in order to have exactly one per output video buffer.
This can involve rewriting input captions, for example when the
input is CDP sequence counters are rewritten, time codes are dropped
and potentially re-injected if the input video frame had a time code
meta.
Caption buffers may also get split up in order to assign captions to
the correct field when the input is interlaced.
This can also imply that the input will drift from synchronization,
when there isn't enough padding in the input stream to catch up. In
that case the element will start dropping old caption buffers once
the number of buffers in its internal queue reaches a certain limit
(configurable).
The property is exposed so that existing users of cccombiner can
revert back to the original behaviour, but should eventually be
removed, as that behaviour was simply inadequate.
This commit also disallows changing the input caption type, as
this would needlessly complicate implementation, and removes
the corresponding test.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2076>
2021-03-09 12:22:10 +00:00
|
|
|
|
2022-06-01 11:24:41 +00:00
|
|
|
gst_buffer_map (buffer, &map, GST_MAP_WRITE);
|
|
|
|
len = map.size;
|
2024-03-08 07:22:53 +00:00
|
|
|
cc_buffer_take_cc_data (self->cc_buffer, self->cdp_fps_entry, map.data, &len);
|
2022-06-01 11:24:41 +00:00
|
|
|
gst_buffer_unmap (buffer, &map);
|
|
|
|
gst_buffer_set_size (buffer, len);
|
|
|
|
}
|
cccombiner: implement scheduling
Prior to that, cccombiner's behaviour was essentially that of
a funnel: it strictly looked at input timestamps to associate
together video and caption buffers.
This patch instead exposes a "schedule" property, with a default
of TRUE, to control whether caption buffers should be smoothly
scheduled, in order to have exactly one per output video buffer.
This can involve rewriting input captions, for example when the
input is CDP sequence counters are rewritten, time codes are dropped
and potentially re-injected if the input video frame had a time code
meta.
Caption buffers may also get split up in order to assign captions to
the correct field when the input is interlaced.
This can also imply that the input will drift from synchronization,
when there isn't enough padding in the input stream to catch up. In
that case the element will start dropping old caption buffers once
the number of buffers in its internal queue reaches a certain limit
(configurable).
The property is exposed so that existing users of cccombiner can
revert back to the original behaviour, but should eventually be
removed, as that behaviour was simply inadequate.
This commit also disallows changing the input caption type, as
this would needlessly complicate implementation, and removes
the corresponding test.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2076>
2021-03-09 12:22:10 +00:00
|
|
|
|
2022-06-01 11:24:41 +00:00
|
|
|
static void
|
|
|
|
prepend_s334_to_cea608 (guint field, guint8 * data, guint * len,
|
|
|
|
guint alloc_len)
|
|
|
|
{
|
|
|
|
int i;
|
cccombiner: implement scheduling
Prior to that, cccombiner's behaviour was essentially that of
a funnel: it strictly looked at input timestamps to associate
together video and caption buffers.
This patch instead exposes a "schedule" property, with a default
of TRUE, to control whether caption buffers should be smoothly
scheduled, in order to have exactly one per output video buffer.
This can involve rewriting input captions, for example when the
input is CDP sequence counters are rewritten, time codes are dropped
and potentially re-injected if the input video frame had a time code
meta.
Caption buffers may also get split up in order to assign captions to
the correct field when the input is interlaced.
This can also imply that the input will drift from synchronization,
when there isn't enough padding in the input stream to catch up. In
that case the element will start dropping old caption buffers once
the number of buffers in its internal queue reaches a certain limit
(configurable).
The property is exposed so that existing users of cccombiner can
revert back to the original behaviour, but should eventually be
removed, as that behaviour was simply inadequate.
This commit also disallows changing the input caption type, as
this would needlessly complicate implementation, and removes
the corresponding test.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2076>
2021-03-09 12:22:10 +00:00
|
|
|
|
2022-06-01 11:24:41 +00:00
|
|
|
g_assert (*len / 2 * 3 <= alloc_len);
|
cccombiner: implement scheduling
Prior to that, cccombiner's behaviour was essentially that of
a funnel: it strictly looked at input timestamps to associate
together video and caption buffers.
This patch instead exposes a "schedule" property, with a default
of TRUE, to control whether caption buffers should be smoothly
scheduled, in order to have exactly one per output video buffer.
This can involve rewriting input captions, for example when the
input is CDP sequence counters are rewritten, time codes are dropped
and potentially re-injected if the input video frame had a time code
meta.
Caption buffers may also get split up in order to assign captions to
the correct field when the input is interlaced.
This can also imply that the input will drift from synchronization,
when there isn't enough padding in the input stream to catch up. In
that case the element will start dropping old caption buffers once
the number of buffers in its internal queue reaches a certain limit
(configurable).
The property is exposed so that existing users of cccombiner can
revert back to the original behaviour, but should eventually be
removed, as that behaviour was simply inadequate.
This commit also disallows changing the input caption type, as
this would needlessly complicate implementation, and removes
the corresponding test.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2076>
2021-03-09 12:22:10 +00:00
|
|
|
|
2022-06-01 11:24:41 +00:00
|
|
|
for (i = *len / 2; i >= 0; i--) {
|
|
|
|
data[i * 3 + 2] = data[i * 2 + 1];
|
2023-03-02 16:23:44 +00:00
|
|
|
data[i * 3 + 1] = data[i * 2 + 0];
|
|
|
|
data[i * 3 + 0] = field == 0 ? 0x80 : 0x00;
|
cccombiner: implement scheduling
Prior to that, cccombiner's behaviour was essentially that of
a funnel: it strictly looked at input timestamps to associate
together video and caption buffers.
This patch instead exposes a "schedule" property, with a default
of TRUE, to control whether caption buffers should be smoothly
scheduled, in order to have exactly one per output video buffer.
This can involve rewriting input captions, for example when the
input is CDP sequence counters are rewritten, time codes are dropped
and potentially re-injected if the input video frame had a time code
meta.
Caption buffers may also get split up in order to assign captions to
the correct field when the input is interlaced.
This can also imply that the input will drift from synchronization,
when there isn't enough padding in the input stream to catch up. In
that case the element will start dropping old caption buffers once
the number of buffers in its internal queue reaches a certain limit
(configurable).
The property is exposed so that existing users of cccombiner can
revert back to the original behaviour, but should eventually be
removed, as that behaviour was simply inadequate.
This commit also disallows changing the input caption type, as
this would needlessly complicate implementation, and removes
the corresponding test.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2076>
2021-03-09 12:22:10 +00:00
|
|
|
}
|
2023-03-02 16:23:44 +00:00
|
|
|
|
|
|
|
*len = *len * 3 / 2;
|
cccombiner: implement scheduling
Prior to that, cccombiner's behaviour was essentially that of
a funnel: it strictly looked at input timestamps to associate
together video and caption buffers.
This patch instead exposes a "schedule" property, with a default
of TRUE, to control whether caption buffers should be smoothly
scheduled, in order to have exactly one per output video buffer.
This can involve rewriting input captions, for example when the
input is CDP sequence counters are rewritten, time codes are dropped
and potentially re-injected if the input video frame had a time code
meta.
Caption buffers may also get split up in order to assign captions to
the correct field when the input is interlaced.
This can also imply that the input will drift from synchronization,
when there isn't enough padding in the input stream to catch up. In
that case the element will start dropping old caption buffers once
the number of buffers in its internal queue reaches a certain limit
(configurable).
The property is exposed so that existing users of cccombiner can
revert back to the original behaviour, but should eventually be
removed, as that behaviour was simply inadequate.
This commit also disallows changing the input caption type, as
this would needlessly complicate implementation, and removes
the corresponding test.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2076>
2021-03-09 12:22:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2022-06-01 11:24:41 +00:00
|
|
|
take_s334_both_fields (GstCCCombiner * self, GstBuffer * buffer)
|
cccombiner: implement scheduling
Prior to that, cccombiner's behaviour was essentially that of
a funnel: it strictly looked at input timestamps to associate
together video and caption buffers.
This patch instead exposes a "schedule" property, with a default
of TRUE, to control whether caption buffers should be smoothly
scheduled, in order to have exactly one per output video buffer.
This can involve rewriting input captions, for example when the
input is CDP sequence counters are rewritten, time codes are dropped
and potentially re-injected if the input video frame had a time code
meta.
Caption buffers may also get split up in order to assign captions to
the correct field when the input is interlaced.
This can also imply that the input will drift from synchronization,
when there isn't enough padding in the input stream to catch up. In
that case the element will start dropping old caption buffers once
the number of buffers in its internal queue reaches a certain limit
(configurable).
The property is exposed so that existing users of cccombiner can
revert back to the original behaviour, but should eventually be
removed, as that behaviour was simply inadequate.
This commit also disallows changing the input caption type, as
this would needlessly complicate implementation, and removes
the corresponding test.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2076>
2021-03-09 12:22:10 +00:00
|
|
|
{
|
2022-06-01 11:24:41 +00:00
|
|
|
GstMapInfo out = GST_MAP_INFO_INIT;
|
|
|
|
guint s334_len, cc_data_len, i;
|
|
|
|
|
|
|
|
gst_buffer_map (buffer, &out, GST_MAP_READWRITE);
|
|
|
|
|
|
|
|
cc_data_len = out.size;
|
2024-03-08 07:22:53 +00:00
|
|
|
cc_buffer_take_cc_data (self->cc_buffer, self->cdp_fps_entry,
|
2023-05-05 05:17:16 +00:00
|
|
|
out.data, &cc_data_len);
|
2022-06-01 11:24:41 +00:00
|
|
|
s334_len = drop_ccp_from_cc_data (out.data, cc_data_len);
|
|
|
|
if (s334_len < 0) {
|
|
|
|
s334_len = 0;
|
|
|
|
goto out;
|
cccombiner: implement scheduling
Prior to that, cccombiner's behaviour was essentially that of
a funnel: it strictly looked at input timestamps to associate
together video and caption buffers.
This patch instead exposes a "schedule" property, with a default
of TRUE, to control whether caption buffers should be smoothly
scheduled, in order to have exactly one per output video buffer.
This can involve rewriting input captions, for example when the
input is CDP sequence counters are rewritten, time codes are dropped
and potentially re-injected if the input video frame had a time code
meta.
Caption buffers may also get split up in order to assign captions to
the correct field when the input is interlaced.
This can also imply that the input will drift from synchronization,
when there isn't enough padding in the input stream to catch up. In
that case the element will start dropping old caption buffers once
the number of buffers in its internal queue reaches a certain limit
(configurable).
The property is exposed so that existing users of cccombiner can
revert back to the original behaviour, but should eventually be
removed, as that behaviour was simply inadequate.
This commit also disallows changing the input caption type, as
this would needlessly complicate implementation, and removes
the corresponding test.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2076>
2021-03-09 12:22:10 +00:00
|
|
|
}
|
|
|
|
|
2022-06-01 11:24:41 +00:00
|
|
|
for (i = 0; i < s334_len / 3; i++) {
|
|
|
|
guint byte = out.data[i * 3];
|
|
|
|
/* We have to assume a line offset of 0 */
|
|
|
|
out.data[i * 3] = (byte == 0xfc || byte == 0xf8) ? 0x80 : 0x00;
|
cccombiner: implement scheduling
Prior to that, cccombiner's behaviour was essentially that of
a funnel: it strictly looked at input timestamps to associate
together video and caption buffers.
This patch instead exposes a "schedule" property, with a default
of TRUE, to control whether caption buffers should be smoothly
scheduled, in order to have exactly one per output video buffer.
This can involve rewriting input captions, for example when the
input is CDP sequence counters are rewritten, time codes are dropped
and potentially re-injected if the input video frame had a time code
meta.
Caption buffers may also get split up in order to assign captions to
the correct field when the input is interlaced.
This can also imply that the input will drift from synchronization,
when there isn't enough padding in the input stream to catch up. In
that case the element will start dropping old caption buffers once
the number of buffers in its internal queue reaches a certain limit
(configurable).
The property is exposed so that existing users of cccombiner can
revert back to the original behaviour, but should eventually be
removed, as that behaviour was simply inadequate.
This commit also disallows changing the input caption type, as
this would needlessly complicate implementation, and removes
the corresponding test.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2076>
2021-03-09 12:22:10 +00:00
|
|
|
}
|
|
|
|
|
2022-06-01 11:24:41 +00:00
|
|
|
out:
|
|
|
|
gst_buffer_unmap (buffer, &out);
|
|
|
|
gst_buffer_set_size (buffer, s334_len);
|
cccombiner: implement scheduling
Prior to that, cccombiner's behaviour was essentially that of
a funnel: it strictly looked at input timestamps to associate
together video and caption buffers.
This patch instead exposes a "schedule" property, with a default
of TRUE, to control whether caption buffers should be smoothly
scheduled, in order to have exactly one per output video buffer.
This can involve rewriting input captions, for example when the
input is CDP sequence counters are rewritten, time codes are dropped
and potentially re-injected if the input video frame had a time code
meta.
Caption buffers may also get split up in order to assign captions to
the correct field when the input is interlaced.
This can also imply that the input will drift from synchronization,
when there isn't enough padding in the input stream to catch up. In
that case the element will start dropping old caption buffers once
the number of buffers in its internal queue reaches a certain limit
(configurable).
The property is exposed so that existing users of cccombiner can
revert back to the original behaviour, but should eventually be
removed, as that behaviour was simply inadequate.
This commit also disallows changing the input caption type, as
this would needlessly complicate implementation, and removes
the corresponding test.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2076>
2021-03-09 12:22:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
schedule_cdp (GstCCCombiner * self, const GstVideoTimeCode * tc,
|
|
|
|
const guint8 * data, guint len, GstClockTime pts, GstClockTime duration)
|
|
|
|
{
|
2022-05-30 11:39:13 +00:00
|
|
|
guint8 cc_data[MAX_CDP_PACKET_LEN];
|
cccombiner: implement scheduling
Prior to that, cccombiner's behaviour was essentially that of
a funnel: it strictly looked at input timestamps to associate
together video and caption buffers.
This patch instead exposes a "schedule" property, with a default
of TRUE, to control whether caption buffers should be smoothly
scheduled, in order to have exactly one per output video buffer.
This can involve rewriting input captions, for example when the
input is CDP sequence counters are rewritten, time codes are dropped
and potentially re-injected if the input video frame had a time code
meta.
Caption buffers may also get split up in order to assign captions to
the correct field when the input is interlaced.
This can also imply that the input will drift from synchronization,
when there isn't enough padding in the input stream to catch up. In
that case the element will start dropping old caption buffers once
the number of buffers in its internal queue reaches a certain limit
(configurable).
The property is exposed so that existing users of cccombiner can
revert back to the original behaviour, but should eventually be
removed, as that behaviour was simply inadequate.
This commit also disallows changing the input caption type, as
this would needlessly complicate implementation, and removes
the corresponding test.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2076>
2021-03-09 12:22:10 +00:00
|
|
|
guint cc_data_len;
|
|
|
|
|
2022-05-30 11:39:13 +00:00
|
|
|
cc_data_len = extract_cdp (self, data, len, cc_data);
|
2022-06-01 11:24:41 +00:00
|
|
|
if (cc_buffer_push_cc_data (self->cc_buffer, cc_data, cc_data_len))
|
|
|
|
self->current_scheduled++;
|
cccombiner: implement scheduling
Prior to that, cccombiner's behaviour was essentially that of
a funnel: it strictly looked at input timestamps to associate
together video and caption buffers.
This patch instead exposes a "schedule" property, with a default
of TRUE, to control whether caption buffers should be smoothly
scheduled, in order to have exactly one per output video buffer.
This can involve rewriting input captions, for example when the
input is CDP sequence counters are rewritten, time codes are dropped
and potentially re-injected if the input video frame had a time code
meta.
Caption buffers may also get split up in order to assign captions to
the correct field when the input is interlaced.
This can also imply that the input will drift from synchronization,
when there isn't enough padding in the input stream to catch up. In
that case the element will start dropping old caption buffers once
the number of buffers in its internal queue reaches a certain limit
(configurable).
The property is exposed so that existing users of cccombiner can
revert back to the original behaviour, but should eventually be
removed, as that behaviour was simply inadequate.
This commit also disallows changing the input caption type, as
this would needlessly complicate implementation, and removes
the corresponding test.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2076>
2021-03-09 12:22:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
schedule_cea608_s334_1a (GstCCCombiner * self, guint8 * data, guint len,
|
|
|
|
GstClockTime pts, GstClockTime duration)
|
|
|
|
{
|
|
|
|
guint8 field0_data[3], field1_data[3];
|
|
|
|
guint field0_len = 0, field1_len = 0;
|
|
|
|
guint i;
|
|
|
|
|
|
|
|
if (len % 3 != 0) {
|
|
|
|
GST_WARNING ("Invalid cc_data buffer size %u. Truncating to a multiple "
|
|
|
|
"of 3", len);
|
|
|
|
len = len - (len % 3);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < len / 3; i++) {
|
2022-01-07 23:16:29 +00:00
|
|
|
if (data[i * 3] & 0x80) {
|
cccombiner: implement scheduling
Prior to that, cccombiner's behaviour was essentially that of
a funnel: it strictly looked at input timestamps to associate
together video and caption buffers.
This patch instead exposes a "schedule" property, with a default
of TRUE, to control whether caption buffers should be smoothly
scheduled, in order to have exactly one per output video buffer.
This can involve rewriting input captions, for example when the
input is CDP sequence counters are rewritten, time codes are dropped
and potentially re-injected if the input video frame had a time code
meta.
Caption buffers may also get split up in order to assign captions to
the correct field when the input is interlaced.
This can also imply that the input will drift from synchronization,
when there isn't enough padding in the input stream to catch up. In
that case the element will start dropping old caption buffers once
the number of buffers in its internal queue reaches a certain limit
(configurable).
The property is exposed so that existing users of cccombiner can
revert back to the original behaviour, but should eventually be
removed, as that behaviour was simply inadequate.
This commit also disallows changing the input caption type, as
this would needlessly complicate implementation, and removes
the corresponding test.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2076>
2021-03-09 12:22:10 +00:00
|
|
|
if (data[i * 3 + 1] == 0x80 && data[i * 3 + 2] == 0x80)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
field0_data[field0_len++] = data[i * 3 + 1];
|
|
|
|
field0_data[field0_len++] = data[i * 3 + 2];
|
2022-01-07 23:16:29 +00:00
|
|
|
} else {
|
cccombiner: implement scheduling
Prior to that, cccombiner's behaviour was essentially that of
a funnel: it strictly looked at input timestamps to associate
together video and caption buffers.
This patch instead exposes a "schedule" property, with a default
of TRUE, to control whether caption buffers should be smoothly
scheduled, in order to have exactly one per output video buffer.
This can involve rewriting input captions, for example when the
input is CDP sequence counters are rewritten, time codes are dropped
and potentially re-injected if the input video frame had a time code
meta.
Caption buffers may also get split up in order to assign captions to
the correct field when the input is interlaced.
This can also imply that the input will drift from synchronization,
when there isn't enough padding in the input stream to catch up. In
that case the element will start dropping old caption buffers once
the number of buffers in its internal queue reaches a certain limit
(configurable).
The property is exposed so that existing users of cccombiner can
revert back to the original behaviour, but should eventually be
removed, as that behaviour was simply inadequate.
This commit also disallows changing the input caption type, as
this would needlessly complicate implementation, and removes
the corresponding test.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2076>
2021-03-09 12:22:10 +00:00
|
|
|
if (data[i * 3 + 1] == 0x80 && data[i * 3 + 2] == 0x80)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
field1_data[field1_len++] = data[i * 3 + 1];
|
|
|
|
field1_data[field1_len++] = data[i * 3 + 2];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-06-01 11:24:41 +00:00
|
|
|
if (cc_buffer_push_separated (self->cc_buffer, field0_data, field0_len,
|
|
|
|
field1_data, field1_len, NULL, 0))
|
|
|
|
self->current_scheduled++;
|
cccombiner: implement scheduling
Prior to that, cccombiner's behaviour was essentially that of
a funnel: it strictly looked at input timestamps to associate
together video and caption buffers.
This patch instead exposes a "schedule" property, with a default
of TRUE, to control whether caption buffers should be smoothly
scheduled, in order to have exactly one per output video buffer.
This can involve rewriting input captions, for example when the
input is CDP sequence counters are rewritten, time codes are dropped
and potentially re-injected if the input video frame had a time code
meta.
Caption buffers may also get split up in order to assign captions to
the correct field when the input is interlaced.
This can also imply that the input will drift from synchronization,
when there isn't enough padding in the input stream to catch up. In
that case the element will start dropping old caption buffers once
the number of buffers in its internal queue reaches a certain limit
(configurable).
The property is exposed so that existing users of cccombiner can
revert back to the original behaviour, but should eventually be
removed, as that behaviour was simply inadequate.
This commit also disallows changing the input caption type, as
this would needlessly complicate implementation, and removes
the corresponding test.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2076>
2021-03-09 12:22:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
schedule_cea708_raw (GstCCCombiner * self, guint8 * data, guint len,
|
|
|
|
GstClockTime pts, GstClockTime duration)
|
|
|
|
{
|
2022-06-01 11:24:41 +00:00
|
|
|
if (cc_buffer_push_cc_data (self->cc_buffer, data, len))
|
|
|
|
self->current_scheduled++;
|
cccombiner: implement scheduling
Prior to that, cccombiner's behaviour was essentially that of
a funnel: it strictly looked at input timestamps to associate
together video and caption buffers.
This patch instead exposes a "schedule" property, with a default
of TRUE, to control whether caption buffers should be smoothly
scheduled, in order to have exactly one per output video buffer.
This can involve rewriting input captions, for example when the
input is CDP sequence counters are rewritten, time codes are dropped
and potentially re-injected if the input video frame had a time code
meta.
Caption buffers may also get split up in order to assign captions to
the correct field when the input is interlaced.
This can also imply that the input will drift from synchronization,
when there isn't enough padding in the input stream to catch up. In
that case the element will start dropping old caption buffers once
the number of buffers in its internal queue reaches a certain limit
(configurable).
The property is exposed so that existing users of cccombiner can
revert back to the original behaviour, but should eventually be
removed, as that behaviour was simply inadequate.
This commit also disallows changing the input caption type, as
this would needlessly complicate implementation, and removes
the corresponding test.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2076>
2021-03-09 12:22:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2022-06-01 11:24:41 +00:00
|
|
|
schedule_cea608_raw (GstCCCombiner * self, guint8 * data, guint len)
|
cccombiner: implement scheduling
Prior to that, cccombiner's behaviour was essentially that of
a funnel: it strictly looked at input timestamps to associate
together video and caption buffers.
This patch instead exposes a "schedule" property, with a default
of TRUE, to control whether caption buffers should be smoothly
scheduled, in order to have exactly one per output video buffer.
This can involve rewriting input captions, for example when the
input is CDP sequence counters are rewritten, time codes are dropped
and potentially re-injected if the input video frame had a time code
meta.
Caption buffers may also get split up in order to assign captions to
the correct field when the input is interlaced.
This can also imply that the input will drift from synchronization,
when there isn't enough padding in the input stream to catch up. In
that case the element will start dropping old caption buffers once
the number of buffers in its internal queue reaches a certain limit
(configurable).
The property is exposed so that existing users of cccombiner can
revert back to the original behaviour, but should eventually be
removed, as that behaviour was simply inadequate.
This commit also disallows changing the input caption type, as
this would needlessly complicate implementation, and removes
the corresponding test.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2076>
2021-03-09 12:22:10 +00:00
|
|
|
{
|
2022-06-01 11:24:41 +00:00
|
|
|
if (cc_buffer_push_separated (self->cc_buffer, data, len, NULL, 0, NULL, 0))
|
|
|
|
self->current_scheduled++;
|
cccombiner: implement scheduling
Prior to that, cccombiner's behaviour was essentially that of
a funnel: it strictly looked at input timestamps to associate
together video and caption buffers.
This patch instead exposes a "schedule" property, with a default
of TRUE, to control whether caption buffers should be smoothly
scheduled, in order to have exactly one per output video buffer.
This can involve rewriting input captions, for example when the
input is CDP sequence counters are rewritten, time codes are dropped
and potentially re-injected if the input video frame had a time code
meta.
Caption buffers may also get split up in order to assign captions to
the correct field when the input is interlaced.
This can also imply that the input will drift from synchronization,
when there isn't enough padding in the input stream to catch up. In
that case the element will start dropping old caption buffers once
the number of buffers in its internal queue reaches a certain limit
(configurable).
The property is exposed so that existing users of cccombiner can
revert back to the original behaviour, but should eventually be
removed, as that behaviour was simply inadequate.
This commit also disallows changing the input caption type, as
this would needlessly complicate implementation, and removes
the corresponding test.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2076>
2021-03-09 12:22:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2024-11-26 15:27:19 +00:00
|
|
|
schedule_caption (GstCCCombiner * self, GstAggregatorPad * caption_pad,
|
|
|
|
GstBuffer * caption_buf, const GstVideoTimeCode * tc)
|
cccombiner: implement scheduling
Prior to that, cccombiner's behaviour was essentially that of
a funnel: it strictly looked at input timestamps to associate
together video and caption buffers.
This patch instead exposes a "schedule" property, with a default
of TRUE, to control whether caption buffers should be smoothly
scheduled, in order to have exactly one per output video buffer.
This can involve rewriting input captions, for example when the
input is CDP sequence counters are rewritten, time codes are dropped
and potentially re-injected if the input video frame had a time code
meta.
Caption buffers may also get split up in order to assign captions to
the correct field when the input is interlaced.
This can also imply that the input will drift from synchronization,
when there isn't enough padding in the input stream to catch up. In
that case the element will start dropping old caption buffers once
the number of buffers in its internal queue reaches a certain limit
(configurable).
The property is exposed so that existing users of cccombiner can
revert back to the original behaviour, but should eventually be
removed, as that behaviour was simply inadequate.
This commit also disallows changing the input caption type, as
this would needlessly complicate implementation, and removes
the corresponding test.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2076>
2021-03-09 12:22:10 +00:00
|
|
|
{
|
|
|
|
GstMapInfo map;
|
2024-03-12 03:25:31 +00:00
|
|
|
GstClockTime pts, duration, running_time;
|
cccombiner: implement scheduling
Prior to that, cccombiner's behaviour was essentially that of
a funnel: it strictly looked at input timestamps to associate
together video and caption buffers.
This patch instead exposes a "schedule" property, with a default
of TRUE, to control whether caption buffers should be smoothly
scheduled, in order to have exactly one per output video buffer.
This can involve rewriting input captions, for example when the
input is CDP sequence counters are rewritten, time codes are dropped
and potentially re-injected if the input video frame had a time code
meta.
Caption buffers may also get split up in order to assign captions to
the correct field when the input is interlaced.
This can also imply that the input will drift from synchronization,
when there isn't enough padding in the input stream to catch up. In
that case the element will start dropping old caption buffers once
the number of buffers in its internal queue reaches a certain limit
(configurable).
The property is exposed so that existing users of cccombiner can
revert back to the original behaviour, but should eventually be
removed, as that behaviour was simply inadequate.
This commit also disallows changing the input caption type, as
this would needlessly complicate implementation, and removes
the corresponding test.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2076>
2021-03-09 12:22:10 +00:00
|
|
|
|
|
|
|
pts = GST_BUFFER_PTS (caption_buf);
|
|
|
|
duration = GST_BUFFER_DURATION (caption_buf);
|
|
|
|
|
2024-03-12 03:25:31 +00:00
|
|
|
running_time =
|
|
|
|
gst_segment_to_running_time (&caption_pad->segment, GST_FORMAT_TIME, pts);
|
2022-06-01 11:24:41 +00:00
|
|
|
|
2024-03-12 03:25:31 +00:00
|
|
|
if (self->current_scheduled + 1 >= self->max_scheduled) {
|
|
|
|
GstClockTime stream_time;
|
2022-06-01 11:24:41 +00:00
|
|
|
|
|
|
|
GST_WARNING_OBJECT (self,
|
|
|
|
"scheduled queue runs too long, discarding stored");
|
|
|
|
|
|
|
|
stream_time =
|
|
|
|
gst_segment_to_stream_time (&caption_pad->segment, GST_FORMAT_TIME,
|
|
|
|
pts);
|
|
|
|
|
|
|
|
gst_element_post_message (GST_ELEMENT_CAST (self),
|
|
|
|
gst_message_new_qos (GST_OBJECT_CAST (self), FALSE,
|
|
|
|
running_time, stream_time, pts, duration));
|
|
|
|
|
|
|
|
cc_buffer_discard (self->cc_buffer);
|
|
|
|
self->current_scheduled = 0;
|
|
|
|
}
|
|
|
|
|
2024-03-12 03:25:31 +00:00
|
|
|
self->last_caption_ts = running_time;
|
|
|
|
|
cccombiner: implement scheduling
Prior to that, cccombiner's behaviour was essentially that of
a funnel: it strictly looked at input timestamps to associate
together video and caption buffers.
This patch instead exposes a "schedule" property, with a default
of TRUE, to control whether caption buffers should be smoothly
scheduled, in order to have exactly one per output video buffer.
This can involve rewriting input captions, for example when the
input is CDP sequence counters are rewritten, time codes are dropped
and potentially re-injected if the input video frame had a time code
meta.
Caption buffers may also get split up in order to assign captions to
the correct field when the input is interlaced.
This can also imply that the input will drift from synchronization,
when there isn't enough padding in the input stream to catch up. In
that case the element will start dropping old caption buffers once
the number of buffers in its internal queue reaches a certain limit
(configurable).
The property is exposed so that existing users of cccombiner can
revert back to the original behaviour, but should eventually be
removed, as that behaviour was simply inadequate.
This commit also disallows changing the input caption type, as
this would needlessly complicate implementation, and removes
the corresponding test.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2076>
2021-03-09 12:22:10 +00:00
|
|
|
gst_buffer_map (caption_buf, &map, GST_MAP_READ);
|
|
|
|
|
|
|
|
switch (self->caption_type) {
|
|
|
|
case GST_VIDEO_CAPTION_TYPE_CEA708_CDP:
|
|
|
|
schedule_cdp (self, tc, map.data, map.size, pts, duration);
|
|
|
|
break;
|
|
|
|
case GST_VIDEO_CAPTION_TYPE_CEA708_RAW:
|
|
|
|
schedule_cea708_raw (self, map.data, map.size, pts, duration);
|
|
|
|
break;
|
|
|
|
case GST_VIDEO_CAPTION_TYPE_CEA608_S334_1A:
|
|
|
|
schedule_cea608_s334_1a (self, map.data, map.size, pts, duration);
|
|
|
|
break;
|
|
|
|
case GST_VIDEO_CAPTION_TYPE_CEA608_RAW:
|
2022-06-01 11:24:41 +00:00
|
|
|
schedule_cea608_raw (self, map.data, map.size);
|
cccombiner: implement scheduling
Prior to that, cccombiner's behaviour was essentially that of
a funnel: it strictly looked at input timestamps to associate
together video and caption buffers.
This patch instead exposes a "schedule" property, with a default
of TRUE, to control whether caption buffers should be smoothly
scheduled, in order to have exactly one per output video buffer.
This can involve rewriting input captions, for example when the
input is CDP sequence counters are rewritten, time codes are dropped
and potentially re-injected if the input video frame had a time code
meta.
Caption buffers may also get split up in order to assign captions to
the correct field when the input is interlaced.
This can also imply that the input will drift from synchronization,
when there isn't enough padding in the input stream to catch up. In
that case the element will start dropping old caption buffers once
the number of buffers in its internal queue reaches a certain limit
(configurable).
The property is exposed so that existing users of cccombiner can
revert back to the original behaviour, but should eventually be
removed, as that behaviour was simply inadequate.
This commit also disallows changing the input caption type, as
this would needlessly complicate implementation, and removes
the corresponding test.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2076>
2021-03-09 12:22:10 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
gst_buffer_unmap (caption_buf, &map);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2022-06-01 11:24:41 +00:00
|
|
|
dequeue_caption (GstCCCombiner * self, GstVideoTimeCode * tc, gboolean drain)
|
2022-01-05 21:48:31 +00:00
|
|
|
{
|
2022-06-01 11:24:41 +00:00
|
|
|
guint8 cea608_1[MAX_CEA608_LEN], cea608_2[MAX_CEA608_LEN];
|
|
|
|
guint8 cc_data[MAX_CDP_PACKET_LEN];
|
|
|
|
guint cea608_1_len = MAX_CEA608_LEN, cea608_2_len = MAX_CEA608_LEN;
|
|
|
|
guint cc_data_len = MAX_CDP_PACKET_LEN;
|
2022-01-05 21:48:31 +00:00
|
|
|
CaptionData caption_data;
|
|
|
|
|
2022-06-01 11:24:41 +00:00
|
|
|
g_assert (self->current_frame_captions->len == 0);
|
2022-01-05 21:48:31 +00:00
|
|
|
|
2022-06-01 11:24:41 +00:00
|
|
|
if (drain && cc_buffer_is_empty (self->cc_buffer))
|
2022-01-05 21:48:31 +00:00
|
|
|
return;
|
|
|
|
|
2024-03-12 03:25:31 +00:00
|
|
|
if (self->prop_schedule_timeout != GST_CLOCK_TIME_NONE) {
|
|
|
|
if (self->last_caption_ts == GST_CLOCK_TIME_NONE) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (self->current_video_running_time > self->last_caption_ts
|
|
|
|
&& self->current_video_running_time - self->last_caption_ts
|
|
|
|
> self->prop_schedule_timeout) {
|
|
|
|
GST_LOG_OBJECT (self, "Not outputting caption as last caption buffer ts %"
|
|
|
|
GST_TIME_FORMAT " is more than the schedule timeout %" GST_TIME_FORMAT
|
|
|
|
" from the current output time %" GST_TIME_FORMAT,
|
|
|
|
GST_TIME_ARGS (self->last_caption_ts),
|
|
|
|
GST_TIME_ARGS (self->prop_schedule_timeout),
|
|
|
|
GST_TIME_ARGS (self->current_video_running_time));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-06-01 11:24:41 +00:00
|
|
|
caption_data.caption_type = self->caption_type;
|
|
|
|
switch (self->caption_type) {
|
|
|
|
case GST_VIDEO_CAPTION_TYPE_CEA708_CDP:
|
|
|
|
{
|
|
|
|
/* Only relevant in alternate and mixed mode, no need to look at the caps */
|
|
|
|
if (GST_BUFFER_FLAG_IS_SET (self->current_video_buffer,
|
|
|
|
GST_VIDEO_BUFFER_FLAG_INTERLACED)) {
|
|
|
|
if (!GST_VIDEO_BUFFER_IS_BOTTOM_FIELD (self->current_video_buffer)) {
|
2024-03-08 07:22:53 +00:00
|
|
|
cc_buffer_take_cc_data (self->cc_buffer, self->cdp_fps_entry,
|
2023-05-05 05:17:16 +00:00
|
|
|
cc_data, &cc_data_len);
|
2022-06-01 11:24:41 +00:00
|
|
|
caption_data.buffer =
|
|
|
|
make_cdp_buffer (self, cc_data, cc_data_len, self->cdp_fps_entry,
|
|
|
|
tc);
|
|
|
|
g_array_append_val (self->current_frame_captions, caption_data);
|
|
|
|
}
|
|
|
|
} else {
|
2024-03-08 07:22:53 +00:00
|
|
|
cc_buffer_take_cc_data (self->cc_buffer, self->cdp_fps_entry,
|
2023-05-05 05:17:16 +00:00
|
|
|
cc_data, &cc_data_len);
|
2022-06-01 11:24:41 +00:00
|
|
|
caption_data.buffer =
|
|
|
|
make_cdp_buffer (self, cc_data, cc_data_len, self->cdp_fps_entry,
|
|
|
|
tc);
|
|
|
|
g_array_append_val (self->current_frame_captions, caption_data);
|
|
|
|
}
|
|
|
|
break;
|
2022-02-01 22:46:43 +00:00
|
|
|
}
|
2022-06-01 11:24:41 +00:00
|
|
|
case GST_VIDEO_CAPTION_TYPE_CEA708_RAW:
|
|
|
|
{
|
|
|
|
/* Only relevant in alternate and mixed mode, no need to look at the caps */
|
|
|
|
if (GST_BUFFER_FLAG_IS_SET (self->current_video_buffer,
|
|
|
|
GST_VIDEO_BUFFER_FLAG_INTERLACED)) {
|
|
|
|
if (!GST_VIDEO_BUFFER_IS_BOTTOM_FIELD (self->current_video_buffer)) {
|
|
|
|
caption_data.buffer =
|
|
|
|
gst_buffer_new_allocate (NULL, MAX_CDP_PACKET_LEN, NULL);
|
|
|
|
write_cc_data_to (self, caption_data.buffer);
|
|
|
|
g_array_append_val (self->current_frame_captions, caption_data);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
caption_data.buffer =
|
|
|
|
gst_buffer_new_allocate (NULL, MAX_CDP_PACKET_LEN, NULL);
|
|
|
|
write_cc_data_to (self, caption_data.buffer);
|
|
|
|
g_array_append_val (self->current_frame_captions, caption_data);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case GST_VIDEO_CAPTION_TYPE_CEA608_S334_1A:
|
|
|
|
{
|
|
|
|
if (self->progressive) {
|
|
|
|
cc_buffer_take_separated (self->cc_buffer, self->cdp_fps_entry,
|
|
|
|
cea608_1, &cea608_1_len, cea608_2, &cea608_2_len, cc_data,
|
|
|
|
&cc_data_len);
|
|
|
|
prepend_s334_to_cea608 (0, cea608_1, &cea608_1_len, sizeof (cea608_1));
|
|
|
|
caption_data.buffer = make_buffer (self, cea608_1, cea608_1_len);
|
|
|
|
g_array_append_val (self->current_frame_captions, caption_data);
|
|
|
|
} else if (GST_BUFFER_FLAG_IS_SET (self->current_video_buffer,
|
|
|
|
GST_VIDEO_BUFFER_FLAG_INTERLACED) &&
|
|
|
|
GST_BUFFER_FLAG_IS_SET (self->current_video_buffer,
|
|
|
|
GST_VIDEO_BUFFER_FLAG_ONEFIELD)) {
|
|
|
|
cc_buffer_take_separated (self->cc_buffer, self->cdp_fps_entry,
|
|
|
|
cea608_1, &cea608_1_len, cea608_2, &cea608_2_len, cc_data,
|
|
|
|
&cc_data_len);
|
|
|
|
if (GST_VIDEO_BUFFER_IS_TOP_FIELD (self->current_video_buffer)) {
|
|
|
|
prepend_s334_to_cea608 (0, cea608_1, &cea608_1_len,
|
|
|
|
sizeof (cea608_1));
|
|
|
|
caption_data.buffer = make_buffer (self, cea608_1, cea608_1_len);
|
|
|
|
} else {
|
|
|
|
prepend_s334_to_cea608 (1, cea608_2, &cea608_2_len,
|
|
|
|
sizeof (cea608_2));
|
|
|
|
caption_data.buffer = make_buffer (self, cea608_2, cea608_2_len);
|
|
|
|
}
|
|
|
|
g_array_append_val (self->current_frame_captions, caption_data);
|
|
|
|
} else {
|
|
|
|
caption_data.buffer =
|
|
|
|
gst_buffer_new_allocate (NULL, MAX_CDP_PACKET_LEN, NULL);
|
|
|
|
take_s334_both_fields (self, caption_data.buffer);
|
|
|
|
g_array_append_val (self->current_frame_captions, caption_data);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case GST_VIDEO_CAPTION_TYPE_CEA608_RAW:
|
|
|
|
{
|
|
|
|
cc_buffer_take_separated (self->cc_buffer, self->cdp_fps_entry,
|
|
|
|
cea608_1, &cea608_1_len, cea608_2, &cea608_2_len, cc_data,
|
|
|
|
&cc_data_len);
|
|
|
|
if (self->progressive) {
|
|
|
|
caption_data.buffer = make_buffer (self, cea608_1, cea608_1_len);
|
|
|
|
g_array_append_val (self->current_frame_captions, caption_data);
|
|
|
|
} else if (GST_BUFFER_FLAG_IS_SET (self->current_video_buffer,
|
|
|
|
GST_VIDEO_BUFFER_FLAG_INTERLACED)) {
|
|
|
|
if (!GST_VIDEO_BUFFER_IS_BOTTOM_FIELD (self->current_video_buffer)) {
|
|
|
|
caption_data.buffer = make_buffer (self, cea608_1, cea608_1_len);
|
|
|
|
g_array_append_val (self->current_frame_captions, caption_data);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
caption_data.buffer = make_buffer (self, cea608_1, cea608_1_len);
|
|
|
|
g_array_append_val (self->current_frame_captions, caption_data);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
break;
|
2022-02-01 22:46:43 +00:00
|
|
|
}
|
2022-01-05 21:48:31 +00:00
|
|
|
}
|
|
|
|
|
2024-02-01 17:45:01 +00:00
|
|
|
static gboolean
|
|
|
|
remove_caption_meta (GstBuffer * buffer, GstMeta ** meta, gpointer user_data)
|
|
|
|
{
|
|
|
|
if ((*meta)->info->api == GST_VIDEO_CAPTION_META_API_TYPE)
|
|
|
|
*meta = NULL;
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2018-11-05 14:24:58 +00:00
|
|
|
static GstFlowReturn
|
2019-03-13 12:43:54 +00:00
|
|
|
gst_cc_combiner_collect_captions (GstCCCombiner * self, gboolean timeout)
|
2018-11-05 14:24:58 +00:00
|
|
|
{
|
2019-03-13 12:43:54 +00:00
|
|
|
GstAggregatorPad *src_pad =
|
|
|
|
GST_AGGREGATOR_PAD (GST_AGGREGATOR_SRC_PAD (self));
|
2018-11-05 14:24:58 +00:00
|
|
|
GstAggregatorPad *caption_pad;
|
|
|
|
GstBuffer *video_buf;
|
cccombiner: implement scheduling
Prior to that, cccombiner's behaviour was essentially that of
a funnel: it strictly looked at input timestamps to associate
together video and caption buffers.
This patch instead exposes a "schedule" property, with a default
of TRUE, to control whether caption buffers should be smoothly
scheduled, in order to have exactly one per output video buffer.
This can involve rewriting input captions, for example when the
input is CDP sequence counters are rewritten, time codes are dropped
and potentially re-injected if the input video frame had a time code
meta.
Caption buffers may also get split up in order to assign captions to
the correct field when the input is interlaced.
This can also imply that the input will drift from synchronization,
when there isn't enough padding in the input stream to catch up. In
that case the element will start dropping old caption buffers once
the number of buffers in its internal queue reaches a certain limit
(configurable).
The property is exposed so that existing users of cccombiner can
revert back to the original behaviour, but should eventually be
removed, as that behaviour was simply inadequate.
This commit also disallows changing the input caption type, as
this would needlessly complicate implementation, and removes
the corresponding test.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2076>
2021-03-09 12:22:10 +00:00
|
|
|
GstVideoTimeCodeMeta *tc_meta;
|
|
|
|
GstVideoTimeCode *tc = NULL;
|
2021-10-25 23:09:58 +00:00
|
|
|
gboolean caption_pad_is_eos = FALSE;
|
2018-11-05 14:24:58 +00:00
|
|
|
|
|
|
|
g_assert (self->current_video_buffer != NULL);
|
|
|
|
|
2022-02-18 16:06:44 +00:00
|
|
|
GST_OBJECT_LOCK (self);
|
|
|
|
caption_pad = self->caption_pad ? gst_object_ref (self->caption_pad) : NULL;
|
|
|
|
GST_OBJECT_UNLOCK (self);
|
|
|
|
|
2018-11-05 14:24:58 +00:00
|
|
|
/* No caption pad, forward buffer directly */
|
|
|
|
if (!caption_pad) {
|
|
|
|
GST_LOG_OBJECT (self, "No caption pad, passing through video");
|
|
|
|
video_buf = self->current_video_buffer;
|
2020-08-05 14:57:15 +00:00
|
|
|
gst_aggregator_selected_samples (GST_AGGREGATOR_CAST (self),
|
|
|
|
GST_BUFFER_PTS (video_buf), GST_BUFFER_DTS (video_buf),
|
2020-08-07 06:37:20 +00:00
|
|
|
GST_BUFFER_DURATION (video_buf), NULL);
|
2021-10-26 13:58:26 +00:00
|
|
|
self->current_video_buffer = NULL;
|
2019-03-13 12:43:54 +00:00
|
|
|
goto done;
|
2018-11-05 14:24:58 +00:00
|
|
|
}
|
|
|
|
|
cccombiner: implement scheduling
Prior to that, cccombiner's behaviour was essentially that of
a funnel: it strictly looked at input timestamps to associate
together video and caption buffers.
This patch instead exposes a "schedule" property, with a default
of TRUE, to control whether caption buffers should be smoothly
scheduled, in order to have exactly one per output video buffer.
This can involve rewriting input captions, for example when the
input is CDP sequence counters are rewritten, time codes are dropped
and potentially re-injected if the input video frame had a time code
meta.
Caption buffers may also get split up in order to assign captions to
the correct field when the input is interlaced.
This can also imply that the input will drift from synchronization,
when there isn't enough padding in the input stream to catch up. In
that case the element will start dropping old caption buffers once
the number of buffers in its internal queue reaches a certain limit
(configurable).
The property is exposed so that existing users of cccombiner can
revert back to the original behaviour, but should eventually be
removed, as that behaviour was simply inadequate.
This commit also disallows changing the input caption type, as
this would needlessly complicate implementation, and removes
the corresponding test.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2076>
2021-03-09 12:22:10 +00:00
|
|
|
tc_meta = gst_buffer_get_video_time_code_meta (self->current_video_buffer);
|
|
|
|
|
|
|
|
if (tc_meta) {
|
|
|
|
tc = &tc_meta->tc;
|
|
|
|
}
|
|
|
|
|
2018-11-05 14:24:58 +00:00
|
|
|
GST_LOG_OBJECT (self, "Trying to collect captions for queued video buffer");
|
|
|
|
do {
|
|
|
|
GstBuffer *caption_buf;
|
|
|
|
GstClockTime caption_time;
|
|
|
|
CaptionData caption_data;
|
|
|
|
|
|
|
|
caption_buf = gst_aggregator_pad_peek_buffer (caption_pad);
|
|
|
|
if (!caption_buf) {
|
|
|
|
if (gst_aggregator_pad_is_eos (caption_pad)) {
|
|
|
|
GST_DEBUG_OBJECT (self, "Caption pad is EOS, we're done");
|
2021-10-25 23:09:58 +00:00
|
|
|
|
|
|
|
caption_pad_is_eos = TRUE;
|
2018-11-05 14:24:58 +00:00
|
|
|
break;
|
2019-03-13 12:43:54 +00:00
|
|
|
} else if (!timeout) {
|
2018-11-05 14:24:58 +00:00
|
|
|
GST_DEBUG_OBJECT (self, "Need more caption data");
|
|
|
|
gst_object_unref (caption_pad);
|
|
|
|
return GST_FLOW_NEED_DATA;
|
2019-03-13 12:43:54 +00:00
|
|
|
} else {
|
|
|
|
GST_DEBUG_OBJECT (self, "No caption data on timeout");
|
|
|
|
break;
|
2018-11-05 14:24:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
caption_time = GST_BUFFER_PTS (caption_buf);
|
|
|
|
if (!GST_CLOCK_TIME_IS_VALID (caption_time)) {
|
|
|
|
GST_ERROR_OBJECT (self, "Caption buffer without PTS");
|
|
|
|
|
|
|
|
gst_buffer_unref (caption_buf);
|
|
|
|
gst_object_unref (caption_pad);
|
|
|
|
|
|
|
|
return GST_FLOW_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
caption_time =
|
|
|
|
gst_segment_to_running_time (&caption_pad->segment, GST_FORMAT_TIME,
|
|
|
|
caption_time);
|
|
|
|
|
|
|
|
if (!GST_CLOCK_TIME_IS_VALID (caption_time)) {
|
|
|
|
GST_DEBUG_OBJECT (self, "Caption buffer outside segment, dropping");
|
|
|
|
|
|
|
|
gst_aggregator_pad_drop_buffer (caption_pad);
|
|
|
|
gst_buffer_unref (caption_buf);
|
|
|
|
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2020-04-22 14:51:08 +00:00
|
|
|
if (gst_buffer_get_size (caption_buf) == 0 &&
|
|
|
|
GST_BUFFER_FLAG_IS_SET (caption_buf, GST_BUFFER_FLAG_GAP)) {
|
|
|
|
/* This is a gap, we can go ahead. We only consume it once its end point
|
|
|
|
* is behind the current video running time. Important to note that
|
|
|
|
* we can't deal with gaps with no duration (-1)
|
|
|
|
*/
|
|
|
|
if (!GST_CLOCK_TIME_IS_VALID (GST_BUFFER_DURATION (caption_buf))) {
|
|
|
|
GST_ERROR_OBJECT (self, "GAP buffer without a duration");
|
|
|
|
|
|
|
|
gst_buffer_unref (caption_buf);
|
|
|
|
gst_object_unref (caption_pad);
|
|
|
|
|
|
|
|
return GST_FLOW_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
gst_buffer_unref (caption_buf);
|
|
|
|
|
|
|
|
if (caption_time + GST_BUFFER_DURATION (caption_buf) <
|
|
|
|
self->current_video_running_time_end) {
|
|
|
|
gst_aggregator_pad_drop_buffer (caption_pad);
|
|
|
|
continue;
|
|
|
|
} else {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-11-05 14:24:58 +00:00
|
|
|
/* Collected all caption buffers for this video buffer */
|
|
|
|
if (caption_time >= self->current_video_running_time_end) {
|
|
|
|
gst_buffer_unref (caption_buf);
|
|
|
|
break;
|
cccombiner: implement scheduling
Prior to that, cccombiner's behaviour was essentially that of
a funnel: it strictly looked at input timestamps to associate
together video and caption buffers.
This patch instead exposes a "schedule" property, with a default
of TRUE, to control whether caption buffers should be smoothly
scheduled, in order to have exactly one per output video buffer.
This can involve rewriting input captions, for example when the
input is CDP sequence counters are rewritten, time codes are dropped
and potentially re-injected if the input video frame had a time code
meta.
Caption buffers may also get split up in order to assign captions to
the correct field when the input is interlaced.
This can also imply that the input will drift from synchronization,
when there isn't enough padding in the input stream to catch up. In
that case the element will start dropping old caption buffers once
the number of buffers in its internal queue reaches a certain limit
(configurable).
The property is exposed so that existing users of cccombiner can
revert back to the original behaviour, but should eventually be
removed, as that behaviour was simply inadequate.
This commit also disallows changing the input caption type, as
this would needlessly complicate implementation, and removes
the corresponding test.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2076>
2021-03-09 12:22:10 +00:00
|
|
|
} else if (!self->schedule) {
|
|
|
|
if (GST_CLOCK_TIME_IS_VALID (self->previous_video_running_time_end)) {
|
|
|
|
if (caption_time < self->previous_video_running_time_end) {
|
|
|
|
GST_WARNING_OBJECT (self,
|
|
|
|
"Caption buffer before end of last video frame, dropping");
|
|
|
|
|
|
|
|
gst_aggregator_pad_drop_buffer (caption_pad);
|
|
|
|
gst_buffer_unref (caption_buf);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
} else if (caption_time < self->current_video_running_time) {
|
2020-04-22 14:53:00 +00:00
|
|
|
GST_WARNING_OBJECT (self,
|
cccombiner: implement scheduling
Prior to that, cccombiner's behaviour was essentially that of
a funnel: it strictly looked at input timestamps to associate
together video and caption buffers.
This patch instead exposes a "schedule" property, with a default
of TRUE, to control whether caption buffers should be smoothly
scheduled, in order to have exactly one per output video buffer.
This can involve rewriting input captions, for example when the
input is CDP sequence counters are rewritten, time codes are dropped
and potentially re-injected if the input video frame had a time code
meta.
Caption buffers may also get split up in order to assign captions to
the correct field when the input is interlaced.
This can also imply that the input will drift from synchronization,
when there isn't enough padding in the input stream to catch up. In
that case the element will start dropping old caption buffers once
the number of buffers in its internal queue reaches a certain limit
(configurable).
The property is exposed so that existing users of cccombiner can
revert back to the original behaviour, but should eventually be
removed, as that behaviour was simply inadequate.
This commit also disallows changing the input caption type, as
this would needlessly complicate implementation, and removes
the corresponding test.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2076>
2021-03-09 12:22:10 +00:00
|
|
|
"Caption buffer before current video frame, dropping");
|
2020-04-22 14:53:00 +00:00
|
|
|
|
|
|
|
gst_aggregator_pad_drop_buffer (caption_pad);
|
|
|
|
gst_buffer_unref (caption_buf);
|
|
|
|
continue;
|
|
|
|
}
|
2018-11-05 14:24:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* This caption buffer has to be collected */
|
|
|
|
GST_LOG_OBJECT (self,
|
|
|
|
"Collecting caption buffer %p %" GST_TIME_FORMAT " for video buffer %p",
|
|
|
|
caption_buf, GST_TIME_ARGS (caption_time), self->current_video_buffer);
|
cccombiner: implement scheduling
Prior to that, cccombiner's behaviour was essentially that of
a funnel: it strictly looked at input timestamps to associate
together video and caption buffers.
This patch instead exposes a "schedule" property, with a default
of TRUE, to control whether caption buffers should be smoothly
scheduled, in order to have exactly one per output video buffer.
This can involve rewriting input captions, for example when the
input is CDP sequence counters are rewritten, time codes are dropped
and potentially re-injected if the input video frame had a time code
meta.
Caption buffers may also get split up in order to assign captions to
the correct field when the input is interlaced.
This can also imply that the input will drift from synchronization,
when there isn't enough padding in the input stream to catch up. In
that case the element will start dropping old caption buffers once
the number of buffers in its internal queue reaches a certain limit
(configurable).
The property is exposed so that existing users of cccombiner can
revert back to the original behaviour, but should eventually be
removed, as that behaviour was simply inadequate.
This commit also disallows changing the input caption type, as
this would needlessly complicate implementation, and removes
the corresponding test.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2076>
2021-03-09 12:22:10 +00:00
|
|
|
|
|
|
|
caption_data.caption_type = self->caption_type;
|
|
|
|
|
2018-11-05 14:24:58 +00:00
|
|
|
gst_aggregator_pad_drop_buffer (caption_pad);
|
cccombiner: implement scheduling
Prior to that, cccombiner's behaviour was essentially that of
a funnel: it strictly looked at input timestamps to associate
together video and caption buffers.
This patch instead exposes a "schedule" property, with a default
of TRUE, to control whether caption buffers should be smoothly
scheduled, in order to have exactly one per output video buffer.
This can involve rewriting input captions, for example when the
input is CDP sequence counters are rewritten, time codes are dropped
and potentially re-injected if the input video frame had a time code
meta.
Caption buffers may also get split up in order to assign captions to
the correct field when the input is interlaced.
This can also imply that the input will drift from synchronization,
when there isn't enough padding in the input stream to catch up. In
that case the element will start dropping old caption buffers once
the number of buffers in its internal queue reaches a certain limit
(configurable).
The property is exposed so that existing users of cccombiner can
revert back to the original behaviour, but should eventually be
removed, as that behaviour was simply inadequate.
This commit also disallows changing the input caption type, as
this would needlessly complicate implementation, and removes
the corresponding test.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2076>
2021-03-09 12:22:10 +00:00
|
|
|
|
|
|
|
if (!self->schedule) {
|
|
|
|
caption_data.buffer = caption_buf;
|
|
|
|
g_array_append_val (self->current_frame_captions, caption_data);
|
|
|
|
} else {
|
2024-11-26 15:27:19 +00:00
|
|
|
schedule_caption (self, caption_pad, caption_buf, tc);
|
cccombiner: implement scheduling
Prior to that, cccombiner's behaviour was essentially that of
a funnel: it strictly looked at input timestamps to associate
together video and caption buffers.
This patch instead exposes a "schedule" property, with a default
of TRUE, to control whether caption buffers should be smoothly
scheduled, in order to have exactly one per output video buffer.
This can involve rewriting input captions, for example when the
input is CDP sequence counters are rewritten, time codes are dropped
and potentially re-injected if the input video frame had a time code
meta.
Caption buffers may also get split up in order to assign captions to
the correct field when the input is interlaced.
This can also imply that the input will drift from synchronization,
when there isn't enough padding in the input stream to catch up. In
that case the element will start dropping old caption buffers once
the number of buffers in its internal queue reaches a certain limit
(configurable).
The property is exposed so that existing users of cccombiner can
revert back to the original behaviour, but should eventually be
removed, as that behaviour was simply inadequate.
This commit also disallows changing the input caption type, as
this would needlessly complicate implementation, and removes
the corresponding test.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2076>
2021-03-09 12:22:10 +00:00
|
|
|
gst_buffer_unref (caption_buf);
|
|
|
|
}
|
2018-11-05 14:24:58 +00:00
|
|
|
} while (TRUE);
|
|
|
|
|
cccombiner: implement scheduling
Prior to that, cccombiner's behaviour was essentially that of
a funnel: it strictly looked at input timestamps to associate
together video and caption buffers.
This patch instead exposes a "schedule" property, with a default
of TRUE, to control whether caption buffers should be smoothly
scheduled, in order to have exactly one per output video buffer.
This can involve rewriting input captions, for example when the
input is CDP sequence counters are rewritten, time codes are dropped
and potentially re-injected if the input video frame had a time code
meta.
Caption buffers may also get split up in order to assign captions to
the correct field when the input is interlaced.
This can also imply that the input will drift from synchronization,
when there isn't enough padding in the input stream to catch up. In
that case the element will start dropping old caption buffers once
the number of buffers in its internal queue reaches a certain limit
(configurable).
The property is exposed so that existing users of cccombiner can
revert back to the original behaviour, but should eventually be
removed, as that behaviour was simply inadequate.
This commit also disallows changing the input caption type, as
this would needlessly complicate implementation, and removes
the corresponding test.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2076>
2021-03-09 12:22:10 +00:00
|
|
|
if (self->schedule) {
|
2022-06-01 11:24:41 +00:00
|
|
|
dequeue_caption (self, tc, caption_pad_is_eos);
|
cccombiner: implement scheduling
Prior to that, cccombiner's behaviour was essentially that of
a funnel: it strictly looked at input timestamps to associate
together video and caption buffers.
This patch instead exposes a "schedule" property, with a default
of TRUE, to control whether caption buffers should be smoothly
scheduled, in order to have exactly one per output video buffer.
This can involve rewriting input captions, for example when the
input is CDP sequence counters are rewritten, time codes are dropped
and potentially re-injected if the input video frame had a time code
meta.
Caption buffers may also get split up in order to assign captions to
the correct field when the input is interlaced.
This can also imply that the input will drift from synchronization,
when there isn't enough padding in the input stream to catch up. In
that case the element will start dropping old caption buffers once
the number of buffers in its internal queue reaches a certain limit
(configurable).
The property is exposed so that existing users of cccombiner can
revert back to the original behaviour, but should eventually be
removed, as that behaviour was simply inadequate.
This commit also disallows changing the input caption type, as
this would needlessly complicate implementation, and removes
the corresponding test.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2076>
2021-03-09 12:22:10 +00:00
|
|
|
}
|
|
|
|
|
2020-08-05 14:57:15 +00:00
|
|
|
gst_aggregator_selected_samples (GST_AGGREGATOR_CAST (self),
|
|
|
|
GST_BUFFER_PTS (self->current_video_buffer),
|
|
|
|
GST_BUFFER_DTS (self->current_video_buffer),
|
2020-08-07 06:37:20 +00:00
|
|
|
GST_BUFFER_DURATION (self->current_video_buffer), NULL);
|
2020-07-01 01:59:56 +00:00
|
|
|
|
2024-02-01 17:45:01 +00:00
|
|
|
GST_LOG_OBJECT (self, "Collected %u captions for buffer %p",
|
cccombiner: implement scheduling
Prior to that, cccombiner's behaviour was essentially that of
a funnel: it strictly looked at input timestamps to associate
together video and caption buffers.
This patch instead exposes a "schedule" property, with a default
of TRUE, to control whether caption buffers should be smoothly
scheduled, in order to have exactly one per output video buffer.
This can involve rewriting input captions, for example when the
input is CDP sequence counters are rewritten, time codes are dropped
and potentially re-injected if the input video frame had a time code
meta.
Caption buffers may also get split up in order to assign captions to
the correct field when the input is interlaced.
This can also imply that the input will drift from synchronization,
when there isn't enough padding in the input stream to catch up. In
that case the element will start dropping old caption buffers once
the number of buffers in its internal queue reaches a certain limit
(configurable).
The property is exposed so that existing users of cccombiner can
revert back to the original behaviour, but should eventually be
removed, as that behaviour was simply inadequate.
This commit also disallows changing the input caption type, as
this would needlessly complicate implementation, and removes
the corresponding test.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2076>
2021-03-09 12:22:10 +00:00
|
|
|
self->current_frame_captions->len, self->current_video_buffer);
|
|
|
|
|
2024-02-01 17:45:01 +00:00
|
|
|
switch (self->prop_input_meta_processing) {
|
|
|
|
case CCCOMBINER_INPUT_PROCESSING_APPEND:
|
|
|
|
break;
|
|
|
|
case CCCOMBINER_INPUT_PROCESSING_DROP:
|
|
|
|
self->current_video_buffer =
|
|
|
|
gst_buffer_make_writable (self->current_video_buffer);
|
|
|
|
gst_buffer_foreach_meta (self->current_video_buffer, remove_caption_meta,
|
|
|
|
NULL);
|
|
|
|
break;
|
|
|
|
case CCCOMBINER_INPUT_PROCESSING_FAVOR:
|
|
|
|
if (gst_buffer_get_meta (self->current_video_buffer,
|
|
|
|
GST_VIDEO_CAPTION_META_API_TYPE)) {
|
|
|
|
GST_LOG_OBJECT (self,
|
|
|
|
"Video buffer already has captions, dropping %d dequeued captions",
|
|
|
|
self->current_frame_captions->len);
|
|
|
|
g_array_set_size (self->current_frame_captions, 0);
|
|
|
|
}
|
|
|
|
break;
|
2024-12-06 18:13:50 +00:00
|
|
|
case CCCOMBINER_INPUT_PROCESSING_FORCE:
|
|
|
|
GST_LOG_OBJECT (self,
|
|
|
|
"Forced input captions, dropping %d dequeued captions",
|
|
|
|
self->current_frame_captions->len);
|
|
|
|
g_array_set_size (self->current_frame_captions, 0);
|
|
|
|
break;
|
2024-02-01 17:45:01 +00:00
|
|
|
}
|
|
|
|
|
2018-11-05 14:24:58 +00:00
|
|
|
if (self->current_frame_captions->len > 0) {
|
|
|
|
guint i;
|
|
|
|
|
2022-06-01 11:24:41 +00:00
|
|
|
if (self->schedule)
|
|
|
|
self->current_scheduled = MAX (1, self->current_scheduled) - 1;
|
|
|
|
|
2018-11-05 14:24:58 +00:00
|
|
|
video_buf = gst_buffer_make_writable (self->current_video_buffer);
|
|
|
|
self->current_video_buffer = NULL;
|
|
|
|
|
|
|
|
for (i = 0; i < self->current_frame_captions->len; i++) {
|
|
|
|
CaptionData *caption_data =
|
|
|
|
&g_array_index (self->current_frame_captions, CaptionData, i);
|
|
|
|
GstMapInfo map;
|
|
|
|
|
|
|
|
gst_buffer_map (caption_data->buffer, &map, GST_MAP_READ);
|
|
|
|
gst_buffer_add_video_caption_meta (video_buf, caption_data->caption_type,
|
|
|
|
map.data, map.size);
|
|
|
|
gst_buffer_unmap (caption_data->buffer, &map);
|
|
|
|
}
|
|
|
|
|
|
|
|
g_array_set_size (self->current_frame_captions, 0);
|
|
|
|
} else {
|
|
|
|
GST_LOG_OBJECT (self, "No captions for buffer %p",
|
|
|
|
self->current_video_buffer);
|
|
|
|
video_buf = self->current_video_buffer;
|
|
|
|
self->current_video_buffer = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
gst_object_unref (caption_pad);
|
|
|
|
|
2019-03-13 12:43:54 +00:00
|
|
|
done:
|
|
|
|
src_pad->segment.position =
|
|
|
|
GST_BUFFER_PTS (video_buf) + GST_BUFFER_DURATION (video_buf);
|
|
|
|
|
2018-11-05 14:24:58 +00:00
|
|
|
return gst_aggregator_finish_buffer (GST_AGGREGATOR_CAST (self), video_buf);
|
|
|
|
}
|
|
|
|
|
2022-02-18 16:19:57 +00:00
|
|
|
static GstClockTime
|
|
|
|
gst_cc_combiner_get_next_time (GstAggregator * aggregator)
|
|
|
|
{
|
|
|
|
GstCCCombiner *self = GST_CCCOMBINER (aggregator);
|
|
|
|
|
|
|
|
GST_OBJECT_LOCK (self);
|
|
|
|
/* No point timing out if we can't combine captions */
|
|
|
|
if (!self->caption_pad)
|
|
|
|
goto wait_for_data;
|
|
|
|
|
|
|
|
/* We need a video buffer */
|
|
|
|
if (!self->current_video_buffer &&
|
|
|
|
!gst_aggregator_pad_has_buffer (self->video_pad))
|
|
|
|
goto wait_for_data;
|
|
|
|
GST_OBJECT_UNLOCK (self);
|
|
|
|
|
|
|
|
return gst_aggregator_simple_get_next_time (aggregator);
|
|
|
|
|
|
|
|
wait_for_data:
|
|
|
|
GST_OBJECT_UNLOCK (self);
|
|
|
|
return GST_CLOCK_TIME_NONE;
|
|
|
|
}
|
|
|
|
|
2018-11-05 14:24:58 +00:00
|
|
|
static GstFlowReturn
|
|
|
|
gst_cc_combiner_aggregate (GstAggregator * aggregator, gboolean timeout)
|
|
|
|
{
|
|
|
|
GstCCCombiner *self = GST_CCCOMBINER (aggregator);
|
|
|
|
GstFlowReturn flow_ret = GST_FLOW_OK;
|
|
|
|
|
|
|
|
/* If we have no current video buffer, queue one. If we have one but
|
|
|
|
* its end running time is not known yet, try to determine it from the
|
|
|
|
* next video buffer */
|
|
|
|
if (!self->current_video_buffer
|
|
|
|
|| !GST_CLOCK_TIME_IS_VALID (self->current_video_running_time_end)) {
|
|
|
|
GstAggregatorPad *video_pad;
|
|
|
|
GstClockTime video_start;
|
|
|
|
GstBuffer *video_buf;
|
|
|
|
|
2022-02-18 16:06:44 +00:00
|
|
|
video_pad = self->video_pad;
|
2018-11-05 14:24:58 +00:00
|
|
|
video_buf = gst_aggregator_pad_peek_buffer (video_pad);
|
|
|
|
if (!video_buf) {
|
|
|
|
if (gst_aggregator_pad_is_eos (video_pad)) {
|
|
|
|
GST_DEBUG_OBJECT (aggregator, "Video pad is EOS, we're done");
|
|
|
|
|
|
|
|
/* Assume that this buffer ends where it started +50ms (25fps) and handle it */
|
|
|
|
if (self->current_video_buffer) {
|
|
|
|
self->current_video_running_time_end =
|
|
|
|
self->current_video_running_time + 50 * GST_MSECOND;
|
2019-03-13 12:43:54 +00:00
|
|
|
flow_ret = gst_cc_combiner_collect_captions (self, timeout);
|
2018-11-05 14:24:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* If we collected all captions for the remaining video frame we're
|
|
|
|
* done, otherwise get called another time and go directly into the
|
|
|
|
* outer branch for finishing the current video frame */
|
|
|
|
if (flow_ret == GST_FLOW_NEED_DATA)
|
|
|
|
flow_ret = GST_FLOW_OK;
|
|
|
|
else
|
|
|
|
flow_ret = GST_FLOW_EOS;
|
|
|
|
} else {
|
|
|
|
flow_ret = GST_FLOW_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
return flow_ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
video_start = GST_BUFFER_PTS (video_buf);
|
|
|
|
if (!GST_CLOCK_TIME_IS_VALID (video_start)) {
|
|
|
|
gst_buffer_unref (video_buf);
|
|
|
|
|
|
|
|
GST_ERROR_OBJECT (aggregator, "Video buffer without PTS");
|
|
|
|
|
|
|
|
return GST_FLOW_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
video_start =
|
|
|
|
gst_segment_to_running_time (&video_pad->segment, GST_FORMAT_TIME,
|
|
|
|
video_start);
|
|
|
|
if (!GST_CLOCK_TIME_IS_VALID (video_start)) {
|
|
|
|
GST_DEBUG_OBJECT (aggregator, "Buffer outside segment, dropping");
|
|
|
|
gst_aggregator_pad_drop_buffer (video_pad);
|
|
|
|
gst_buffer_unref (video_buf);
|
|
|
|
return GST_FLOW_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (self->current_video_buffer) {
|
|
|
|
/* If we already have a video buffer just update the current end running
|
|
|
|
* time accordingly. That's what was missing and why we got here */
|
|
|
|
self->current_video_running_time_end = video_start;
|
|
|
|
gst_buffer_unref (video_buf);
|
|
|
|
GST_LOG_OBJECT (self,
|
|
|
|
"Determined end timestamp for video buffer: %p %" GST_TIME_FORMAT
|
|
|
|
" - %" GST_TIME_FORMAT, self->current_video_buffer,
|
|
|
|
GST_TIME_ARGS (self->current_video_running_time),
|
|
|
|
GST_TIME_ARGS (self->current_video_running_time_end));
|
|
|
|
} else {
|
|
|
|
/* Otherwise we had no buffer queued currently. Let's do that now
|
|
|
|
* so that we can collect captions for it */
|
|
|
|
gst_buffer_replace (&self->current_video_buffer, video_buf);
|
|
|
|
self->current_video_running_time = video_start;
|
|
|
|
gst_aggregator_pad_drop_buffer (video_pad);
|
|
|
|
gst_buffer_unref (video_buf);
|
|
|
|
|
|
|
|
if (GST_BUFFER_DURATION_IS_VALID (video_buf)) {
|
|
|
|
GstClockTime end_time =
|
|
|
|
GST_BUFFER_PTS (video_buf) + GST_BUFFER_DURATION (video_buf);
|
|
|
|
if (video_pad->segment.stop != -1 && end_time > video_pad->segment.stop)
|
|
|
|
end_time = video_pad->segment.stop;
|
|
|
|
self->current_video_running_time_end =
|
|
|
|
gst_segment_to_running_time (&video_pad->segment, GST_FORMAT_TIME,
|
|
|
|
end_time);
|
|
|
|
} else if (self->video_fps_n != 0 && self->video_fps_d != 0) {
|
|
|
|
GstClockTime end_time =
|
|
|
|
GST_BUFFER_PTS (video_buf) + gst_util_uint64_scale_int (GST_SECOND,
|
|
|
|
self->video_fps_d, self->video_fps_n);
|
|
|
|
if (video_pad->segment.stop != -1 && end_time > video_pad->segment.stop)
|
|
|
|
end_time = video_pad->segment.stop;
|
|
|
|
self->current_video_running_time_end =
|
|
|
|
gst_segment_to_running_time (&video_pad->segment, GST_FORMAT_TIME,
|
|
|
|
end_time);
|
|
|
|
} else {
|
|
|
|
self->current_video_running_time_end = GST_CLOCK_TIME_NONE;
|
|
|
|
}
|
|
|
|
|
|
|
|
GST_LOG_OBJECT (self,
|
|
|
|
"Queued new video buffer: %p %" GST_TIME_FORMAT " - %"
|
|
|
|
GST_TIME_FORMAT, self->current_video_buffer,
|
|
|
|
GST_TIME_ARGS (self->current_video_running_time),
|
|
|
|
GST_TIME_ARGS (self->current_video_running_time_end));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* At this point we have a video buffer queued and can start collecting
|
|
|
|
* caption buffers for it */
|
|
|
|
g_assert (self->current_video_buffer != NULL);
|
|
|
|
g_assert (GST_CLOCK_TIME_IS_VALID (self->current_video_running_time));
|
|
|
|
g_assert (GST_CLOCK_TIME_IS_VALID (self->current_video_running_time_end));
|
|
|
|
|
2019-03-13 12:43:54 +00:00
|
|
|
flow_ret = gst_cc_combiner_collect_captions (self, timeout);
|
2018-11-05 14:24:58 +00:00
|
|
|
|
|
|
|
/* Only if we collected all captions we replace the current video buffer
|
|
|
|
* with NULL and continue with the next one on the next call */
|
|
|
|
if (flow_ret == GST_FLOW_NEED_DATA) {
|
|
|
|
flow_ret = GST_FLOW_OK;
|
|
|
|
} else {
|
|
|
|
gst_buffer_replace (&self->current_video_buffer, NULL);
|
2020-04-22 14:53:00 +00:00
|
|
|
self->previous_video_running_time_end =
|
|
|
|
self->current_video_running_time_end;
|
2018-11-05 14:24:58 +00:00
|
|
|
self->current_video_running_time = self->current_video_running_time_end =
|
|
|
|
GST_CLOCK_TIME_NONE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return flow_ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
gst_cc_combiner_sink_event (GstAggregator * aggregator,
|
|
|
|
GstAggregatorPad * agg_pad, GstEvent * event)
|
|
|
|
{
|
|
|
|
GstCCCombiner *self = GST_CCCOMBINER (aggregator);
|
|
|
|
|
|
|
|
switch (GST_EVENT_TYPE (event)) {
|
|
|
|
case GST_EVENT_CAPS:{
|
|
|
|
GstCaps *caps;
|
|
|
|
GstStructure *s;
|
|
|
|
|
|
|
|
gst_event_parse_caps (event, &caps);
|
|
|
|
s = gst_caps_get_structure (caps, 0);
|
|
|
|
|
|
|
|
if (strcmp (GST_OBJECT_NAME (agg_pad), "caption") == 0) {
|
cccombiner: implement scheduling
Prior to that, cccombiner's behaviour was essentially that of
a funnel: it strictly looked at input timestamps to associate
together video and caption buffers.
This patch instead exposes a "schedule" property, with a default
of TRUE, to control whether caption buffers should be smoothly
scheduled, in order to have exactly one per output video buffer.
This can involve rewriting input captions, for example when the
input is CDP sequence counters are rewritten, time codes are dropped
and potentially re-injected if the input video frame had a time code
meta.
Caption buffers may also get split up in order to assign captions to
the correct field when the input is interlaced.
This can also imply that the input will drift from synchronization,
when there isn't enough padding in the input stream to catch up. In
that case the element will start dropping old caption buffers once
the number of buffers in its internal queue reaches a certain limit
(configurable).
The property is exposed so that existing users of cccombiner can
revert back to the original behaviour, but should eventually be
removed, as that behaviour was simply inadequate.
This commit also disallows changing the input caption type, as
this would needlessly complicate implementation, and removes
the corresponding test.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2076>
2021-03-09 12:22:10 +00:00
|
|
|
GstVideoCaptionType caption_type =
|
|
|
|
gst_video_caption_type_from_caps (caps);
|
|
|
|
|
|
|
|
if (self->caption_type != GST_VIDEO_CAPTION_TYPE_UNKNOWN &&
|
|
|
|
caption_type != self->caption_type) {
|
|
|
|
GST_ERROR_OBJECT (self, "Changing caption type is not allowed");
|
|
|
|
|
|
|
|
GST_ELEMENT_ERROR (self, CORE, NEGOTIATION, (NULL),
|
|
|
|
("Changing caption type is not allowed"));
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
self->caption_type = caption_type;
|
2018-11-05 14:24:58 +00:00
|
|
|
} else {
|
2019-03-13 12:43:54 +00:00
|
|
|
gint fps_n, fps_d;
|
cccombiner: implement scheduling
Prior to that, cccombiner's behaviour was essentially that of
a funnel: it strictly looked at input timestamps to associate
together video and caption buffers.
This patch instead exposes a "schedule" property, with a default
of TRUE, to control whether caption buffers should be smoothly
scheduled, in order to have exactly one per output video buffer.
This can involve rewriting input captions, for example when the
input is CDP sequence counters are rewritten, time codes are dropped
and potentially re-injected if the input video frame had a time code
meta.
Caption buffers may also get split up in order to assign captions to
the correct field when the input is interlaced.
This can also imply that the input will drift from synchronization,
when there isn't enough padding in the input stream to catch up. In
that case the element will start dropping old caption buffers once
the number of buffers in its internal queue reaches a certain limit
(configurable).
The property is exposed so that existing users of cccombiner can
revert back to the original behaviour, but should eventually be
removed, as that behaviour was simply inadequate.
This commit also disallows changing the input caption type, as
this would needlessly complicate implementation, and removes
the corresponding test.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2076>
2021-03-09 12:22:10 +00:00
|
|
|
const gchar *interlace_mode;
|
2019-03-13 12:43:54 +00:00
|
|
|
|
|
|
|
fps_n = fps_d = 0;
|
|
|
|
|
|
|
|
gst_structure_get_fraction (s, "framerate", &fps_n, &fps_d);
|
|
|
|
|
cccombiner: implement scheduling
Prior to that, cccombiner's behaviour was essentially that of
a funnel: it strictly looked at input timestamps to associate
together video and caption buffers.
This patch instead exposes a "schedule" property, with a default
of TRUE, to control whether caption buffers should be smoothly
scheduled, in order to have exactly one per output video buffer.
This can involve rewriting input captions, for example when the
input is CDP sequence counters are rewritten, time codes are dropped
and potentially re-injected if the input video frame had a time code
meta.
Caption buffers may also get split up in order to assign captions to
the correct field when the input is interlaced.
This can also imply that the input will drift from synchronization,
when there isn't enough padding in the input stream to catch up. In
that case the element will start dropping old caption buffers once
the number of buffers in its internal queue reaches a certain limit
(configurable).
The property is exposed so that existing users of cccombiner can
revert back to the original behaviour, but should eventually be
removed, as that behaviour was simply inadequate.
This commit also disallows changing the input caption type, as
this would needlessly complicate implementation, and removes
the corresponding test.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2076>
2021-03-09 12:22:10 +00:00
|
|
|
interlace_mode = gst_structure_get_string (s, "interlace-mode");
|
|
|
|
|
|
|
|
self->progressive = !interlace_mode
|
|
|
|
|| !g_strcmp0 (interlace_mode, "progressive");
|
|
|
|
|
2019-03-13 12:43:54 +00:00
|
|
|
if (fps_n != self->video_fps_n || fps_d != self->video_fps_d) {
|
|
|
|
GstClockTime latency;
|
|
|
|
|
|
|
|
latency = gst_util_uint64_scale (GST_SECOND, fps_d, fps_n);
|
|
|
|
gst_aggregator_set_latency (aggregator, latency, latency);
|
|
|
|
}
|
|
|
|
|
|
|
|
self->video_fps_n = fps_n;
|
|
|
|
self->video_fps_d = fps_d;
|
2018-11-05 14:24:58 +00:00
|
|
|
|
cccombiner: implement scheduling
Prior to that, cccombiner's behaviour was essentially that of
a funnel: it strictly looked at input timestamps to associate
together video and caption buffers.
This patch instead exposes a "schedule" property, with a default
of TRUE, to control whether caption buffers should be smoothly
scheduled, in order to have exactly one per output video buffer.
This can involve rewriting input captions, for example when the
input is CDP sequence counters are rewritten, time codes are dropped
and potentially re-injected if the input video frame had a time code
meta.
Caption buffers may also get split up in order to assign captions to
the correct field when the input is interlaced.
This can also imply that the input will drift from synchronization,
when there isn't enough padding in the input stream to catch up. In
that case the element will start dropping old caption buffers once
the number of buffers in its internal queue reaches a certain limit
(configurable).
The property is exposed so that existing users of cccombiner can
revert back to the original behaviour, but should eventually be
removed, as that behaviour was simply inadequate.
This commit also disallows changing the input caption type, as
this would needlessly complicate implementation, and removes
the corresponding test.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2076>
2021-03-09 12:22:10 +00:00
|
|
|
self->cdp_fps_entry = cdp_fps_entry_from_fps (fps_n, fps_d);
|
2022-06-01 11:24:41 +00:00
|
|
|
if (!self->cdp_fps_entry || self->cdp_fps_entry->fps_n == 0) {
|
|
|
|
GST_WARNING_OBJECT (self, "Missing valid caption framerate in "
|
|
|
|
"video caps");
|
|
|
|
|
|
|
|
GST_ELEMENT_WARNING (self, CORE, NEGOTIATION, (NULL),
|
|
|
|
("Missing valid caption framerate in video caps"));
|
|
|
|
|
|
|
|
self->cdp_fps_entry = cdp_fps_entry_from_fps (60, 1);
|
|
|
|
}
|
cccombiner: implement scheduling
Prior to that, cccombiner's behaviour was essentially that of
a funnel: it strictly looked at input timestamps to associate
together video and caption buffers.
This patch instead exposes a "schedule" property, with a default
of TRUE, to control whether caption buffers should be smoothly
scheduled, in order to have exactly one per output video buffer.
This can involve rewriting input captions, for example when the
input is CDP sequence counters are rewritten, time codes are dropped
and potentially re-injected if the input video frame had a time code
meta.
Caption buffers may also get split up in order to assign captions to
the correct field when the input is interlaced.
This can also imply that the input will drift from synchronization,
when there isn't enough padding in the input stream to catch up. In
that case the element will start dropping old caption buffers once
the number of buffers in its internal queue reaches a certain limit
(configurable).
The property is exposed so that existing users of cccombiner can
revert back to the original behaviour, but should eventually be
removed, as that behaviour was simply inadequate.
This commit also disallows changing the input caption type, as
this would needlessly complicate implementation, and removes
the corresponding test.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2076>
2021-03-09 12:22:10 +00:00
|
|
|
|
2019-08-14 07:13:52 +00:00
|
|
|
gst_aggregator_set_src_caps (aggregator, caps);
|
2018-11-05 14:24:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
2020-07-08 15:24:06 +00:00
|
|
|
}
|
|
|
|
case GST_EVENT_SEGMENT:{
|
|
|
|
if (strcmp (GST_OBJECT_NAME (agg_pad), "sink") == 0) {
|
|
|
|
const GstSegment *segment;
|
|
|
|
|
|
|
|
gst_event_parse_segment (event, &segment);
|
|
|
|
gst_aggregator_update_segment (aggregator, segment);
|
|
|
|
}
|
|
|
|
break;
|
2018-11-05 14:24:58 +00:00
|
|
|
}
|
2024-03-12 03:25:31 +00:00
|
|
|
case GST_EVENT_STREAM_START:{
|
|
|
|
if (strcmp (GST_OBJECT_NAME (agg_pad), "caption") == 0) {
|
|
|
|
self->last_caption_ts = GST_CLOCK_TIME_NONE;
|
|
|
|
}
|
|
|
|
}
|
2018-11-05 14:24:58 +00:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return GST_AGGREGATOR_CLASS (parent_class)->sink_event (aggregator, agg_pad,
|
|
|
|
event);
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
gst_cc_combiner_stop (GstAggregator * aggregator)
|
|
|
|
{
|
|
|
|
GstCCCombiner *self = GST_CCCOMBINER (aggregator);
|
|
|
|
|
|
|
|
self->video_fps_n = self->video_fps_d = 0;
|
|
|
|
self->current_video_running_time = self->current_video_running_time_end =
|
2020-04-22 14:53:00 +00:00
|
|
|
self->previous_video_running_time_end = GST_CLOCK_TIME_NONE;
|
2018-11-05 14:24:58 +00:00
|
|
|
gst_buffer_replace (&self->current_video_buffer, NULL);
|
|
|
|
|
|
|
|
g_array_set_size (self->current_frame_captions, 0);
|
cccombiner: implement scheduling
Prior to that, cccombiner's behaviour was essentially that of
a funnel: it strictly looked at input timestamps to associate
together video and caption buffers.
This patch instead exposes a "schedule" property, with a default
of TRUE, to control whether caption buffers should be smoothly
scheduled, in order to have exactly one per output video buffer.
This can involve rewriting input captions, for example when the
input is CDP sequence counters are rewritten, time codes are dropped
and potentially re-injected if the input video frame had a time code
meta.
Caption buffers may also get split up in order to assign captions to
the correct field when the input is interlaced.
This can also imply that the input will drift from synchronization,
when there isn't enough padding in the input stream to catch up. In
that case the element will start dropping old caption buffers once
the number of buffers in its internal queue reaches a certain limit
(configurable).
The property is exposed so that existing users of cccombiner can
revert back to the original behaviour, but should eventually be
removed, as that behaviour was simply inadequate.
This commit also disallows changing the input caption type, as
this would needlessly complicate implementation, and removes
the corresponding test.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2076>
2021-03-09 12:22:10 +00:00
|
|
|
self->caption_type = GST_VIDEO_CAPTION_TYPE_UNKNOWN;
|
|
|
|
|
2022-06-01 11:24:41 +00:00
|
|
|
cc_buffer_discard (self->cc_buffer);
|
|
|
|
self->current_scheduled = 0;
|
cccombiner: implement scheduling
Prior to that, cccombiner's behaviour was essentially that of
a funnel: it strictly looked at input timestamps to associate
together video and caption buffers.
This patch instead exposes a "schedule" property, with a default
of TRUE, to control whether caption buffers should be smoothly
scheduled, in order to have exactly one per output video buffer.
This can involve rewriting input captions, for example when the
input is CDP sequence counters are rewritten, time codes are dropped
and potentially re-injected if the input video frame had a time code
meta.
Caption buffers may also get split up in order to assign captions to
the correct field when the input is interlaced.
This can also imply that the input will drift from synchronization,
when there isn't enough padding in the input stream to catch up. In
that case the element will start dropping old caption buffers once
the number of buffers in its internal queue reaches a certain limit
(configurable).
The property is exposed so that existing users of cccombiner can
revert back to the original behaviour, but should eventually be
removed, as that behaviour was simply inadequate.
This commit also disallows changing the input caption type, as
this would needlessly complicate implementation, and removes
the corresponding test.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2076>
2021-03-09 12:22:10 +00:00
|
|
|
self->cdp_fps_entry = &null_fps_entry;
|
2018-11-05 14:24:58 +00:00
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static GstFlowReturn
|
|
|
|
gst_cc_combiner_flush (GstAggregator * aggregator)
|
|
|
|
{
|
|
|
|
GstCCCombiner *self = GST_CCCOMBINER (aggregator);
|
2019-03-13 12:43:54 +00:00
|
|
|
GstAggregatorPad *src_pad =
|
|
|
|
GST_AGGREGATOR_PAD (GST_AGGREGATOR_SRC_PAD (aggregator));
|
2018-11-05 14:24:58 +00:00
|
|
|
|
|
|
|
self->current_video_running_time = self->current_video_running_time_end =
|
2020-04-22 14:53:00 +00:00
|
|
|
self->previous_video_running_time_end = GST_CLOCK_TIME_NONE;
|
2018-11-05 14:24:58 +00:00
|
|
|
gst_buffer_replace (&self->current_video_buffer, NULL);
|
|
|
|
|
|
|
|
g_array_set_size (self->current_frame_captions, 0);
|
|
|
|
|
2019-03-13 12:43:54 +00:00
|
|
|
src_pad->segment.position = GST_CLOCK_TIME_NONE;
|
|
|
|
|
cccombiner: implement scheduling
Prior to that, cccombiner's behaviour was essentially that of
a funnel: it strictly looked at input timestamps to associate
together video and caption buffers.
This patch instead exposes a "schedule" property, with a default
of TRUE, to control whether caption buffers should be smoothly
scheduled, in order to have exactly one per output video buffer.
This can involve rewriting input captions, for example when the
input is CDP sequence counters are rewritten, time codes are dropped
and potentially re-injected if the input video frame had a time code
meta.
Caption buffers may also get split up in order to assign captions to
the correct field when the input is interlaced.
This can also imply that the input will drift from synchronization,
when there isn't enough padding in the input stream to catch up. In
that case the element will start dropping old caption buffers once
the number of buffers in its internal queue reaches a certain limit
(configurable).
The property is exposed so that existing users of cccombiner can
revert back to the original behaviour, but should eventually be
removed, as that behaviour was simply inadequate.
This commit also disallows changing the input caption type, as
this would needlessly complicate implementation, and removes
the corresponding test.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2076>
2021-03-09 12:22:10 +00:00
|
|
|
self->cdp_hdr_sequence_cntr = 0;
|
2022-06-01 11:24:41 +00:00
|
|
|
|
|
|
|
cc_buffer_discard (self->cc_buffer);
|
|
|
|
self->current_scheduled = 0;
|
cccombiner: implement scheduling
Prior to that, cccombiner's behaviour was essentially that of
a funnel: it strictly looked at input timestamps to associate
together video and caption buffers.
This patch instead exposes a "schedule" property, with a default
of TRUE, to control whether caption buffers should be smoothly
scheduled, in order to have exactly one per output video buffer.
This can involve rewriting input captions, for example when the
input is CDP sequence counters are rewritten, time codes are dropped
and potentially re-injected if the input video frame had a time code
meta.
Caption buffers may also get split up in order to assign captions to
the correct field when the input is interlaced.
This can also imply that the input will drift from synchronization,
when there isn't enough padding in the input stream to catch up. In
that case the element will start dropping old caption buffers once
the number of buffers in its internal queue reaches a certain limit
(configurable).
The property is exposed so that existing users of cccombiner can
revert back to the original behaviour, but should eventually be
removed, as that behaviour was simply inadequate.
This commit also disallows changing the input caption type, as
this would needlessly complicate implementation, and removes
the corresponding test.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2076>
2021-03-09 12:22:10 +00:00
|
|
|
|
2018-11-05 14:24:58 +00:00
|
|
|
return GST_FLOW_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
static GstAggregatorPad *
|
|
|
|
gst_cc_combiner_create_new_pad (GstAggregator * aggregator,
|
|
|
|
GstPadTemplate * templ, const gchar * req_name, const GstCaps * caps)
|
|
|
|
{
|
|
|
|
GstCCCombiner *self = GST_CCCOMBINER (aggregator);
|
|
|
|
GstAggregatorPad *agg_pad;
|
|
|
|
|
|
|
|
if (templ->direction != GST_PAD_SINK)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
if (templ->presence != GST_PAD_REQUEST)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
if (strcmp (templ->name_template, "caption") != 0)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
GST_OBJECT_LOCK (self);
|
|
|
|
agg_pad = g_object_new (GST_TYPE_AGGREGATOR_PAD,
|
|
|
|
"name", "caption", "direction", GST_PAD_SINK, "template", templ, NULL);
|
cccombiner: implement scheduling
Prior to that, cccombiner's behaviour was essentially that of
a funnel: it strictly looked at input timestamps to associate
together video and caption buffers.
This patch instead exposes a "schedule" property, with a default
of TRUE, to control whether caption buffers should be smoothly
scheduled, in order to have exactly one per output video buffer.
This can involve rewriting input captions, for example when the
input is CDP sequence counters are rewritten, time codes are dropped
and potentially re-injected if the input video frame had a time code
meta.
Caption buffers may also get split up in order to assign captions to
the correct field when the input is interlaced.
This can also imply that the input will drift from synchronization,
when there isn't enough padding in the input stream to catch up. In
that case the element will start dropping old caption buffers once
the number of buffers in its internal queue reaches a certain limit
(configurable).
The property is exposed so that existing users of cccombiner can
revert back to the original behaviour, but should eventually be
removed, as that behaviour was simply inadequate.
This commit also disallows changing the input caption type, as
this would needlessly complicate implementation, and removes
the corresponding test.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2076>
2021-03-09 12:22:10 +00:00
|
|
|
self->caption_type = GST_VIDEO_CAPTION_TYPE_UNKNOWN;
|
2022-02-18 16:06:44 +00:00
|
|
|
self->caption_pad = gst_object_ref (agg_pad);
|
2018-11-05 14:24:58 +00:00
|
|
|
GST_OBJECT_UNLOCK (self);
|
|
|
|
|
|
|
|
return agg_pad;
|
|
|
|
}
|
|
|
|
|
2022-02-18 16:06:44 +00:00
|
|
|
static void
|
|
|
|
gst_cc_combiner_release_pad (GstElement * element, GstPad * pad)
|
|
|
|
{
|
|
|
|
GstCCCombiner *self = GST_CCCOMBINER (element);
|
|
|
|
|
|
|
|
GST_OBJECT_LOCK (self);
|
|
|
|
if (pad == GST_PAD_CAST (self->caption_pad)) {
|
|
|
|
gst_clear_object (&self->caption_pad);
|
|
|
|
}
|
|
|
|
GST_OBJECT_UNLOCK (self);
|
|
|
|
|
|
|
|
GST_ELEMENT_CLASS (parent_class)->release_pad (element, pad);
|
|
|
|
}
|
|
|
|
|
2019-07-09 09:43:53 +00:00
|
|
|
static gboolean
|
|
|
|
gst_cc_combiner_src_query (GstAggregator * aggregator, GstQuery * query)
|
|
|
|
{
|
2022-02-18 16:06:44 +00:00
|
|
|
GstCCCombiner *self = GST_CCCOMBINER (aggregator);
|
2019-07-09 09:43:53 +00:00
|
|
|
gboolean ret;
|
|
|
|
|
|
|
|
switch (GST_QUERY_TYPE (query)) {
|
|
|
|
case GST_QUERY_POSITION:
|
|
|
|
case GST_QUERY_DURATION:
|
|
|
|
case GST_QUERY_URI:
|
|
|
|
case GST_QUERY_CAPS:
|
|
|
|
case GST_QUERY_ALLOCATION:
|
2022-02-18 16:06:44 +00:00
|
|
|
ret = gst_pad_peer_query (GST_PAD_CAST (self->video_pad), query);
|
2019-07-09 09:43:53 +00:00
|
|
|
break;
|
|
|
|
case GST_QUERY_ACCEPT_CAPS:{
|
|
|
|
GstCaps *caps;
|
|
|
|
GstCaps *templ = gst_static_pad_template_get_caps (&srctemplate);
|
|
|
|
|
|
|
|
gst_query_parse_accept_caps (query, &caps);
|
|
|
|
gst_query_set_accept_caps_result (query, gst_caps_is_subset (caps,
|
|
|
|
templ));
|
2020-08-13 11:19:21 +00:00
|
|
|
gst_caps_unref (templ);
|
2019-07-09 09:43:53 +00:00
|
|
|
ret = TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
ret = GST_AGGREGATOR_CLASS (parent_class)->src_query (aggregator, query);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
gst_cc_combiner_sink_query (GstAggregator * aggregator,
|
|
|
|
GstAggregatorPad * aggpad, GstQuery * query)
|
|
|
|
{
|
2022-02-18 16:06:44 +00:00
|
|
|
GstCCCombiner *self = GST_CCCOMBINER (aggregator);
|
2019-07-09 09:43:53 +00:00
|
|
|
GstPad *srcpad = GST_AGGREGATOR_SRC_PAD (aggregator);
|
|
|
|
|
|
|
|
gboolean ret;
|
|
|
|
|
|
|
|
switch (GST_QUERY_TYPE (query)) {
|
|
|
|
case GST_QUERY_POSITION:
|
|
|
|
case GST_QUERY_DURATION:
|
|
|
|
case GST_QUERY_URI:
|
|
|
|
case GST_QUERY_ALLOCATION:
|
2022-02-18 16:06:44 +00:00
|
|
|
if (aggpad == self->video_pad) {
|
2019-07-09 09:43:53 +00:00
|
|
|
ret = gst_pad_peer_query (srcpad, query);
|
|
|
|
} else {
|
|
|
|
ret =
|
2020-08-13 11:19:21 +00:00
|
|
|
GST_AGGREGATOR_CLASS (parent_class)->sink_query (aggregator,
|
|
|
|
aggpad, query);
|
2019-07-09 09:43:53 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case GST_QUERY_CAPS:
|
2022-02-18 16:06:44 +00:00
|
|
|
if (aggpad == self->video_pad) {
|
2019-07-09 09:43:53 +00:00
|
|
|
ret = gst_pad_peer_query (srcpad, query);
|
|
|
|
} else {
|
|
|
|
GstCaps *filter;
|
|
|
|
GstCaps *templ = gst_static_pad_template_get_caps (&captiontemplate);
|
|
|
|
|
|
|
|
gst_query_parse_caps (query, &filter);
|
|
|
|
|
|
|
|
if (filter) {
|
|
|
|
GstCaps *caps =
|
|
|
|
gst_caps_intersect_full (filter, templ, GST_CAPS_INTERSECT_FIRST);
|
|
|
|
gst_query_set_caps_result (query, caps);
|
|
|
|
gst_caps_unref (caps);
|
|
|
|
} else {
|
|
|
|
gst_query_set_caps_result (query, templ);
|
|
|
|
}
|
|
|
|
gst_caps_unref (templ);
|
|
|
|
ret = TRUE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case GST_QUERY_ACCEPT_CAPS:
|
2022-02-18 16:06:44 +00:00
|
|
|
if (aggpad == self->video_pad) {
|
2019-07-09 09:43:53 +00:00
|
|
|
ret = gst_pad_peer_query (srcpad, query);
|
|
|
|
} else {
|
|
|
|
GstCaps *caps;
|
|
|
|
GstCaps *templ = gst_static_pad_template_get_caps (&captiontemplate);
|
|
|
|
|
|
|
|
gst_query_parse_accept_caps (query, &caps);
|
|
|
|
gst_query_set_accept_caps_result (query, gst_caps_is_subset (caps,
|
|
|
|
templ));
|
2020-08-13 11:19:21 +00:00
|
|
|
gst_caps_unref (templ);
|
2019-07-09 09:43:53 +00:00
|
|
|
ret = TRUE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
2020-08-13 11:19:21 +00:00
|
|
|
ret = GST_AGGREGATOR_CLASS (parent_class)->sink_query (aggregator,
|
|
|
|
aggpad, query);
|
2019-07-09 09:43:53 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2020-07-01 01:59:56 +00:00
|
|
|
static GstSample *
|
|
|
|
gst_cc_combiner_peek_next_sample (GstAggregator * agg,
|
|
|
|
GstAggregatorPad * aggpad)
|
|
|
|
{
|
|
|
|
GstCCCombiner *self = GST_CCCOMBINER (agg);
|
|
|
|
GstSample *res = NULL;
|
|
|
|
|
2022-02-18 16:06:44 +00:00
|
|
|
if (aggpad != self->video_pad) {
|
|
|
|
/* Must be the caption pad */
|
2020-07-01 01:59:56 +00:00
|
|
|
if (self->current_frame_captions->len > 0) {
|
|
|
|
GstCaps *caps = gst_pad_get_current_caps (GST_PAD (aggpad));
|
|
|
|
GstBufferList *buflist = gst_buffer_list_new ();
|
|
|
|
guint i;
|
|
|
|
|
|
|
|
for (i = 0; i < self->current_frame_captions->len; i++) {
|
|
|
|
CaptionData *caption_data =
|
|
|
|
&g_array_index (self->current_frame_captions, CaptionData, i);
|
|
|
|
gst_buffer_list_add (buflist, gst_buffer_ref (caption_data->buffer));
|
|
|
|
}
|
|
|
|
|
|
|
|
res = gst_sample_new (NULL, caps, &aggpad->segment, NULL);
|
|
|
|
gst_caps_unref (caps);
|
|
|
|
|
|
|
|
gst_sample_set_buffer_list (res, buflist);
|
|
|
|
gst_buffer_list_unref (buflist);
|
|
|
|
}
|
2022-02-18 16:06:44 +00:00
|
|
|
} else {
|
2020-07-01 01:59:56 +00:00
|
|
|
if (self->current_video_buffer) {
|
|
|
|
GstCaps *caps = gst_pad_get_current_caps (GST_PAD (aggpad));
|
|
|
|
res = gst_sample_new (self->current_video_buffer,
|
|
|
|
caps, &aggpad->segment, NULL);
|
|
|
|
gst_caps_unref (caps);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
cccombiner: implement scheduling
Prior to that, cccombiner's behaviour was essentially that of
a funnel: it strictly looked at input timestamps to associate
together video and caption buffers.
This patch instead exposes a "schedule" property, with a default
of TRUE, to control whether caption buffers should be smoothly
scheduled, in order to have exactly one per output video buffer.
This can involve rewriting input captions, for example when the
input is CDP sequence counters are rewritten, time codes are dropped
and potentially re-injected if the input video frame had a time code
meta.
Caption buffers may also get split up in order to assign captions to
the correct field when the input is interlaced.
This can also imply that the input will drift from synchronization,
when there isn't enough padding in the input stream to catch up. In
that case the element will start dropping old caption buffers once
the number of buffers in its internal queue reaches a certain limit
(configurable).
The property is exposed so that existing users of cccombiner can
revert back to the original behaviour, but should eventually be
removed, as that behaviour was simply inadequate.
This commit also disallows changing the input caption type, as
this would needlessly complicate implementation, and removes
the corresponding test.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2076>
2021-03-09 12:22:10 +00:00
|
|
|
static GstStateChangeReturn
|
|
|
|
gst_cc_combiner_change_state (GstElement * element, GstStateChange transition)
|
|
|
|
{
|
|
|
|
GstCCCombiner *self = GST_CCCOMBINER (element);
|
|
|
|
|
|
|
|
switch (transition) {
|
|
|
|
case GST_STATE_CHANGE_READY_TO_PAUSED:
|
|
|
|
self->schedule = self->prop_schedule;
|
|
|
|
self->max_scheduled = self->prop_max_scheduled;
|
2022-02-01 22:46:43 +00:00
|
|
|
self->output_padding = self->prop_output_padding;
|
2022-06-01 11:24:41 +00:00
|
|
|
cc_buffer_set_max_buffer_time (self->cc_buffer, GST_CLOCK_TIME_NONE);
|
2023-10-02 12:34:42 +00:00
|
|
|
cc_buffer_set_output_padding (self->cc_buffer, self->prop_output_padding,
|
|
|
|
self->prop_output_padding);
|
cccombiner: implement scheduling
Prior to that, cccombiner's behaviour was essentially that of
a funnel: it strictly looked at input timestamps to associate
together video and caption buffers.
This patch instead exposes a "schedule" property, with a default
of TRUE, to control whether caption buffers should be smoothly
scheduled, in order to have exactly one per output video buffer.
This can involve rewriting input captions, for example when the
input is CDP sequence counters are rewritten, time codes are dropped
and potentially re-injected if the input video frame had a time code
meta.
Caption buffers may also get split up in order to assign captions to
the correct field when the input is interlaced.
This can also imply that the input will drift from synchronization,
when there isn't enough padding in the input stream to catch up. In
that case the element will start dropping old caption buffers once
the number of buffers in its internal queue reaches a certain limit
(configurable).
The property is exposed so that existing users of cccombiner can
revert back to the original behaviour, but should eventually be
removed, as that behaviour was simply inadequate.
This commit also disallows changing the input caption type, as
this would needlessly complicate implementation, and removes
the corresponding test.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2076>
2021-03-09 12:22:10 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gst_cc_combiner_set_property (GObject * object, guint prop_id,
|
|
|
|
const GValue * value, GParamSpec * pspec)
|
|
|
|
{
|
|
|
|
GstCCCombiner *self = GST_CCCOMBINER (object);
|
|
|
|
|
|
|
|
switch (prop_id) {
|
|
|
|
case PROP_SCHEDULE:
|
|
|
|
self->prop_schedule = g_value_get_boolean (value);
|
|
|
|
break;
|
|
|
|
case PROP_MAX_SCHEDULED:
|
|
|
|
self->prop_max_scheduled = g_value_get_uint (value);
|
|
|
|
break;
|
2022-02-01 22:46:43 +00:00
|
|
|
case PROP_OUTPUT_PADDING:
|
|
|
|
self->prop_output_padding = g_value_get_boolean (value);
|
|
|
|
break;
|
2024-03-08 07:22:53 +00:00
|
|
|
case PROP_CEA608_PADDING_STRATEGY:
|
|
|
|
self->prop_cea608_padding_strategy = g_value_get_flags (value);
|
|
|
|
cc_buffer_set_cea608_padding_strategy (self->cc_buffer,
|
|
|
|
self->prop_cea608_padding_strategy);
|
|
|
|
break;
|
|
|
|
case PROP_CEA608_VALID_PADDING_TIMEOUT:
|
|
|
|
self->prop_cea608_valid_padding_timeout = g_value_get_uint64 (value);
|
|
|
|
cc_buffer_set_cea608_valid_timeout (self->cc_buffer,
|
|
|
|
self->prop_cea608_valid_padding_timeout);
|
|
|
|
break;
|
2024-03-12 03:25:31 +00:00
|
|
|
case PROP_SCHEDULE_TIMEOUT:
|
|
|
|
self->prop_schedule_timeout = g_value_get_uint64 (value);
|
|
|
|
break;
|
2024-02-01 17:45:01 +00:00
|
|
|
case PROP_INPUT_META_PROCESSING:
|
|
|
|
self->prop_input_meta_processing = g_value_get_enum (value);
|
|
|
|
break;
|
cccombiner: implement scheduling
Prior to that, cccombiner's behaviour was essentially that of
a funnel: it strictly looked at input timestamps to associate
together video and caption buffers.
This patch instead exposes a "schedule" property, with a default
of TRUE, to control whether caption buffers should be smoothly
scheduled, in order to have exactly one per output video buffer.
This can involve rewriting input captions, for example when the
input is CDP sequence counters are rewritten, time codes are dropped
and potentially re-injected if the input video frame had a time code
meta.
Caption buffers may also get split up in order to assign captions to
the correct field when the input is interlaced.
This can also imply that the input will drift from synchronization,
when there isn't enough padding in the input stream to catch up. In
that case the element will start dropping old caption buffers once
the number of buffers in its internal queue reaches a certain limit
(configurable).
The property is exposed so that existing users of cccombiner can
revert back to the original behaviour, but should eventually be
removed, as that behaviour was simply inadequate.
This commit also disallows changing the input caption type, as
this would needlessly complicate implementation, and removes
the corresponding test.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2076>
2021-03-09 12:22:10 +00:00
|
|
|
default:
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gst_cc_combiner_get_property (GObject * object, guint prop_id, GValue * value,
|
|
|
|
GParamSpec * pspec)
|
|
|
|
{
|
|
|
|
GstCCCombiner *self = GST_CCCOMBINER (object);
|
|
|
|
|
|
|
|
switch (prop_id) {
|
|
|
|
case PROP_SCHEDULE:
|
|
|
|
g_value_set_boolean (value, self->prop_schedule);
|
|
|
|
break;
|
|
|
|
case PROP_MAX_SCHEDULED:
|
|
|
|
g_value_set_uint (value, self->prop_max_scheduled);
|
|
|
|
break;
|
2022-02-01 22:46:43 +00:00
|
|
|
case PROP_OUTPUT_PADDING:
|
|
|
|
g_value_set_boolean (value, self->prop_output_padding);
|
|
|
|
break;
|
2024-03-08 07:22:53 +00:00
|
|
|
case PROP_CEA608_PADDING_STRATEGY:
|
|
|
|
g_value_set_flags (value, self->prop_cea608_padding_strategy);
|
|
|
|
break;
|
|
|
|
case PROP_CEA608_VALID_PADDING_TIMEOUT:
|
|
|
|
g_value_set_uint64 (value, self->prop_cea608_valid_padding_timeout);
|
|
|
|
break;
|
2024-03-12 03:25:31 +00:00
|
|
|
case PROP_SCHEDULE_TIMEOUT:
|
|
|
|
g_value_set_uint64 (value, self->prop_schedule_timeout);
|
|
|
|
break;
|
2024-02-01 17:45:01 +00:00
|
|
|
case PROP_INPUT_META_PROCESSING:
|
|
|
|
g_value_set_enum (value, self->prop_input_meta_processing);
|
|
|
|
break;
|
cccombiner: implement scheduling
Prior to that, cccombiner's behaviour was essentially that of
a funnel: it strictly looked at input timestamps to associate
together video and caption buffers.
This patch instead exposes a "schedule" property, with a default
of TRUE, to control whether caption buffers should be smoothly
scheduled, in order to have exactly one per output video buffer.
This can involve rewriting input captions, for example when the
input is CDP sequence counters are rewritten, time codes are dropped
and potentially re-injected if the input video frame had a time code
meta.
Caption buffers may also get split up in order to assign captions to
the correct field when the input is interlaced.
This can also imply that the input will drift from synchronization,
when there isn't enough padding in the input stream to catch up. In
that case the element will start dropping old caption buffers once
the number of buffers in its internal queue reaches a certain limit
(configurable).
The property is exposed so that existing users of cccombiner can
revert back to the original behaviour, but should eventually be
removed, as that behaviour was simply inadequate.
This commit also disallows changing the input caption type, as
this would needlessly complicate implementation, and removes
the corresponding test.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2076>
2021-03-09 12:22:10 +00:00
|
|
|
default:
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-11-05 14:24:58 +00:00
|
|
|
static void
|
|
|
|
gst_cc_combiner_class_init (GstCCCombinerClass * klass)
|
|
|
|
{
|
|
|
|
GObjectClass *gobject_class;
|
|
|
|
GstElementClass *gstelement_class;
|
|
|
|
GstAggregatorClass *aggregator_class;
|
|
|
|
|
|
|
|
gobject_class = (GObjectClass *) klass;
|
|
|
|
gstelement_class = (GstElementClass *) klass;
|
|
|
|
aggregator_class = (GstAggregatorClass *) klass;
|
|
|
|
|
|
|
|
gobject_class->finalize = gst_cc_combiner_finalize;
|
cccombiner: implement scheduling
Prior to that, cccombiner's behaviour was essentially that of
a funnel: it strictly looked at input timestamps to associate
together video and caption buffers.
This patch instead exposes a "schedule" property, with a default
of TRUE, to control whether caption buffers should be smoothly
scheduled, in order to have exactly one per output video buffer.
This can involve rewriting input captions, for example when the
input is CDP sequence counters are rewritten, time codes are dropped
and potentially re-injected if the input video frame had a time code
meta.
Caption buffers may also get split up in order to assign captions to
the correct field when the input is interlaced.
This can also imply that the input will drift from synchronization,
when there isn't enough padding in the input stream to catch up. In
that case the element will start dropping old caption buffers once
the number of buffers in its internal queue reaches a certain limit
(configurable).
The property is exposed so that existing users of cccombiner can
revert back to the original behaviour, but should eventually be
removed, as that behaviour was simply inadequate.
This commit also disallows changing the input caption type, as
this would needlessly complicate implementation, and removes
the corresponding test.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2076>
2021-03-09 12:22:10 +00:00
|
|
|
gobject_class->set_property = gst_cc_combiner_set_property;
|
|
|
|
gobject_class->get_property = gst_cc_combiner_get_property;
|
2018-11-05 14:24:58 +00:00
|
|
|
|
|
|
|
gst_element_class_set_static_metadata (gstelement_class,
|
|
|
|
"Closed Caption Combiner",
|
|
|
|
"Filter",
|
|
|
|
"Combines GstVideoCaptionMeta with video input stream",
|
|
|
|
"Sebastian Dröge <sebastian@centricular.com>");
|
|
|
|
|
cccombiner: implement scheduling
Prior to that, cccombiner's behaviour was essentially that of
a funnel: it strictly looked at input timestamps to associate
together video and caption buffers.
This patch instead exposes a "schedule" property, with a default
of TRUE, to control whether caption buffers should be smoothly
scheduled, in order to have exactly one per output video buffer.
This can involve rewriting input captions, for example when the
input is CDP sequence counters are rewritten, time codes are dropped
and potentially re-injected if the input video frame had a time code
meta.
Caption buffers may also get split up in order to assign captions to
the correct field when the input is interlaced.
This can also imply that the input will drift from synchronization,
when there isn't enough padding in the input stream to catch up. In
that case the element will start dropping old caption buffers once
the number of buffers in its internal queue reaches a certain limit
(configurable).
The property is exposed so that existing users of cccombiner can
revert back to the original behaviour, but should eventually be
removed, as that behaviour was simply inadequate.
This commit also disallows changing the input caption type, as
this would needlessly complicate implementation, and removes
the corresponding test.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2076>
2021-03-09 12:22:10 +00:00
|
|
|
/**
|
|
|
|
* GstCCCombiner:schedule:
|
|
|
|
*
|
|
|
|
* Controls whether caption buffers should be smoothly scheduled
|
|
|
|
* in order to have exactly one per output video buffer.
|
|
|
|
*
|
|
|
|
* This can involve rewriting input captions, for example when the
|
|
|
|
* input is CDP sequence counters are rewritten, time codes are dropped
|
|
|
|
* and potentially re-injected if the input video frame had a time code
|
|
|
|
* meta.
|
|
|
|
*
|
|
|
|
* Caption buffers may also get split up in order to assign captions to
|
|
|
|
* the correct field when the input is interlaced.
|
|
|
|
*
|
|
|
|
* This can also imply that the input will drift from synchronization,
|
|
|
|
* when there isn't enough padding in the input stream to catch up. In
|
|
|
|
* that case the element will start dropping old caption buffers once
|
|
|
|
* the number of buffers in its internal queue reaches
|
|
|
|
* #GstCCCombiner:max-scheduled.
|
|
|
|
*
|
|
|
|
* When this is set to %FALSE, the behaviour of this element is essentially
|
|
|
|
* that of a funnel.
|
|
|
|
*
|
|
|
|
* Since: 1.20
|
|
|
|
*/
|
|
|
|
g_object_class_install_property (G_OBJECT_CLASS (klass),
|
|
|
|
PROP_SCHEDULE, g_param_spec_boolean ("schedule",
|
|
|
|
"Schedule",
|
|
|
|
"Schedule caption buffers so that exactly one is output per video frame",
|
2021-10-26 14:00:36 +00:00
|
|
|
DEFAULT_SCHEDULE,
|
cccombiner: implement scheduling
Prior to that, cccombiner's behaviour was essentially that of
a funnel: it strictly looked at input timestamps to associate
together video and caption buffers.
This patch instead exposes a "schedule" property, with a default
of TRUE, to control whether caption buffers should be smoothly
scheduled, in order to have exactly one per output video buffer.
This can involve rewriting input captions, for example when the
input is CDP sequence counters are rewritten, time codes are dropped
and potentially re-injected if the input video frame had a time code
meta.
Caption buffers may also get split up in order to assign captions to
the correct field when the input is interlaced.
This can also imply that the input will drift from synchronization,
when there isn't enough padding in the input stream to catch up. In
that case the element will start dropping old caption buffers once
the number of buffers in its internal queue reaches a certain limit
(configurable).
The property is exposed so that existing users of cccombiner can
revert back to the original behaviour, but should eventually be
removed, as that behaviour was simply inadequate.
This commit also disallows changing the input caption type, as
this would needlessly complicate implementation, and removes
the corresponding test.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2076>
2021-03-09 12:22:10 +00:00
|
|
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
|
|
|
|
GST_PARAM_MUTABLE_READY));
|
|
|
|
|
|
|
|
/**
|
|
|
|
* GstCCCombiner:max-scheduled:
|
|
|
|
*
|
|
|
|
* Controls the number of scheduled buffers after which the element
|
|
|
|
* will start dropping old buffers from its internal queues. See
|
|
|
|
* #GstCCCombiner:schedule.
|
|
|
|
*
|
|
|
|
* Since: 1.20
|
|
|
|
*/
|
|
|
|
g_object_class_install_property (G_OBJECT_CLASS (klass),
|
2021-04-19 10:06:23 +00:00
|
|
|
PROP_MAX_SCHEDULED, g_param_spec_uint ("max-scheduled",
|
cccombiner: implement scheduling
Prior to that, cccombiner's behaviour was essentially that of
a funnel: it strictly looked at input timestamps to associate
together video and caption buffers.
This patch instead exposes a "schedule" property, with a default
of TRUE, to control whether caption buffers should be smoothly
scheduled, in order to have exactly one per output video buffer.
This can involve rewriting input captions, for example when the
input is CDP sequence counters are rewritten, time codes are dropped
and potentially re-injected if the input video frame had a time code
meta.
Caption buffers may also get split up in order to assign captions to
the correct field when the input is interlaced.
This can also imply that the input will drift from synchronization,
when there isn't enough padding in the input stream to catch up. In
that case the element will start dropping old caption buffers once
the number of buffers in its internal queue reaches a certain limit
(configurable).
The property is exposed so that existing users of cccombiner can
revert back to the original behaviour, but should eventually be
removed, as that behaviour was simply inadequate.
This commit also disallows changing the input caption type, as
this would needlessly complicate implementation, and removes
the corresponding test.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2076>
2021-03-09 12:22:10 +00:00
|
|
|
"Max Scheduled",
|
|
|
|
"Maximum number of buffers to queue for scheduling", 0, G_MAXUINT,
|
|
|
|
DEFAULT_MAX_SCHEDULED,
|
|
|
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
|
|
|
|
GST_PARAM_MUTABLE_READY));
|
|
|
|
|
2022-02-01 22:46:43 +00:00
|
|
|
/**
|
|
|
|
* GstCCCombiner:output-padding:
|
|
|
|
*
|
|
|
|
* When #GstCCCombiner:schedule is %TRUE, this property controls
|
|
|
|
* whether the output closed caption meta stream will be padded.
|
|
|
|
*
|
|
|
|
* Since: 1.22
|
|
|
|
*/
|
|
|
|
g_object_class_install_property (G_OBJECT_CLASS (klass),
|
|
|
|
PROP_OUTPUT_PADDING, g_param_spec_boolean ("output-padding",
|
|
|
|
"Output padding",
|
|
|
|
"Whether to output padding packets when schedule=true",
|
|
|
|
DEFAULT_OUTPUT_PADDING,
|
|
|
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
|
|
|
|
GST_PARAM_MUTABLE_READY));
|
|
|
|
|
2024-03-08 07:22:53 +00:00
|
|
|
/**
|
|
|
|
* GstCCCombiner:cea608-padding-strategy:
|
|
|
|
*
|
|
|
|
* Controls the transformations that may be done on padding CEA-608 data.
|
|
|
|
*
|
|
|
|
* Since: 1.26
|
|
|
|
*/
|
|
|
|
g_object_class_install_property (G_OBJECT_CLASS (klass),
|
|
|
|
PROP_CEA608_PADDING_STRATEGY,
|
|
|
|
g_param_spec_flags ("cea608-padding-strategy",
|
|
|
|
"CEA-608 Padding Strategy",
|
|
|
|
"What transformations to perform on CEA-608 padding data",
|
|
|
|
GST_TYPE_CC_BUFFER_CEA608_PADDING_STRATEGY,
|
|
|
|
DEFAULT_CEA608_PADDING_STRATEGY,
|
|
|
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
|
|
|
|
GST_PARAM_MUTABLE_PLAYING));
|
|
|
|
|
|
|
|
/**
|
|
|
|
* GstCCCombiner:cea608-padding-valid-timeout:
|
|
|
|
*
|
|
|
|
* Timeout to apply when padding strategy contains "valid". After this time
|
|
|
|
* hase passed, CEA-608 padding will be signalled as invalid until new valid
|
|
|
|
* CEA-608 non-padding data is received.
|
|
|
|
*
|
|
|
|
* Since: 1.26
|
|
|
|
*/
|
|
|
|
g_object_class_install_property (G_OBJECT_CLASS (klass),
|
|
|
|
PROP_CEA608_VALID_PADDING_TIMEOUT,
|
|
|
|
g_param_spec_uint64 ("cea608-padding-valid-timeout",
|
|
|
|
"CEA-608 Padding Valid Timeout",
|
|
|
|
"How long after receiving valid non-padding CEA-608 data to keep writing valid CEA-608 padding bytes",
|
|
|
|
0, G_MAXUINT64, DEFAULT_CEA608_VALID_PADDING_TIMEOUT,
|
|
|
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
|
|
|
|
GST_PARAM_MUTABLE_PLAYING));
|
2022-02-01 22:46:43 +00:00
|
|
|
|
2024-03-12 03:25:31 +00:00
|
|
|
/**
|
|
|
|
* GstCCCombiner:schedule-timeout:
|
|
|
|
*
|
|
|
|
* Timeout to apply when the caption pad is EOS and schedule=true. On
|
|
|
|
* reaching the timeout, no caption data will be placed on the outgoing
|
|
|
|
* buffers until receiving a new stream.
|
|
|
|
*
|
|
|
|
* Since: 1.26
|
|
|
|
*/
|
|
|
|
g_object_class_install_property (G_OBJECT_CLASS (klass),
|
|
|
|
PROP_SCHEDULE_TIMEOUT,
|
|
|
|
g_param_spec_uint64 ("schedule-timeout",
|
|
|
|
"Schedule Timeout",
|
|
|
|
"How long after not receiving caption data on the caption pad to continue adding (padding) caption data on output buffers",
|
|
|
|
0, G_MAXUINT64, DEFAULT_SCHEDULE_TIMEOUT,
|
|
|
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
|
|
|
|
GST_PARAM_MUTABLE_PLAYING));
|
|
|
|
|
2024-02-01 17:45:01 +00:00
|
|
|
/**
|
|
|
|
* GstCCCombiner:input-meta-processing
|
|
|
|
*
|
|
|
|
* Controls how input closed caption meta is processed.
|
|
|
|
*
|
|
|
|
* Since: 1.26
|
|
|
|
*/
|
|
|
|
g_object_class_install_property (G_OBJECT_CLASS (klass),
|
|
|
|
PROP_INPUT_META_PROCESSING, g_param_spec_enum ("input-meta-processing",
|
|
|
|
"Input Meta Processing",
|
|
|
|
"Controls how input closed caption meta is processed",
|
|
|
|
GST_TYPE_CCCOMBINER_INPUT_META_PROCESSING,
|
|
|
|
DEFAULT_INPUT_META_PROCESSING,
|
|
|
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
|
|
|
|
2018-11-05 14:24:58 +00:00
|
|
|
gst_element_class_add_static_pad_template_with_gtype (gstelement_class,
|
|
|
|
&sinktemplate, GST_TYPE_AGGREGATOR_PAD);
|
|
|
|
gst_element_class_add_static_pad_template_with_gtype (gstelement_class,
|
|
|
|
&srctemplate, GST_TYPE_AGGREGATOR_PAD);
|
|
|
|
gst_element_class_add_static_pad_template_with_gtype (gstelement_class,
|
|
|
|
&captiontemplate, GST_TYPE_AGGREGATOR_PAD);
|
|
|
|
|
cccombiner: implement scheduling
Prior to that, cccombiner's behaviour was essentially that of
a funnel: it strictly looked at input timestamps to associate
together video and caption buffers.
This patch instead exposes a "schedule" property, with a default
of TRUE, to control whether caption buffers should be smoothly
scheduled, in order to have exactly one per output video buffer.
This can involve rewriting input captions, for example when the
input is CDP sequence counters are rewritten, time codes are dropped
and potentially re-injected if the input video frame had a time code
meta.
Caption buffers may also get split up in order to assign captions to
the correct field when the input is interlaced.
This can also imply that the input will drift from synchronization,
when there isn't enough padding in the input stream to catch up. In
that case the element will start dropping old caption buffers once
the number of buffers in its internal queue reaches a certain limit
(configurable).
The property is exposed so that existing users of cccombiner can
revert back to the original behaviour, but should eventually be
removed, as that behaviour was simply inadequate.
This commit also disallows changing the input caption type, as
this would needlessly complicate implementation, and removes
the corresponding test.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2076>
2021-03-09 12:22:10 +00:00
|
|
|
gstelement_class->change_state =
|
|
|
|
GST_DEBUG_FUNCPTR (gst_cc_combiner_change_state);
|
2022-02-18 16:06:44 +00:00
|
|
|
gstelement_class->release_pad =
|
|
|
|
GST_DEBUG_FUNCPTR (gst_cc_combiner_release_pad);
|
cccombiner: implement scheduling
Prior to that, cccombiner's behaviour was essentially that of
a funnel: it strictly looked at input timestamps to associate
together video and caption buffers.
This patch instead exposes a "schedule" property, with a default
of TRUE, to control whether caption buffers should be smoothly
scheduled, in order to have exactly one per output video buffer.
This can involve rewriting input captions, for example when the
input is CDP sequence counters are rewritten, time codes are dropped
and potentially re-injected if the input video frame had a time code
meta.
Caption buffers may also get split up in order to assign captions to
the correct field when the input is interlaced.
This can also imply that the input will drift from synchronization,
when there isn't enough padding in the input stream to catch up. In
that case the element will start dropping old caption buffers once
the number of buffers in its internal queue reaches a certain limit
(configurable).
The property is exposed so that existing users of cccombiner can
revert back to the original behaviour, but should eventually be
removed, as that behaviour was simply inadequate.
This commit also disallows changing the input caption type, as
this would needlessly complicate implementation, and removes
the corresponding test.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2076>
2021-03-09 12:22:10 +00:00
|
|
|
|
2018-11-05 14:24:58 +00:00
|
|
|
aggregator_class->aggregate = gst_cc_combiner_aggregate;
|
|
|
|
aggregator_class->stop = gst_cc_combiner_stop;
|
|
|
|
aggregator_class->flush = gst_cc_combiner_flush;
|
|
|
|
aggregator_class->create_new_pad = gst_cc_combiner_create_new_pad;
|
|
|
|
aggregator_class->sink_event = gst_cc_combiner_sink_event;
|
2019-08-14 07:13:52 +00:00
|
|
|
aggregator_class->negotiate = NULL;
|
2022-02-18 16:19:57 +00:00
|
|
|
aggregator_class->get_next_time = gst_cc_combiner_get_next_time;
|
2019-07-09 09:43:53 +00:00
|
|
|
aggregator_class->src_query = gst_cc_combiner_src_query;
|
|
|
|
aggregator_class->sink_query = gst_cc_combiner_sink_query;
|
2020-07-01 01:59:56 +00:00
|
|
|
aggregator_class->peek_next_sample = gst_cc_combiner_peek_next_sample;
|
2018-11-05 14:24:58 +00:00
|
|
|
|
|
|
|
GST_DEBUG_CATEGORY_INIT (gst_cc_combiner_debug, "cccombiner",
|
|
|
|
0, "Closed Caption combiner");
|
2024-02-01 17:45:01 +00:00
|
|
|
|
|
|
|
gst_type_mark_as_plugin_api (GST_TYPE_CCCOMBINER_INPUT_META_PROCESSING, 0);
|
2018-11-05 14:24:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gst_cc_combiner_init (GstCCCombiner * self)
|
|
|
|
{
|
|
|
|
GstPadTemplate *templ;
|
|
|
|
|
|
|
|
templ = gst_static_pad_template_get (&sinktemplate);
|
2022-02-18 16:06:44 +00:00
|
|
|
self->video_pad = g_object_new (GST_TYPE_AGGREGATOR_PAD,
|
2018-11-05 14:24:58 +00:00
|
|
|
"name", "sink", "direction", GST_PAD_SINK, "template", templ, NULL);
|
|
|
|
gst_object_unref (templ);
|
2022-02-18 16:06:44 +00:00
|
|
|
gst_element_add_pad (GST_ELEMENT_CAST (self), GST_PAD_CAST (self->video_pad));
|
2018-11-05 14:24:58 +00:00
|
|
|
|
|
|
|
self->current_frame_captions =
|
|
|
|
g_array_new (FALSE, FALSE, sizeof (CaptionData));
|
|
|
|
g_array_set_clear_func (self->current_frame_captions,
|
|
|
|
(GDestroyNotify) caption_data_clear);
|
|
|
|
|
|
|
|
self->current_video_running_time = self->current_video_running_time_end =
|
2020-04-22 14:53:00 +00:00
|
|
|
self->previous_video_running_time_end = GST_CLOCK_TIME_NONE;
|
2018-11-05 14:24:58 +00:00
|
|
|
|
cccombiner: implement scheduling
Prior to that, cccombiner's behaviour was essentially that of
a funnel: it strictly looked at input timestamps to associate
together video and caption buffers.
This patch instead exposes a "schedule" property, with a default
of TRUE, to control whether caption buffers should be smoothly
scheduled, in order to have exactly one per output video buffer.
This can involve rewriting input captions, for example when the
input is CDP sequence counters are rewritten, time codes are dropped
and potentially re-injected if the input video frame had a time code
meta.
Caption buffers may also get split up in order to assign captions to
the correct field when the input is interlaced.
This can also imply that the input will drift from synchronization,
when there isn't enough padding in the input stream to catch up. In
that case the element will start dropping old caption buffers once
the number of buffers in its internal queue reaches a certain limit
(configurable).
The property is exposed so that existing users of cccombiner can
revert back to the original behaviour, but should eventually be
removed, as that behaviour was simply inadequate.
This commit also disallows changing the input caption type, as
this would needlessly complicate implementation, and removes
the corresponding test.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2076>
2021-03-09 12:22:10 +00:00
|
|
|
self->caption_type = GST_VIDEO_CAPTION_TYPE_UNKNOWN;
|
|
|
|
|
|
|
|
self->prop_schedule = DEFAULT_SCHEDULE;
|
|
|
|
self->prop_max_scheduled = DEFAULT_MAX_SCHEDULED;
|
2022-02-01 22:46:43 +00:00
|
|
|
self->prop_output_padding = DEFAULT_OUTPUT_PADDING;
|
2024-03-08 07:22:53 +00:00
|
|
|
self->prop_cea608_padding_strategy = DEFAULT_CEA608_PADDING_STRATEGY;
|
|
|
|
self->prop_cea608_valid_padding_timeout =
|
|
|
|
DEFAULT_CEA608_VALID_PADDING_TIMEOUT;
|
2024-03-12 03:25:31 +00:00
|
|
|
self->prop_schedule_timeout = DEFAULT_SCHEDULE_TIMEOUT;
|
2024-02-01 17:45:01 +00:00
|
|
|
self->prop_input_meta_processing = DEFAULT_INPUT_META_PROCESSING;
|
cccombiner: implement scheduling
Prior to that, cccombiner's behaviour was essentially that of
a funnel: it strictly looked at input timestamps to associate
together video and caption buffers.
This patch instead exposes a "schedule" property, with a default
of TRUE, to control whether caption buffers should be smoothly
scheduled, in order to have exactly one per output video buffer.
This can involve rewriting input captions, for example when the
input is CDP sequence counters are rewritten, time codes are dropped
and potentially re-injected if the input video frame had a time code
meta.
Caption buffers may also get split up in order to assign captions to
the correct field when the input is interlaced.
This can also imply that the input will drift from synchronization,
when there isn't enough padding in the input stream to catch up. In
that case the element will start dropping old caption buffers once
the number of buffers in its internal queue reaches a certain limit
(configurable).
The property is exposed so that existing users of cccombiner can
revert back to the original behaviour, but should eventually be
removed, as that behaviour was simply inadequate.
This commit also disallows changing the input caption type, as
this would needlessly complicate implementation, and removes
the corresponding test.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2076>
2021-03-09 12:22:10 +00:00
|
|
|
self->cdp_hdr_sequence_cntr = 0;
|
|
|
|
self->cdp_fps_entry = &null_fps_entry;
|
2024-03-12 03:25:31 +00:00
|
|
|
self->last_caption_ts = GST_CLOCK_TIME_NONE;
|
2022-06-01 11:24:41 +00:00
|
|
|
|
|
|
|
self->cc_buffer = cc_buffer_new ();
|
|
|
|
cc_buffer_set_max_buffer_time (self->cc_buffer, GST_CLOCK_TIME_NONE);
|
2024-03-08 07:22:53 +00:00
|
|
|
cc_buffer_set_cea608_valid_timeout (self->cc_buffer,
|
|
|
|
self->prop_cea608_valid_padding_timeout);
|
|
|
|
cc_buffer_set_cea608_padding_strategy (self->cc_buffer,
|
|
|
|
self->prop_cea608_padding_strategy);
|
2018-11-05 14:24:58 +00:00
|
|
|
}
|