summaryrefslogtreecommitdiffstats
path: root/ext
diff options
context:
space:
mode:
authorEdgard Lima <edgard.lima@indt.org.br>2005-12-19 14:40:22 +0000
committerEdgard Lima <edgard.lima@indt.org.br>2005-12-19 14:40:22 +0000
commit9536cc03c0961801c823168ee2af7831e7cd458c (patch)
treee1c5b7ddc0feb7e0223aa653957d5ad8d16b79ef /ext
parent0ec8bf9972e3cf0e15757b781f08b065efa4148b (diff)
downloadgst-plugins-bad-9536cc03c0961801c823168ee2af7831e7cd458c.tar.gz
gst-plugins-bad-9536cc03c0961801c823168ee2af7831e7cd458c.tar.bz2
gst-plugins-bad-9536cc03c0961801c823168ee2af7831e7cd458c.zip
divxdec and divxenc ported to 0.10
Original commit message from CVS: divxdec and divxenc ported to 0.10
Diffstat (limited to 'ext')
-rw-r--r--ext/Makefile.am9
-rw-r--r--ext/divx/Makefile.am11
-rw-r--r--ext/divx/gstdivxdec.c309
-rw-r--r--ext/divx/gstdivxdec.h4
-rw-r--r--ext/divx/gstdivxenc.c146
-rw-r--r--ext/divx/gstdivxenc.h2
6 files changed, 300 insertions, 181 deletions
diff --git a/ext/Makefile.am b/ext/Makefile.am
index 58c96f38..c1f06a9b 100644
--- a/ext/Makefile.am
+++ b/ext/Makefile.am
@@ -40,11 +40,11 @@ else
DIRECTFB_DIR=
endif
-#if USE_DIVX
-#DIVX_DIR=divx
-#else
+if USE_DIVX
+DIVX_DIR=divx
+else
DIVX_DIR=
-#endif
+endif
if USE_DTS
DTS_DIR=dts
@@ -239,6 +239,7 @@ DIST_SUBDIRS= \
ivorbis \
libmms \
dts \
+ divx \
musepack \
sdl \
swfdec \
diff --git a/ext/divx/Makefile.am b/ext/divx/Makefile.am
index e5323e11..8eee5b86 100644
--- a/ext/divx/Makefile.am
+++ b/ext/divx/Makefile.am
@@ -1,14 +1,15 @@
-plugin_LTLIBRARIES = libgstdivxenc.la libgstdivxdec.la
+plugin_LTLIBRARIES = libgstdivxdec.la
+plugin_LTLIBRARIES = libgstdivxenc.la
libgstdivxenc_la_SOURCES = gstdivxenc.c
-libgstdivxenc_la_CFLAGS = $(GST_CFLAGS) $(DIVX_CFLAGS)
-libgstdivxenc_la_LIBADD = $(DIVXENC_LIBS)
+libgstdivxenc_la_CFLAGS = $(GST_CFLAGS) $(DIVX_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS)
+libgstdivxenc_la_LIBADD = $(DIVXENC_LIBS) $(GST_PLUGINS_BASE_LIBS)
libgstdivxenc_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
libgstdivxdec_la_SOURCES = gstdivxdec.c
-libgstdivxdec_la_CFLAGS = $(GST_CFLAGS) $(DIVX_CFLAGS)
-libgstdivxdec_la_LIBADD = $(DIVXDEC_LIBS)
+libgstdivxdec_la_CFLAGS = $(GST_CFLAGS) $(DIVX_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS)
+libgstdivxdec_la_LIBADD = $(DIVXDEC_LIBS) $(GST_PLUGINS_BASE_LIBS)
libgstdivxdec_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
noinst_HEADERS = gstdivxenc.h gstdivxdec.h
diff --git a/ext/divx/gstdivxdec.c b/ext/divx/gstdivxdec.c
index 543bff3f..29b838e2 100644
--- a/ext/divx/gstdivxdec.c
+++ b/ext/divx/gstdivxdec.c
@@ -39,7 +39,7 @@ static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
GST_STATIC_CAPS ("video/x-divx, "
"divxversion = (int) [ 3, 5 ], "
"width = (int) [ 16, 4096 ], "
- "height = (int) [ 16, 4096 ], " "framerate = (double) [ 0, MAX ]")
+ "height = (int) [ 16, 4096 ], " "framerate = (fraction) [0/1, MAX]")
);
static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
@@ -69,11 +69,11 @@ static void gst_divxdec_base_init (GstDivxDecClass * klass);
static void gst_divxdec_class_init (GstDivxDecClass * klass);
static void gst_divxdec_init (GstDivxDec * divxdec);
static void gst_divxdec_dispose (GObject * object);
-static void gst_divxdec_chain (GstPad * pad, GstData * data);
-static GstPadLinkReturn gst_divxdec_connect (GstPad * pad,
- const GstCaps * vscapslist);
-static GstPadLinkReturn gst_divxdec_negotiate (GstDivxDec * divxdec);
-
+static GstFlowReturn gst_divxdec_chain (GstPad * pad, GstBuffer * buf);
+static gboolean gst_divxdec_connect (GstPad * pad, GstCaps * vscapslist);
+static gboolean gst_divxdec_negotiate (GstDivxDec * divxdec);
+static GstStateChangeReturn
+gst_divxdec_change_state (GstElement * element, GstStateChange transition);
static GstElementClass *parent_class = NULL;
/* static guint gst_divxdec_signals[LAST_SIGNAL] = { 0 }; */
@@ -150,10 +150,12 @@ gst_divxdec_base_init (GstDivxDecClass * klass)
static void
gst_divxdec_class_init (GstDivxDecClass * klass)
{
+ GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
GObjectClass *gobject_class = (GObjectClass *) klass;
parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
+ gstelement_class->change_state = gst_divxdec_change_state;
gobject_class->dispose = gst_divxdec_dispose;
}
@@ -167,14 +169,14 @@ gst_divxdec_init (GstDivxDec * divxdec)
"sink");
gst_element_add_pad (GST_ELEMENT (divxdec), divxdec->sinkpad);
gst_pad_set_chain_function (divxdec->sinkpad, gst_divxdec_chain);
- gst_pad_set_link_function (divxdec->sinkpad, gst_divxdec_connect);
+ gst_pad_set_setcaps_function (divxdec->sinkpad, gst_divxdec_connect);
/* create the src pad */
divxdec->srcpad =
gst_pad_new_from_template (gst_static_pad_template_get (&src_template),
"src");
gst_element_add_pad (GST_ELEMENT (divxdec), divxdec->srcpad);
- gst_pad_use_explicit_caps (divxdec->srcpad);
+ gst_pad_use_fixed_caps (divxdec->srcpad);
/* bitrate, etc. */
divxdec->width = divxdec->height = divxdec->csp = divxdec->bitcnt = -1;
@@ -244,11 +246,9 @@ gst_divxdec_setup (GstDivxDec * divxdec)
gst_divxdec_unset (divxdec);
return FALSE;
}
-
return TRUE;
}
-
static void
gst_divxdec_dispose (GObject * object)
{
@@ -258,28 +258,19 @@ gst_divxdec_dispose (GObject * object)
G_OBJECT_CLASS (parent_class)->dispose (object);
}
-
-static void
-gst_divxdec_chain (GstPad * pad, GstData * _data)
+static GstFlowReturn
+gst_divxdec_chain (GstPad * pad, GstBuffer * buf)
{
- GstBuffer *buf = GST_BUFFER (_data);
GstDivxDec *divxdec;
GstBuffer *outbuf;
DEC_FRAME xframe;
- int ret;
-
- g_return_if_fail (pad != NULL);
- g_return_if_fail (GST_IS_PAD (pad));
- g_return_if_fail (buf != NULL);
-
- divxdec = GST_DIVXDEC (GST_OBJECT_PARENT (pad));
+ int res;
+ GstFlowReturn ret;
+ divxdec = GST_DIVXDEC (gst_pad_get_parent (pad));
if (!divxdec->handle) {
if (gst_divxdec_negotiate (divxdec) <= 0) {
- GST_ELEMENT_ERROR (divxdec, CORE, TOO_LAZY, (NULL),
- ("No format set - aborting"));
- gst_buffer_unref (buf);
- return;
+ goto not_negotiated;
}
}
@@ -296,15 +287,37 @@ gst_divxdec_chain (GstPad * pad, GstData * _data)
xframe.stride = 0;
xframe.render_flag = 1;
- if ((ret = decore (divxdec->handle, DEC_OPT_FRAME, &xframe, NULL))) {
+ if ((res = decore (divxdec->handle, DEC_OPT_FRAME, &xframe, NULL))) {
+ goto not_decoding;
+ }
+
+ gst_buffer_set_caps (outbuf, GST_PAD_CAPS (divxdec->srcpad));
+ ret = gst_pad_push (divxdec->srcpad, outbuf);
+ goto cleanup;
+
+not_negotiated:
+ {
+ GST_ELEMENT_ERROR (divxdec, CORE, TOO_LAZY, (NULL),
+ ("No format set - aborting"));
+ ret = GST_FLOW_NOT_NEGOTIATED;
+ goto cleanup;
+ }
+
+not_decoding:
+ {
GST_ELEMENT_ERROR (divxdec, STREAM, DECODE, (NULL),
- ("Error decoding divx frame: %s (%d)", gst_divxdec_error (ret), ret));
- gst_buffer_unref (buf);
- return;
+ ("Error decoding divx frame: %s (%d)", gst_divxdec_error (res), res));
+ gst_buffer_unref (outbuf);
+ ret = GST_FLOW_ERROR;
+ goto cleanup;
}
- gst_pad_push (divxdec->srcpad, GST_DATA (outbuf));
+cleanup:
+
gst_buffer_unref (buf);
+ gst_object_unref (divxdec);
+ return ret;
+
}
@@ -312,85 +325,89 @@ gst_divxdec_chain (GstPad * pad, GstData * _data)
* stays clear */
/*
-{
+ {
GST_MAKE_FOURCC ('R', 'G', 'B', ' '), 32, 32,
-#if (G_BYTE_ORDER == G_BIG_ENDIAN)
-GST_MAKE_FOURCC ('A', 'B', 'G', 'R'), 32}
+ #if (G_BYTE_ORDER == G_BIG_ENDIAN)
+ GST_MAKE_FOURCC ('A', 'B', 'G', 'R'), 32}
-,
-#else
-0, 32}
+ ,
+ #else
+ 0, 32}
-,
-#endif
-{
+ ,
+ #endif
+ {
GST_MAKE_FOURCC ('R', 'G', 'B', ' '), 24, 24,
-#if (G_BYTE_ORDER == G_BIG_ENDIAN)
-GST_MAKE_FOURCC ('A', 'B', 'G', 'R'), 24}
+ #if (G_BYTE_ORDER == G_BIG_ENDIAN)
+ GST_MAKE_FOURCC ('A', 'B', 'G', 'R'), 24}
-,
-#else
-0, 24}
+ ,
+ #else
+ 0, 24}
-,
-#endif
-{
-GST_MAKE_FOURCC ('R', 'G', 'B', ' '), 16, 16, 3, 16}
+ ,
+ #endif
+ {
+ GST_MAKE_FOURCC ('R', 'G', 'B', ' '), 16, 16, 3, 16}
-, {
-GST_MAKE_FOURCC ('R', 'G', 'B', ' '), 15, 16, 0, 16}
+ , {
+ GST_MAKE_FOURCC ('R', 'G', 'B', ' '), 15, 16, 0, 16}
-,
-#endif
- if (fmt_list[i].fourcc == GST_MAKE_FOURCC ('R', 'G', 'B', ' ')) {
+ ,
+ #endif
+ if (fmt_list[i].fourcc == GST_MAKE_FOURCC ('R', 'G', 'B', ' ')) {
guint32 r_mask = 0, b_mask = 0, g_mask = 0;
gint endianness = 0;
switch (fmt_list[i].depth) {
- case 15:
- endianness = G_BYTE_ORDER;
- r_mask = 0xf800;
- g_mask = 0x07c0;
- b_mask = 0x003e;
- break;
- case 16:
- endianness = G_BYTE_ORDER;
- r_mask = 0xf800;
- g_mask = 0x07e0;
- b_mask = 0x001f;
- break;
- case 24:
- endianness = G_BIG_ENDIAN;
- r_mask = GST_VIDEO_BYTE1_MASK_24_INT;
- g_mask = GST_VIDEO_BYTE2_MASK_24_INT;
- b_mask = GST_VIDEO_BYTE3_MASK_24_INT break;
- case 32:
- endianness = G_BIG_ENDIAN;
- r_mask = GST_VIDEO_BYTE1_MASK_32_INT;
- g_mask = GST_VIDEO_BYTE2_MASK_32_INT;
- b_mask = GST_VIDEO_BYTE3_MASK_32_INT break;
+ case 15:
+ endianness = G_BYTE_ORDER;
+ r_mask = 0xf800;
+ g_mask = 0x07c0;
+ b_mask = 0x003e;
+ break;
+ case 16:
+ endianness = G_BYTE_ORDER;
+ r_mask = 0xf800;
+ g_mask = 0x07e0;
+ b_mask = 0x001f;
+ break;
+ case 24:
+ endianness = G_BIG_ENDIAN;
+ r_mask = GST_VIDEO_BYTE1_MASK_24_INT;
+ g_mask = GST_VIDEO_BYTE2_MASK_24_INT;
+ b_mask = GST_VIDEO_BYTE3_MASK_24_INT break;
+ case 32:
+ endianness = G_BIG_ENDIAN;
+ r_mask = GST_VIDEO_BYTE1_MASK_32_INT;
+ g_mask = GST_VIDEO_BYTE2_MASK_32_INT;
+ b_mask = GST_VIDEO_BYTE3_MASK_32_INT break;
}
caps = GST_CAPS_NEW ("divxdec_src_pad_rgb",
- "video/x-raw-rgb",
- "width", GST_PROPS_INT (divxdec->width),
- "height", GST_PROPS_INT (divxdec->height),
- "framerate", GST_PROPS_FLOAT (divxdec->fps),
- "depth", GST_PROPS_INT (fmt_list[i].depth),
- "bpp", GST_PROPS_INT (fmt_list[i].bpp),
- "endianness", GST_PROPS_INT (endianness),
- "red_mask", GST_PROPS_INT (r_mask),
- "green_mask", GST_PROPS_INT (g_mask),
- "blue_mask", GST_PROPS_INT (b_mask));
-} else {
-#endif
-
-#endif
+ "video/x-raw-rgb",
+ "width", GST_PROPS_INT (divxdec->width),
+ "height", GST_PROPS_INT (divxdec->height),
+ "framerate", GST_PROPS_FLOAT (divxdec->fps),
+ "depth", GST_PROPS_INT (fmt_list[i].depth),
+ "bpp", GST_PROPS_INT (fmt_list[i].bpp),
+ "endianness", GST_PROPS_INT (endianness),
+ "red_mask", GST_PROPS_INT (r_mask),
+ "green_mask", GST_PROPS_INT (g_mask),
+ "blue_mask", GST_PROPS_INT (b_mask));
+ } else {
+ #endif
+
+ #endif
*/
-static GstPadLinkReturn
+static gboolean
gst_divxdec_negotiate (GstDivxDec * divxdec)
{
- GstCaps *caps;
+ GstCaps *caps = NULL;
+ gint i;
+ gint par_num, par_den;
+ gboolean ret = FALSE;
+
struct
{
guint32 fourcc;
@@ -398,6 +415,7 @@ gst_divxdec_negotiate (GstDivxDec * divxdec)
guint32 csp;
gint bitcnt;
}
+
fmt_list[] = {
{
GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'), 16, 16,
@@ -414,7 +432,18 @@ gst_divxdec_negotiate (GstDivxDec * divxdec)
, {
0, 0, 0, 0, 0}
};
- gint i;
+
+ GST_DEBUG_OBJECT (divxdec, "fps %d/%d, PAR %d/%d",
+ divxdec->fps_n, divxdec->fps_d, divxdec->par_n, divxdec->par_d);
+
+ /* calculate par
+ * the info.aspect_* values reflect PAR;
+ * 0:0 is allowed and can be interpreted as 1:1, so correct for it */
+ par_num = divxdec->par_n;
+ par_den = divxdec->par_d;
+ if (par_num == 0 && par_den == 0) {
+ par_num = par_den = 1;
+ }
for (i = 0; fmt_list[i].fourcc != 0; i++) {
divxdec->csp = fmt_list[i].csp;
@@ -422,27 +451,48 @@ gst_divxdec_negotiate (GstDivxDec * divxdec)
caps = gst_caps_new_simple ("video/x-raw-yuv",
"width", G_TYPE_INT, divxdec->width,
"height", G_TYPE_INT, divxdec->height,
- "framerate", G_TYPE_DOUBLE, divxdec->fps,
+ "framerate", GST_TYPE_FRACTION, divxdec->fps_n, divxdec->fps_d,
+ "pixel-aspect-ratio", GST_TYPE_FRACTION, par_num, par_den,
"format", GST_TYPE_FOURCC, fmt_list[i].fourcc, NULL);
- if (gst_divxdec_setup (divxdec) &&
- gst_pad_set_explicit_caps (divxdec->srcpad, caps)) {
- divxdec->csp = fmt_list[i].csp;
- divxdec->bpp = fmt_list[i].bpp;
- divxdec->bitcnt = fmt_list[i].bitcnt;
- return GST_PAD_LINK_OK;
+ if (caps) {
+
+ if (gst_divxdec_setup (divxdec) &&
+ gst_pad_set_caps (divxdec->srcpad, caps)) {
+ divxdec->csp = fmt_list[i].csp;
+ divxdec->bpp = fmt_list[i].bpp;
+ divxdec->bitcnt = fmt_list[i].bitcnt;
+ ret = TRUE;
+ goto done;
+ }
+
+ gst_caps_unref (caps);
+ caps = NULL;
+
}
+
}
/* if we got here - it's not good */
- return GST_PAD_LINK_REFUSED;
+
+done:
+
+ if (caps) {
+ gst_caps_unref (caps);
+ }
+
+ return ret;
}
-static GstPadLinkReturn
-gst_divxdec_connect (GstPad * pad, const GstCaps * caps)
+static gboolean
+gst_divxdec_connect (GstPad * pad, GstCaps * caps)
{
GstDivxDec *divxdec;
+ const GValue *par;
+ const GValue *fps;
+ gboolean ret = FALSE;
+
GstStructure *structure = gst_caps_get_structure (caps, 0);
divxdec = GST_DIVXDEC (gst_pad_get_parent (pad));
@@ -452,18 +502,61 @@ gst_divxdec_connect (GstPad * pad, const GstCaps * caps)
gst_divxdec_unset (divxdec);
}
- /* we are not going to act on variable caps */
- if (!gst_caps_is_fixed (caps))
- return GST_PAD_LINK_DELAYED;
-
/* if we get here, we know the input is divx. we
* only need to bother with the output colorspace */
gst_structure_get_int (structure, "width", &divxdec->width);
gst_structure_get_int (structure, "height", &divxdec->height);
- gst_structure_get_double (structure, "framerate", &divxdec->fps);
gst_structure_get_int (structure, "divxversion", &divxdec->version);
- return gst_divxdec_negotiate (divxdec);
+ /* get pixel aspect ratio if it's set */
+ par = gst_structure_get_value (structure, "pixel-aspect-ratio");
+ if (par) {
+ divxdec->par_n = gst_value_get_fraction_numerator (par),
+ divxdec->par_d = gst_value_get_fraction_denominator (par);
+ }
+
+ fps = gst_structure_get_value (structure, "framerate");
+ if (fps != NULL) {
+ divxdec->fps_n = gst_value_get_fraction_numerator (fps);
+ divxdec->fps_d = gst_value_get_fraction_denominator (fps);
+ } else {
+ divxdec->fps_n = -1;
+ }
+
+ ret = gst_divxdec_negotiate (divxdec);
+ gst_object_unref (divxdec);
+
+ return ret;
+}
+
+static GstStateChangeReturn
+gst_divxdec_change_state (GstElement * element, GstStateChange transition)
+{
+ GstStateChangeReturn ret;
+
+ switch (transition) {
+ case GST_STATE_CHANGE_NULL_TO_READY:
+ break;
+ case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
+ break;
+ default:
+ break;
+ }
+
+ ret = parent_class->change_state (element, transition);
+
+ switch (transition) {
+ case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
+ break;
+ case GST_STATE_CHANGE_PAUSED_TO_READY:
+ break;
+ case GST_STATE_CHANGE_READY_TO_NULL:
+ break;
+ default:
+ break;
+ }
+
+ return ret;
}
diff --git a/ext/divx/gstdivxdec.h b/ext/divx/gstdivxdec.h
index 0468ff0a..90c47037 100644
--- a/ext/divx/gstdivxdec.h
+++ b/ext/divx/gstdivxdec.h
@@ -56,7 +56,9 @@ struct _GstDivxDec {
int bitcnt, bpp;
int version;
int width, height;
- gdouble fps;
+
+ gint fps_n, fps_d;
+ gint par_n, par_d;
};
struct _GstDivxDecClass {
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)
diff --git a/ext/divx/gstdivxenc.h b/ext/divx/gstdivxenc.h
index 206659d3..0d5cad05 100644
--- a/ext/divx/gstdivxenc.h
+++ b/ext/divx/gstdivxenc.h
@@ -64,7 +64,7 @@ struct _GstDivxEnc {
guint32 csp;
gint bitcnt;
gint width, height;
- gfloat fps;
+ gint fps_n, fps_d;
};
struct _GstDivxEncClass {