mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-07-02 20:55:55 +00:00
divxdec and divxenc ported to 0.10
Original commit message from CVS: divxdec and divxenc ported to 0.10
This commit is contained in:
parent
0ec8bf9972
commit
9536cc03c0
11
ChangeLog
11
ChangeLog
|
@ -1,3 +1,14 @@
|
|||
2005-12-19 Edgard Lima <edgard.lima@indt.org.br>
|
||||
|
||||
* configure.ac:
|
||||
* ext/Makefile.am:
|
||||
* ext/divx/Makefile.am:
|
||||
* ext/divx/gstdivxdec.c:
|
||||
* ext/divx/gstdivxdec.h:
|
||||
* ext/divx/gstdivxenc.c:
|
||||
* ext/divx/gstdivxenc.h:
|
||||
divxdec and divxenc ported to 0.10
|
||||
|
||||
2005-12-18 Julien MOUTTE <julien@moutte.net>
|
||||
|
||||
* docs/plugins/gst-plugins-bad-plugins-decl.txt:
|
||||
|
|
59
configure.ac
59
configure.ac
|
@ -399,6 +399,64 @@ GST_CHECK_FEATURE(DTS, [dts library], dtsdec, [
|
|||
AC_SUBST(DTS_LIBS)
|
||||
])
|
||||
|
||||
dnl *** DIVX ***
|
||||
translit(dnm, m, l) AM_CONDITIONAL(USE_DIVX, true)
|
||||
GST_CHECK_FEATURE(DIVX, [divx plugins], divx, [
|
||||
HAVE_DIVX=yes
|
||||
AC_CHECK_HEADER(encore2.h, ,
|
||||
[ AC_MSG_WARN([Divx4linux encore headers not found]) &&
|
||||
HAVE_DIVX=no ] )
|
||||
if [ test x$HAVE_DIVX = xyes ]; then
|
||||
AC_MSG_CHECKING([Checking for valid divx4linux encore version])
|
||||
AC_TRY_COMPILE([
|
||||
#include <encore2.h>
|
||||
#if ENCORE_VERSION != 20021024
|
||||
#error Wrong version of divx encore libraries
|
||||
#endif
|
||||
], [
|
||||
return 0;
|
||||
], [ HAVE_DIVX=yes && AC_MSG_RESULT(yes)],
|
||||
[ HAVE_DIVX=no && AC_MSG_RESULT(no) &&
|
||||
AC_MSG_WARN([Wrong version of divx4linux installed]) ])
|
||||
fi
|
||||
if [ test x$HAVE_DIVX = xyes ]; then
|
||||
AC_CHECK_HEADER(decore.h, ,
|
||||
[ AC_MSG_WARN([Divx4linux decoder headers not found]) &&
|
||||
HAVE_DIVX=no ] )
|
||||
fi
|
||||
if [ test x$HAVE_DIVX = xyes ]; then
|
||||
AC_MSG_CHECKING([Checking for valid divx4linux decore version])
|
||||
AC_TRY_COMPILE([
|
||||
#include <decore.h>
|
||||
#if DECORE_VERSION != 20021112
|
||||
#error Wrong version of divx decore libraries
|
||||
#endif
|
||||
], [
|
||||
return 0;
|
||||
], [ HAVE_DIVX=yes && AC_MSG_RESULT(yes)],
|
||||
[ HAVE_DIVX=no && AC_MSG_RESULT(no) &&
|
||||
AC_MSG_WARN([Wrong version of divx4linux installed]) ])
|
||||
fi
|
||||
LIBS="-lm"
|
||||
if test x$HAVE_DIVX = xyes; then
|
||||
AC_CHECK_LIB(divxencore, encore, ,
|
||||
[ AC_MSG_WARN([Divx4linux encore libs not found]) &&
|
||||
HAVE_DIVX=no ] )
|
||||
fi
|
||||
if test x$HAVE_DIVX = xyes; then
|
||||
AC_CHECK_LIB(divxdecore, decore, ,
|
||||
[ AC_MSG_WARN([Divx4linux decore libs not found]) &&
|
||||
HAVE_DIVX=no ] )
|
||||
fi
|
||||
if test x$HAVE_DIVX = xyes; then
|
||||
DIVXENC_LIBS="-ldivxencore -lm"
|
||||
DIVXDEC_LIBS="-ldivxdecore -lm"
|
||||
AC_SUBST(DIVXENC_LIBS)
|
||||
AC_SUBST(DIVXDEC_LIBS)
|
||||
fi
|
||||
])
|
||||
|
||||
|
||||
dnl *** musepack ***
|
||||
translit(dnm, m, l) AM_CONDITIONAL(USE_MUSEPACK, true)
|
||||
GST_CHECK_FEATURE(MUSEPACK, [musepackdec], musepack, [
|
||||
|
@ -579,6 +637,7 @@ ext/ivorbis/Makefile
|
|||
ext/gsm/Makefile
|
||||
ext/libmms/Makefile
|
||||
ext/dts/Makefile
|
||||
ext/divx/Makefile
|
||||
ext/musepack/Makefile
|
||||
ext/sdl/Makefile
|
||||
ext/xvid/Makefile
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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))) {
|
||||
GST_ELEMENT_ERROR (divxdec, STREAM, DECODE, (NULL),
|
||||
("Error decoding divx frame: %s (%d)", gst_divxdec_error (ret), ret));
|
||||
gst_buffer_unref (buf);
|
||||
return;
|
||||
if ((res = decore (divxdec->handle, DEC_OPT_FRAME, &xframe, NULL))) {
|
||||
goto not_decoding;
|
||||
}
|
||||
|
||||
gst_pad_push (divxdec->srcpad, GST_DATA (outbuf));
|
||||
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 (res), res));
|
||||
gst_buffer_unref (outbuf);
|
||||
ret = GST_FLOW_ERROR;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
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
|
||||
"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
|
||||
#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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -64,7 +64,7 @@ struct _GstDivxEnc {
|
|||
guint32 csp;
|
||||
gint bitcnt;
|
||||
gint width, height;
|
||||
gfloat fps;
|
||||
gint fps_n, fps_d;
|
||||
};
|
||||
|
||||
struct _GstDivxEncClass {
|
||||
|
|
Loading…
Reference in a new issue