summaryrefslogtreecommitdiffstats
path: root/ext/divx/gstdivxenc.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/divx/gstdivxenc.c')
-rw-r--r--ext/divx/gstdivxenc.c146
1 files changed, 84 insertions, 62 deletions
diff --git a/ext/divx/gstdivxenc.c b/ext/divx/gstdivxenc.c
index 591bb90e..5269e01e 100644
--- a/ext/divx/gstdivxenc.c
+++ b/ext/divx/gstdivxenc.c
@@ -48,7 +48,7 @@ static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
GST_STATIC_CAPS ("video/x-divx, "
"divxversion = (int) 5, "
"width = (int) [ 16, 4096 ], "
- "height = (int) [ 16, 4096 ], " "framerate = (double) [ 0, MAX ]")
+ "height = (int) [ 16, 4096 ], " "framerate = (fraction) [0/1, MAX]")
);
@@ -73,9 +73,8 @@ static void gst_divxenc_class_init (GstDivxEncClass * klass);
static void gst_divxenc_base_init (GstDivxEncClass * klass);
static void gst_divxenc_init (GstDivxEnc * divxenc);
static void gst_divxenc_dispose (GObject * object);
-static void gst_divxenc_chain (GstPad * pad, GstData * data);
-static GstPadLinkReturn gst_divxenc_connect (GstPad * pad,
- const GstCaps * vscapslist);
+static GstFlowReturn gst_divxenc_chain (GstPad * pad, GstBuffer * buf);
+static gboolean gst_divxenc_setcaps (GstPad * pad, GstCaps * caps);
/* properties */
static void gst_divxenc_set_property (GObject * object,
@@ -162,13 +161,12 @@ gst_divxenc_base_init (GstDivxEncClass * klass)
static void
gst_divxenc_class_init (GstDivxEncClass * klass)
{
- GstElementClass *gstelement_class;
- GObjectClass *gobject_class;
+ GObjectClass *gobject_class = (GObjectClass *) klass;
- gobject_class = (GObjectClass *) klass;
- gstelement_class = (GstElementClass *) klass;
+ parent_class = g_type_class_peek_parent (klass);
- parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
+ gobject_class->set_property = gst_divxenc_set_property;
+ gobject_class->get_property = gst_divxenc_get_property;
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_BITRATE,
g_param_spec_ulong ("bitrate", "Bitrate",
@@ -187,9 +185,6 @@ gst_divxenc_class_init (GstDivxEncClass * klass)
g_param_spec_int ("quality", "Quality",
"Amount of Motion Estimation", 1, 5, 3, G_PARAM_READWRITE));
- gobject_class->set_property = gst_divxenc_set_property;
- gobject_class->get_property = gst_divxenc_get_property;
-
gobject_class->dispose = gst_divxenc_dispose;
gst_divxenc_signals[FRAME_ENCODED] =
@@ -210,13 +205,13 @@ gst_divxenc_init (GstDivxEnc * divxenc)
gst_element_add_pad (GST_ELEMENT (divxenc), divxenc->sinkpad);
gst_pad_set_chain_function (divxenc->sinkpad, gst_divxenc_chain);
- gst_pad_set_link_function (divxenc->sinkpad, gst_divxenc_connect);
+ gst_pad_set_setcaps_function (divxenc->sinkpad, gst_divxenc_setcaps);
/* create the src pad */
divxenc->srcpad =
gst_pad_new_from_template (gst_static_pad_template_get (&src_template),
"src");
- gst_pad_use_explicit_caps (divxenc->srcpad);
+ gst_pad_use_fixed_caps (divxenc->srcpad);
gst_element_add_pad (GST_ELEMENT (divxenc), divxenc->srcpad);
/* bitrate, etc. */
@@ -254,7 +249,7 @@ gst_divxenc_setup (GstDivxEnc * divxenc)
output.use_bidirect = 1;
output.input_clock = 0;
output.input_frame_period = 1000000;
- output.internal_timescale = divxenc->fps * 1000000;
+ output.internal_timescale = (divxenc->fps_n / divxenc->fps_d) * 1000000; /* FIX? */
output.max_key_interval = (divxenc->max_key_interval == -1) ?
150 : divxenc->max_key_interval;
output.key_frame_threshold = 50;
@@ -314,21 +309,17 @@ gst_divxenc_dispose (GObject * object)
}
-static void
-gst_divxenc_chain (GstPad * pad, GstData * _data)
+static GstFlowReturn
+gst_divxenc_chain (GstPad * pad, GstBuffer * buf)
{
- GstBuffer *buf = GST_BUFFER (_data);
GstDivxEnc *divxenc;
GstBuffer *outbuf;
ENC_FRAME xframe;
ENC_RESULT xres;
- int ret;
+ int res;
+ GstFlowReturn ret = GST_FLOW_OK;
- g_return_if_fail (pad != NULL);
- g_return_if_fail (GST_IS_PAD (pad));
- g_return_if_fail (buf != NULL);
-
- divxenc = GST_DIVXENC (GST_OBJECT_PARENT (pad));
+ divxenc = GST_DIVXENC (gst_pad_get_parent (pad));
outbuf = gst_buffer_new_and_alloc (divxenc->buffer_size);
GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (buf);
@@ -336,28 +327,38 @@ gst_divxenc_chain (GstPad * pad, GstData * _data)
/* encode and so ... */
xframe.image = GST_BUFFER_DATA (buf);
xframe.bitstream = (void *) GST_BUFFER_DATA (outbuf);
- xframe.length = GST_BUFFER_MAXSIZE (outbuf);
+ xframe.length = GST_BUFFER_SIZE (outbuf); /* GST_BUFFER_MAXSIZE */
xframe.produce_empty_frame = 0;
- if ((ret = encore (divxenc->handle, ENC_OPT_ENCODE, &xframe, &xres))) {
- GST_ELEMENT_ERROR (divxenc, LIBRARY, ENCODE, (NULL),
- ("Error encoding divx frame: %s (%d)", gst_divxenc_error (ret), ret));
- gst_buffer_unref (buf);
- return;
+ if ((res = encore (divxenc->handle, ENC_OPT_ENCODE, &xframe, &xres))) {
+ goto not_encoding;
}
GST_BUFFER_SIZE (outbuf) = xframe.length;
- if (xres.cType == 'I')
- GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_KEY_UNIT);
/* go out, multiply! */
- gst_pad_push (divxenc->srcpad, GST_DATA (outbuf));
+ gst_buffer_set_caps (outbuf, GST_PAD_CAPS (divxenc->srcpad));
+ gst_pad_push (divxenc->srcpad, outbuf);
/* proclaim destiny */
g_signal_emit (G_OBJECT (divxenc), gst_divxenc_signals[FRAME_ENCODED], 0);
/* until the final judgement */
+ goto done;
+
+not_encoding:
+
+ GST_ELEMENT_ERROR (divxenc, LIBRARY, ENCODE, (NULL),
+ ("Error encoding divx frame: %s (%d)", gst_divxenc_error (res), res));
+ ret = GST_FLOW_ERROR;
+ gst_buffer_unref (outbuf);
+ goto done;
+
+done:
gst_buffer_unref (buf);
+ gst_object_unref (divxenc);
+ return ret;
+
}
/* FIXME: moving broken bits here for others to fix */
@@ -366,26 +367,27 @@ gst_divxenc_chain (GstPad * pad, GstData * _data)
case GST_MAKE_FOURCC ('R', 'G', 'B', ' '):
gst_caps_get_int (caps, "depth", &d);
switch (d) {
- case 24:
- divx_cs = 0;
- bitcnt = 24;
- break;
- case 32:
- divx_cs = 0;
- bitcnt = 32;
- break;
+ case 24:
+ divx_cs = 0;
+ bitcnt = 24;
+ break;
+ case 32:
+ divx_cs = 0;
+ bitcnt = 32;
+ break;
*/
-static GstPadLinkReturn
-gst_divxenc_connect (GstPad * pad, const GstCaps * caps)
+static gboolean
+gst_divxenc_setcaps (GstPad * pad, GstCaps * caps)
{
GstDivxEnc *divxenc;
GstStructure *structure = gst_caps_get_structure (caps, 0);
gint w, h;
- gdouble fps;
+ const GValue *fps;
guint32 fourcc;
guint32 divx_cs;
gint bitcnt = 0;
+ gboolean ret = FALSE;
divxenc = GST_DIVXENC (gst_pad_get_parent (pad));
@@ -394,9 +396,16 @@ gst_divxenc_connect (GstPad * pad, const GstCaps * caps)
gst_structure_get_int (structure, "width", &w);
gst_structure_get_int (structure, "height", &h);
- gst_structure_get_double (structure, "framerate", &fps);
gst_structure_get_fourcc (structure, "format", &fourcc);
+ fps = gst_structure_get_value (structure, "framerate");
+ if (fps != NULL && GST_VALUE_HOLDS_FRACTION (fps)) {
+ divxenc->fps_n = gst_value_get_fraction_numerator (fps);
+ divxenc->fps_d = gst_value_get_fraction_denominator (fps);
+ } else {
+ divxenc->fps_n = -1;
+ }
+
switch (fourcc) {
case GST_MAKE_FOURCC ('I', '4', '2', '0'):
divx_cs = GST_MAKE_FOURCC ('I', '4', '2', '0');
@@ -414,35 +423,47 @@ gst_divxenc_connect (GstPad * pad, const GstCaps * caps)
divx_cs = GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y');
break;
default:
- return GST_PAD_LINK_REFUSED;
+ ret = FALSE;
+ goto done;
}
divxenc->csp = divx_cs;
divxenc->bitcnt = bitcnt;
divxenc->width = w;
divxenc->height = h;
- divxenc->fps = fps;
/* try it */
if (gst_divxenc_setup (divxenc)) {
- GstPadLinkReturn ret;
- GstCaps *new_caps;
+ GstCaps *new_caps = NULL;
new_caps = gst_caps_new_simple ("video/x-divx",
"divxversion", G_TYPE_INT, 5,
"width", G_TYPE_INT, w,
- "height", G_TYPE_INT, h, "framerate", G_TYPE_DOUBLE, fps, NULL);
+ "height", G_TYPE_INT, h,
+ "framerate", GST_TYPE_FRACTION, divxenc->fps_n, divxenc->fps_d, NULL);
+
+ if (new_caps) {
+
+ if (!gst_pad_set_caps (divxenc->srcpad, new_caps)) {
+ gst_divxenc_unset (divxenc);
+ ret = FALSE;
+ goto done;
+ }
+ gst_caps_unref (new_caps);
+ ret = TRUE;
+ goto done;
- ret = gst_pad_set_explicit_caps (divxenc->srcpad, new_caps);
- if (ret <= 0) {
- gst_divxenc_unset (divxenc);
}
- return ret;
}
/* if we got here - it's not good */
- return GST_PAD_LINK_REFUSED;
+
+ ret = FALSE;
+
+done:
+ gst_object_unref (divxenc);
+ return ret;
}
@@ -450,10 +471,9 @@ static void
gst_divxenc_set_property (GObject * object,
guint prop_id, const GValue * value, GParamSpec * pspec)
{
- GstDivxEnc *divxenc;
+ GstDivxEnc *divxenc = GST_DIVXENC (object);
- g_return_if_fail (GST_IS_DIVXENC (object));
- divxenc = GST_DIVXENC (object);
+ GST_OBJECT_LOCK (divxenc);
switch (prop_id) {
case ARG_BITRATE:
@@ -469,6 +489,8 @@ gst_divxenc_set_property (GObject * object,
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
+
+ GST_OBJECT_UNLOCK (divxenc);
}
@@ -476,10 +498,9 @@ static void
gst_divxenc_get_property (GObject * object,
guint prop_id, GValue * value, GParamSpec * pspec)
{
- GstDivxEnc *divxenc;
+ GstDivxEnc *divxenc = GST_DIVXENC (object);
- g_return_if_fail (GST_IS_DIVXENC (object));
- divxenc = GST_DIVXENC (object);
+ GST_OBJECT_LOCK (divxenc);
switch (prop_id) {
case ARG_BITRATE:
@@ -498,8 +519,9 @@ gst_divxenc_get_property (GObject * object,
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
-}
+ GST_OBJECT_UNLOCK (divxenc);
+}
static gboolean
plugin_init (GstPlugin * plugin)