#define DEFAULT_PROP_DEPTH 16
#define DEFAULT_PROP_FPS 0.
#define DEFAULT_PROP_DURATION GST_SECOND
+#define DEFAULT_PROP_INVERT FALSE
enum
{
PROP_DEPTH,
PROP_FPS,
PROP_DURATION,
+ PROP_INVERT,
PROP_LAST,
};
static void gst_smpte_init (GstSMPTE * smpte);
static void gst_smpte_finalize (GstSMPTE * smpte);
-static GstFlowReturn gst_smpte_collected (GstCollectPads * pads,
+static GstFlowReturn gst_smpte_collected (GstCollectPads2 * pads,
GstSMPTE * smpte);
static void gst_smpte_set_property (GObject * object, guint prop_id,
g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_TYPE,
g_param_spec_enum ("type", "Type", "The type of transition to use",
GST_TYPE_SMPTE_TRANSITION_TYPE, DEFAULT_PROP_TYPE,
- G_PARAM_READWRITE));
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_FPS,
g_param_spec_float ("fps", "FPS",
"Frames per second if no input files are given (deprecated)", 0.,
- G_MAXFLOAT, DEFAULT_PROP_FPS, G_PARAM_READWRITE));
+ G_MAXFLOAT, DEFAULT_PROP_FPS,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_BORDER,
g_param_spec_int ("border", "Border",
"The border width of the transition", 0, G_MAXINT,
- DEFAULT_PROP_BORDER, G_PARAM_READWRITE));
+ DEFAULT_PROP_BORDER, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_DEPTH,
g_param_spec_int ("depth", "Depth", "Depth of the mask in bits", 1, 24,
- DEFAULT_PROP_DEPTH, G_PARAM_READWRITE));
+ DEFAULT_PROP_DEPTH, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_DURATION,
g_param_spec_uint64 ("duration", "Duration",
"Duration of the transition effect in nanoseconds", 0, G_MAXUINT64,
- DEFAULT_PROP_DURATION, G_PARAM_READWRITE));
+ DEFAULT_PROP_DURATION, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_INVERT,
+ g_param_spec_boolean ("invert", "Invert",
+ "Invert transition mask", DEFAULT_PROP_INVERT,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_smpte_change_state);
}
}
static gboolean
-gst_smpte_update_mask (GstSMPTE * smpte, gint type, gint depth, gint width,
- gint height)
+gst_smpte_update_mask (GstSMPTE * smpte, gint type, gboolean invert,
+ gint depth, gint width, gint height)
{
GstMask *newmask;
if (smpte->mask) {
if (smpte->type == type &&
+ smpte->invert == invert &&
smpte->depth == depth &&
smpte->width == width && smpte->height == height)
return TRUE;
}
- newmask = gst_mask_factory_new (type, depth, width, height);
+ newmask = gst_mask_factory_new (type, invert, depth, width, height);
if (newmask) {
if (smpte->mask) {
gst_mask_destroy (smpte->mask);
}
smpte->mask = newmask;
smpte->type = type;
+ smpte->invert = invert;
smpte->depth = depth;
smpte->width = width;
smpte->height = height;
GST_DEBUG_OBJECT (smpte, "duration: %d frames", smpte->end_position);
- ret = gst_smpte_update_mask (smpte, smpte->type, smpte->depth, smpte->width,
- smpte->height);
+ ret =
+ gst_smpte_update_mask (smpte, smpte->type, smpte->invert, smpte->depth,
+ smpte->width, smpte->height);
return ret;
}
gst_pad_new_from_static_template (&gst_smpte_src_template, "src");
gst_element_add_pad (GST_ELEMENT (smpte), smpte->srcpad);
- smpte->collect = gst_collect_pads_new ();
- gst_collect_pads_set_function (smpte->collect,
- (GstCollectPadsFunction) GST_DEBUG_FUNCPTR (gst_smpte_collected), smpte);
- gst_collect_pads_start (smpte->collect);
+ smpte->collect = gst_collect_pads2_new ();
+ gst_collect_pads2_set_function (smpte->collect,
+ (GstCollectPads2Function) GST_DEBUG_FUNCPTR (gst_smpte_collected), smpte);
+ gst_collect_pads2_start (smpte->collect);
- gst_collect_pads_add_pad (smpte->collect, smpte->sinkpad1,
- sizeof (GstCollectData));
- gst_collect_pads_add_pad (smpte->collect, smpte->sinkpad2,
- sizeof (GstCollectData));
+ gst_collect_pads2_add_pad (smpte->collect, smpte->sinkpad1,
+ sizeof (GstCollectData2));
+ gst_collect_pads2_add_pad (smpte->collect, smpte->sinkpad2,
+ sizeof (GstCollectData2));
smpte->fps = DEFAULT_PROP_FPS;
smpte->type = DEFAULT_PROP_TYPE;
smpte->border = DEFAULT_PROP_BORDER;
smpte->depth = DEFAULT_PROP_DEPTH;
smpte->duration = DEFAULT_PROP_DURATION;
+ smpte->invert = DEFAULT_PROP_INVERT;
smpte->fps_num = 0;
smpte->fps_denom = 1;
}
gint i, j;
gint min, max;
guint8 *in1u, *in1v, *in2u, *in2v, *outu, *outv;
- gint lumsize = width * height;
- gint chromsize = lumsize >> 2;
+ gint uoffset, voffset, ystr, ustr, vstr;
if (border == 0)
border++;
min = pos - border;
max = pos;
- in1u = in1 + lumsize;
- in1v = in1u + chromsize;
- in2u = in2 + lumsize;
- in2v = in2u + chromsize;
- outu = out + lumsize;
- outv = outu + chromsize;
+ uoffset = I420_U_OFFSET (width, height);
+ voffset = I420_V_OFFSET (width, height);
+
+ ystr = I420_Y_ROWSTRIDE (width);
+ ustr = I420_U_ROWSTRIDE (width);
+ vstr = I420_V_ROWSTRIDE (width);
+
+ in1u = in1 + uoffset;
+ in1v = in1 + voffset;
+ in2u = in2 + uoffset;
+ in2v = in2 + voffset;
+ outu = out + uoffset;
+ outv = out + voffset;
maskp = mask->data;
value = *maskp++;
value = ((CLAMP (value, min, max) - min) << 8) / border;
- *out++ = ((*in1++ * value) + (*in2++ * (256 - value))) >> 8;
+ out[j] = ((in1[j] * value) + (in2[j] * (256 - value))) >> 8;
if (!(i & 1) && !(j & 1)) {
- *outu++ = ((*in1u++ * value) + (*in2u++ * (256 - value))) >> 8;
- *outv++ = ((*in1v++ * value) + (*in2v++ * (256 - value))) >> 8;
+ outu[j / 2] =
+ ((in1u[j / 2] * value) + (in2u[j / 2] * (256 - value))) >> 8;
+ outv[j / 2] =
+ ((in1v[j / 2] * value) + (in2v[j / 2] * (256 - value))) >> 8;
}
}
+ out += ystr;
+ in1 += ystr;
+ in2 += ystr;
+ if (!(i & 1)) {
+ outu += ustr;
+ in1u += ustr;
+ in2u += ustr;
+ outv += vstr;
+ in1v += vstr;
+ in2v += vstr;
+ }
}
}
static GstFlowReturn
-gst_smpte_collected (GstCollectPads * pads, GstSMPTE * smpte)
+gst_smpte_collected (GstCollectPads2 * pads, GstSMPTE * smpte)
{
GstBuffer *outbuf;
GstClockTime ts;
smpte->fps_denom, smpte->fps_num);
for (collected = pads->data; collected; collected = g_slist_next (collected)) {
- GstCollectData *data;
+ GstCollectData2 *data;
- data = (GstCollectData *) collected->data;
+ data = (GstCollectData2 *) collected->data;
if (data->pad == smpte->sinkpad1)
- in1 = gst_collect_pads_pop (pads, data);
+ in1 = gst_collect_pads2_pop (pads, data);
else if (data->pad == smpte->sinkpad2)
- in2 = gst_collect_pads_pop (pads, data);
+ in2 = gst_collect_pads2_pop (pads, data);
}
if (in1 == NULL) {
case PROP_DURATION:
smpte->duration = g_value_get_uint64 (value);
break;
+ case PROP_INVERT:
+ smpte->invert = g_value_get_boolean (value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
case PROP_DURATION:
g_value_set_uint64 (value, smpte->duration);
break;
+ case PROP_INVERT:
+ g_value_set_boolean (value, smpte->invert);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
case GST_STATE_CHANGE_READY_TO_PAUSED:
gst_smpte_reset (smpte);
GST_LOG_OBJECT (smpte, "starting collectpads");
- gst_collect_pads_start (smpte->collect);
+ gst_collect_pads2_start (smpte->collect);
break;
case GST_STATE_CHANGE_PAUSED_TO_READY:
GST_LOG_OBJECT (smpte, "stopping collectpads");
- gst_collect_pads_stop (smpte->collect);
+ gst_collect_pads2_stop (smpte->collect);
break;
default:
break;