Update plugins to newest divx.com release API (5.2) (why aren't these libs API stable?!?)

Original commit message from CVS:
Update plugins to newest divx.com release API (5.2) (why aren't these libs API stable?!?)
This commit is contained in:
Ronald S. Bultje 2003-05-30 21:44:53 +00:00
parent 8e1ee4564b
commit c4eefdd7bc
5 changed files with 274 additions and 147 deletions

View file

@ -531,16 +531,48 @@ GST_CHECK_FEATURE(DIVX, [divx plugins], divx, [
AC_CHECK_HEADER(encore2.h, , AC_CHECK_HEADER(encore2.h, ,
[ AC_MSG_WARN([Divx4linux encore headers not found]) && [ AC_MSG_WARN([Divx4linux encore headers not found]) &&
HAVE_DIVX=no ] ) HAVE_DIVX=no ] )
AC_CHECK_HEADER(decore.h, , if [ test x$HAVE_DIVX = xyes ]; then
[ AC_MSG_WARN([Divx4linux decoder headers not found]) && AC_MSG_CHECKING([Checking for valid divx4linux encore version])
HAVE_DIVX=no ] ) 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" LIBS="-lm"
AC_CHECK_LIB(divxencore, encore, , if test x$HAVE_DIVX = xyes; then
[ AC_MSG_WARN([Divx4linux encore libs not found]) && AC_CHECK_LIB(divxencore, encore, ,
HAVE_DIVX=no ] ) [ AC_MSG_WARN([Divx4linux encore libs not found]) &&
AC_CHECK_LIB(divxdecore, decore, , HAVE_DIVX=no ] )
[ AC_MSG_WARN([Divx4linux decore libs not found]) && fi
HAVE_DIVX=no ] ) 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 if test x$HAVE_DIVX = xyes; then
DIVXENC_LIBS="-ldivxencore -lm" DIVXENC_LIBS="-ldivxencore -lm"
DIVXDEC_LIBS="-ldivxdecore -lm" DIVXDEC_LIBS="-ldivxdecore -lm"

View file

@ -89,6 +89,35 @@ static GstElementClass *parent_class = NULL;
/* static guint gst_divxdec_signals[LAST_SIGNAL] = { 0 }; */ /* static guint gst_divxdec_signals[LAST_SIGNAL] = { 0 }; */
static gchar *
gst_divxdec_error (int errorcode)
{
gchar *error;
switch (errorcode) {
case DEC_OK:
error = "No error";
break;
case DEC_MEMORY:
error = "Invalid memory";
break;
case DEC_BAD_FORMAT:
error = "Invalid format";
break;
case DEC_INVALID_ARGUMENT:
error = "Invalid argument";
break;
case DEC_NOT_IMPLEMENTED:
error = "Not implemented";
break;
default:
error = "Unknown error";
break;
}
return error;
}
GType GType
gst_divxdec_get_type(void) gst_divxdec_get_type(void)
{ {
@ -145,7 +174,7 @@ gst_divxdec_init (GstDivxDec *divxdec)
gst_element_add_pad(GST_ELEMENT(divxdec), divxdec->srcpad); gst_element_add_pad(GST_ELEMENT(divxdec), divxdec->srcpad);
/* bitrate, etc. */ /* bitrate, etc. */
divxdec->width = divxdec->height = divxdec->csp = -1; divxdec->width = divxdec->height = divxdec->csp = divxdec->bitcnt = -1;
/* set divx handle to NULL */ /* set divx handle to NULL */
divxdec->handle = NULL; divxdec->handle = NULL;
@ -155,20 +184,9 @@ gst_divxdec_init (GstDivxDec *divxdec)
static void static void
gst_divxdec_unset (GstDivxDec *divxdec) gst_divxdec_unset (GstDivxDec *divxdec)
{ {
/* free allocated memory */
g_free(divxdec->bufinfo.mp4_edged_ref_buffers);
g_free(divxdec->bufinfo.mp4_edged_for_buffers);
g_free(divxdec->bufinfo.mp4_edged_back_buffers);
g_free(divxdec->bufinfo.mp4_display_buffers);
g_free(divxdec->bufinfo.mp4_state);
g_free(divxdec->bufinfo.mp4_tables);
g_free(divxdec->bufinfo.mp4_stream);
g_free(divxdec->bufinfo.mp4_reference);
if (divxdec->handle) { if (divxdec->handle) {
/* unref this instance */ /* unref this instance */
decore((gulong) divxdec->handle, DEC_OPT_RELEASE, decore(divxdec->handle, DEC_OPT_RELEASE, NULL, NULL);
NULL, NULL);
divxdec->handle = NULL; divxdec->handle = NULL;
} }
} }
@ -177,76 +195,40 @@ gst_divxdec_unset (GstDivxDec *divxdec)
static gboolean static gboolean
gst_divxdec_setup (GstDivxDec *divxdec) gst_divxdec_setup (GstDivxDec *divxdec)
{ {
DEC_PARAM xdec; void *handle;
DEC_MEM_REQS xreq; DEC_INIT xinit;
DivXBitmapInfoHeader output;
int ret; int ret;
/* initialise parameters, see divx documentation */ /* initialize the handle */
memset(&xdec, 0, sizeof(DEC_PARAM)); memset(&xinit, 0, sizeof(DEC_INIT));
xdec.x_dim = divxdec->width; if ((ret = decore(&handle, DEC_OPT_INIT, &xinit, NULL)) != 0) {
xdec.y_dim = divxdec->height; gst_element_error(GST_ELEMENT(divxdec),
xdec.time_incr = 15; /* default - what is this? */ "Error initializing divx decoding library: %s (%d)",
xdec.output_format = divxdec->csp; gst_divxdec_error(ret), ret);
if ((ret = decore((gulong) divxdec, DEC_OPT_MEMORY_REQS,
&xdec, &xreq)) != 0) {
char *error;
switch (ret) {
case DEC_MEMORY:
error = "Memory allocation error";
break;
case DEC_BAD_FORMAT:
error = "Format";
break;
default:
error = "Internal failure";
break;
}
GST_DEBUG(GST_CAT_PLUGIN_INFO,
"Setting parameters %dx%d@%d failed: %s",
divxdec->width, divxdec->height, divxdec->csp, error);
return FALSE; return FALSE;
} }
/* allocate memory */ /* we've got a handle now */
xdec.buffers.mp4_edged_ref_buffers = g_malloc(xreq.mp4_edged_ref_buffers_size); divxdec->handle = handle;
memset(xdec.buffers.mp4_edged_ref_buffers, 0, xreq.mp4_edged_ref_buffers_size);
xdec.buffers.mp4_edged_for_buffers = g_malloc(xreq.mp4_edged_for_buffers_size); /* initialise parameters, see divx documentation */
memset(xdec.buffers.mp4_edged_for_buffers, 0, xreq.mp4_edged_for_buffers_size); memset(&output, 0, sizeof(DivXBitmapInfoHeader));
output.biSize = sizeof(DivXBitmapInfoHeader);
output.biWidth = divxdec->width;
output.biHeight = divxdec->height;
output.biBitCount = divxdec->bitcnt;
output.biCompression = divxdec->csp;
xdec.buffers.mp4_edged_back_buffers = g_malloc(xreq.mp4_edged_back_buffers_size); if ((ret = decore(divxdec->handle, DEC_OPT_SETOUT,
memset(xdec.buffers.mp4_edged_back_buffers, 0, xreq.mp4_edged_back_buffers_size); &output, NULL)) != 0) {
xdec.buffers.mp4_display_buffers = g_malloc(xreq.mp4_display_buffers_size);
memset(xdec.buffers.mp4_display_buffers, 0, xreq.mp4_display_buffers_size);
xdec.buffers.mp4_state = g_malloc(xreq.mp4_state_size);
memset(xdec.buffers.mp4_state, 0, xreq.mp4_state_size);
xdec.buffers.mp4_tables = g_malloc(xreq.mp4_tables_size);
memset(xdec.buffers.mp4_tables, 0, xreq.mp4_tables_size);
xdec.buffers.mp4_stream = g_malloc(xreq.mp4_stream_size);
memset(xdec.buffers.mp4_stream, 0, xreq.mp4_stream_size);
xdec.buffers.mp4_reference = g_malloc(xreq.mp4_reference_size);
memset(xdec.buffers.mp4_reference, 0, xreq.mp4_reference_size);
divxdec->bufinfo = xdec.buffers;
if ((ret = decore((gulong) divxdec, DEC_OPT_INIT,
&xdec, &xreq)) != 0) {
gst_element_error(GST_ELEMENT(divxdec), gst_element_error(GST_ELEMENT(divxdec),
"Expected error when confirming current settings: %d", "Error setting output format: %s (%d)",
ret); gst_divxdec_error(ret), ret);
gst_divxdec_unset(divxdec); gst_divxdec_unset(divxdec);
return FALSE; return FALSE;
} }
/* don't tell me this sucks - this is how divx4linux works... */
divxdec->handle = divxdec;
return TRUE; return TRUE;
} }
@ -294,13 +276,14 @@ gst_divxdec_chain (GstPad *pad,
xframe.bitstream = (void *) GST_BUFFER_DATA(buf); xframe.bitstream = (void *) GST_BUFFER_DATA(buf);
xframe.bmp = (void *) GST_BUFFER_DATA(outbuf); xframe.bmp = (void *) GST_BUFFER_DATA(outbuf);
xframe.length = GST_BUFFER_SIZE(buf); xframe.length = GST_BUFFER_SIZE(buf);
xframe.stride = divxdec->width * divxdec->bpp / 8; xframe.stride = 0;
xframe.render_flag = 1; xframe.render_flag = 1;
if ((ret = decore((gulong) divxdec->handle, DEC_OPT_FRAME, if ((ret = decore(divxdec->handle, DEC_OPT_FRAME,
&xframe, NULL))) { &xframe, NULL))) {
gst_element_error(GST_ELEMENT(divxdec), gst_element_error(GST_ELEMENT(divxdec),
"Error decoding divx frame: %d\n", ret); "Error decoding divx frame: %s (%d)",
gst_divxdec_error(ret), ret);
gst_buffer_unref(buf); gst_buffer_unref(buf);
return; return;
} }
@ -319,18 +302,36 @@ gst_divxdec_connect (GstPad *pad,
struct { struct {
guint32 fourcc; guint32 fourcc;
gint depth, bpp; gint depth, bpp;
gint csp; guint32 csp;
gint bitcnt;
} fmt_list[] = { } fmt_list[] = {
{ GST_MAKE_FOURCC('Y','U','Y','V'), 16, 16, DEC_YUY2 }, { GST_MAKE_FOURCC('Y','U','Y','2'), 16, 16,
{ GST_MAKE_FOURCC('U','Y','V','Y'), 16, 16, DEC_UYVY }, GST_MAKE_FOURCC('Y','U','Y','2'), 0 },
{ GST_MAKE_FOURCC('I','4','2','0'), 12, 12, DEC_420 }, { GST_MAKE_FOURCC('U','Y','V','Y'), 16, 16,
{ GST_MAKE_FOURCC('I','Y','U','V'), 12, 12, DEC_420 }, GST_MAKE_FOURCC('U','Y','V','Y'), 0 },
{ GST_MAKE_FOURCC('Y','V','1','2'), 12, 12, DEC_YV12 }, { GST_MAKE_FOURCC('I','4','2','0'), 12, 12,
{ GST_MAKE_FOURCC('R','G','B',' '), 32, 32, DEC_RGB32 }, GST_MAKE_FOURCC('I','4','2','0'), 0 },
{ GST_MAKE_FOURCC('R','G','B',' '), 24, 24, DEC_RGB24 }, { GST_MAKE_FOURCC('I','Y','U','V'), 12, 12,
{ GST_MAKE_FOURCC('R','G','B',' '), 16, 16, DEC_RGB555 }, GST_MAKE_FOURCC('I','4','2','0'), 0 },
{ GST_MAKE_FOURCC('R','G','B',' '), 15, 16, DEC_RGB565 }, { GST_MAKE_FOURCC('Y','V','1','2'), 12, 12,
{ 0, 0, 0 } GST_MAKE_FOURCC('Y','V','1','2'), 0 },
{ GST_MAKE_FOURCC('R','G','B',' '), 32, 32,
#if (G_BYTE_ORDER == G_BIG_ENDIAN)
GST_MAKE_FOURCC('A','B','G','R'), 32 },
#else
0, 32 },
#endif
{ GST_MAKE_FOURCC('R','G','B',' '), 24, 24,
#if (G_BYTE_ORDER == G_BIG_ENDIAN)
GST_MAKE_FOURCC('A','B','G','R'), 24 },
#else
0, 24 },
#endif
{ GST_MAKE_FOURCC('R','G','B',' '), 16, 16,
3, 16 },
{ GST_MAKE_FOURCC('R','G','B',' '), 15, 16,
0, 16 },
{ 0, 0, 0, 0, 0 }
}; };
gint i; gint i;
@ -392,8 +393,9 @@ gst_divxdec_connect (GstPad *pad,
} }
if (gst_pad_try_set_caps(divxdec->srcpad, caps) > 0) { if (gst_pad_try_set_caps(divxdec->srcpad, caps) > 0) {
divxdec->csp = fmt_list[i].csp; divxdec->csp = fmt_list[i].csp;
divxdec->bpp = fmt_list[i].bpp; divxdec->bpp = fmt_list[i].bpp;
divxdec->bitcnt = fmt_list[i].bitcnt;
if (gst_divxdec_setup(divxdec)) if (gst_divxdec_setup(divxdec))
return GST_PAD_LINK_OK; return GST_PAD_LINK_OK;
} }
@ -409,6 +411,15 @@ plugin_init (GModule *module,
GstPlugin *plugin) GstPlugin *plugin)
{ {
GstElementFactory *factory; GstElementFactory *factory;
int lib_version;
lib_version = decore(NULL, DEC_OPT_VERSION, 0, 0);
if (lib_version != DECORE_VERSION) {
g_warning("Version mismatch! This plugin was compiled for "
"DivX version %d, while your library has version %d!",
DECORE_VERSION, lib_version);
return FALSE;
}
/* create an elementfactory for the v4lmjpegsrcparse element */ /* create an elementfactory for the v4lmjpegsrcparse element */
factory = gst_element_factory_new("divxdec", GST_TYPE_DIVXDEC, factory = gst_element_factory_new("divxdec", GST_TYPE_DIVXDEC,

View file

@ -50,10 +50,10 @@ struct _GstDivxDec {
/* divx handle */ /* divx handle */
void *handle; void *handle;
DEC_BUFFERS bufinfo;
/* video (output) settings */ /* video (output) settings */
int csp, bpp; guint32 csp;
int bitcnt, bpp;
int width, height; int width, height;
}; };

View file

@ -76,7 +76,8 @@ enum {
ARG_0, ARG_0,
ARG_BITRATE, ARG_BITRATE,
ARG_MAXKEYINTERVAL, ARG_MAXKEYINTERVAL,
ARG_BUFSIZE ARG_BUFSIZE,
ARG_QUALITY
}; };
@ -102,6 +103,39 @@ static GstElementClass *parent_class = NULL;
static guint gst_divxenc_signals[LAST_SIGNAL] = { 0 }; static guint gst_divxenc_signals[LAST_SIGNAL] = { 0 };
static gchar *
gst_divxenc_error (int errorcode)
{
gchar *error;
switch (errorcode) {
case ENC_BUFFER:
error = "Invalid buffer";
break;
case ENC_FAIL:
error = "Operation failed";
break;
case ENC_OK:
error = "No error";
break;
case ENC_MEMORY:
error = "Bad memory location";
break;
case ENC_BAD_FORMAT:
error = "Invalid format";
break;
case ENC_INTERNAL:
error = "Internal error";
break;
default:
error = "Unknown error";
break;
}
return error;
}
GType GType
gst_divxenc_get_type(void) gst_divxenc_get_type(void)
{ {
@ -152,7 +186,12 @@ gst_divxenc_class_init (GstDivxEncClass *klass)
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_BUFSIZE, g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_BUFSIZE,
g_param_spec_ulong("buffer_size", "Buffer Size", g_param_spec_ulong("buffer_size", "Buffer Size",
"Size of the video buffers", "Size of the video buffers",
0,G_MAXULONG,0,G_PARAM_READWRITE)); 0,G_MAXULONG,0,G_PARAM_READABLE));
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_QUALITY,
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->set_property = gst_divxenc_set_property;
gobject_class->get_property = gst_divxenc_get_property; gobject_class->get_property = gst_divxenc_get_property;
@ -187,10 +226,11 @@ gst_divxenc_init (GstDivxEnc *divxenc)
gst_element_add_pad(GST_ELEMENT(divxenc), divxenc->srcpad); gst_element_add_pad(GST_ELEMENT(divxenc), divxenc->srcpad);
/* bitrate, etc. */ /* bitrate, etc. */
divxenc->width = divxenc->height = divxenc->csp = -1; divxenc->width = divxenc->height = divxenc->csp = divxenc->bitcnt = -1;
divxenc->bitrate = 512 * 1024; divxenc->bitrate = 512 * 1024;
divxenc->max_key_interval = -1; /* default - 2*fps */ divxenc->max_key_interval = -1; /* default - 2*fps */
divxenc->buffer_size = 512 * 1024; divxenc->buffer_size = 512 * 1024;
divxenc->quality = 3;
/* set divx handle to NULL */ /* set divx handle to NULL */
divxenc->handle = NULL; divxenc->handle = NULL;
@ -200,43 +240,63 @@ gst_divxenc_init (GstDivxEnc *divxenc)
static gboolean static gboolean
gst_divxenc_setup (GstDivxEnc *divxenc) gst_divxenc_setup (GstDivxEnc *divxenc)
{ {
ENC_PARAM xenc; void *handle;
SETTINGS output;
DivXBitmapInfoHeader input;
gdouble fps; gdouble fps;
int ret; int ret;
fps = gst_video_frame_rate(GST_PAD_PEER(divxenc->sinkpad)); fps = gst_video_frame_rate(GST_PAD_PEER(divxenc->sinkpad));
/* set it up */ /* set it up */
memset(&xenc, 0, sizeof(ENC_PARAM)); memset(&input, 0, sizeof(DivXBitmapInfoHeader));
xenc.x_dim = divxenc->width; input.biSize = sizeof(DivXBitmapInfoHeader);
xenc.y_dim = divxenc->height; input.biWidth = divxenc->width;
xenc.framerate = fps; input.biHeight = divxenc->height;
input.biBitCount = divxenc->bitcnt;
input.biCompression = divxenc->csp;
xenc.rc_period = 2000; memset(&output, 0, sizeof(SETTINGS));
xenc.rc_reaction_period = 10; output.vbr_mode = 0;
xenc.rc_reaction_ratio = 20; output.bitrate = divxenc->bitrate;
output.quantizer = 0;
output.use_bidirect = 0;
output.input_clock = 0;
output.input_frame_period = 1000000;
output.internal_timescale = fps * 1000000;
output.max_key_interval = (divxenc->max_key_interval == -1) ?
(2 * fps) :
divxenc->max_key_interval;
output.key_frame_threshold = 0;
output.vbv_bitrate = 0;
output.vbv_size = 0;
output.vbv_occupancy = 0;
output.complexity_modulation = 0;
output.deinterlace = 0;
output.quality = divxenc->quality;
output.data_partitioning = 0;
output.quarter_pel = 0;
output.use_gmc = 0;
output.psychovisual = 0;
output.pv_strength_frame = 0;
output.pv_strength_MB = 0;
output.interlace_mode = 0;
output.enable_crop = 0;
output.enable_resize = 0;
output.temporal_enable = 0;
output.spatial_passes = 0;
xenc.max_quantizer = 31; if ((ret = encore(&handle, ENC_OPT_INIT, &input, &output))) {
xenc.min_quantizer = 1;
xenc.quality = 3;
xenc.bitrate = divxenc->bitrate;
xenc.deinterlace = 0;
xenc.max_key_interval = (divxenc->max_key_interval == -1) ?
(2 * xenc.framerate) :
divxenc->max_key_interval;
xenc.handle = NULL;
if ((ret = encore(NULL, ENC_OPT_INIT, &xenc, NULL))) {
gst_element_error(GST_ELEMENT(divxenc), gst_element_error(GST_ELEMENT(divxenc),
"Error setting up divx encoder: %d\n", "Error setting up divx encoder: %s (%d)",
ret); gst_divxenc_error(ret), ret);
return FALSE; return FALSE;
} }
divxenc->handle = xenc.handle; divxenc->handle = handle;
/* set buffer size to theoretical limit (see docs on divx.com) */
divxenc->buffer_size = 6 * divxenc->width * divxenc->height;
return TRUE; return TRUE;
} }
@ -245,8 +305,10 @@ gst_divxenc_setup (GstDivxEnc *divxenc)
static void static void
gst_divxenc_unset (GstDivxEnc *divxenc) gst_divxenc_unset (GstDivxEnc *divxenc)
{ {
encore(divxenc->handle, ENC_OPT_RELEASE, NULL, NULL); if (divxenc->handle) {
divxenc->handle = NULL; encore(divxenc, ENC_OPT_RELEASE, NULL, NULL);
divxenc->handle = NULL;
}
} }
@ -289,19 +351,19 @@ gst_divxenc_chain (GstPad *pad,
xframe.image = GST_BUFFER_DATA(buf); xframe.image = GST_BUFFER_DATA(buf);
xframe.bitstream = (void *) GST_BUFFER_DATA(outbuf); xframe.bitstream = (void *) GST_BUFFER_DATA(outbuf);
xframe.length = GST_BUFFER_MAXSIZE(outbuf); xframe.length = GST_BUFFER_MAXSIZE(outbuf);
xframe.mvs = NULL; xframe.produce_empty_frame = 0;
xframe.colorspace = divxenc->csp;
if ((ret = encore(divxenc->handle, ENC_OPT_ENCODE, if ((ret = encore(divxenc->handle, ENC_OPT_ENCODE,
&xframe, &xres))) { &xframe, &xres))) {
gst_element_error(GST_ELEMENT(divxenc), gst_element_error(GST_ELEMENT(divxenc),
"Error encoding divx frame: %d\n", ret); "Error encoding divx frame: %s (%d)",
gst_divxenc_error(ret), ret);
gst_buffer_unref(buf); gst_buffer_unref(buf);
return; return;
} }
GST_BUFFER_SIZE(outbuf) = xframe.length; GST_BUFFER_SIZE(outbuf) = xframe.length;
if (xres.is_key_frame) if (xres.cType == 'I')
GST_BUFFER_FLAG_SET(outbuf, GST_BUFFER_KEY_UNIT); GST_BUFFER_FLAG_SET(outbuf, GST_BUFFER_KEY_UNIT);
/* go out, multiply! */ /* go out, multiply! */
@ -325,9 +387,7 @@ gst_divxenc_connect (GstPad *pad,
divxenc = GST_DIVXENC(gst_pad_get_parent (pad)); divxenc = GST_DIVXENC(gst_pad_get_parent (pad));
/* if there's something old around, remove it */ /* if there's something old around, remove it */
if (divxenc->handle) { gst_divxenc_unset(divxenc);
gst_divxenc_unset(divxenc);
}
/* we are not going to act on variable caps */ /* we are not going to act on variable caps */
if (!GST_CAPS_IS_FIXED(vscaps)) if (!GST_CAPS_IS_FIXED(vscaps))
@ -336,7 +396,8 @@ gst_divxenc_connect (GstPad *pad,
for (caps = vscaps; caps != NULL; caps = caps->next) { for (caps = vscaps; caps != NULL; caps = caps->next) {
int w,h,d; int w,h,d;
guint32 fourcc; guint32 fourcc;
gint divx_cs; guint32 divx_cs;
gint bitcnt = 0;
gst_caps_get_int(caps, "width", &w); gst_caps_get_int(caps, "width", &w);
gst_caps_get_int(caps, "height", &h); gst_caps_get_int(caps, "height", &h);
gst_caps_get_fourcc_int(caps, "format", &fourcc); gst_caps_get_fourcc_int(caps, "format", &fourcc);
@ -344,25 +405,31 @@ gst_divxenc_connect (GstPad *pad,
switch (fourcc) { switch (fourcc) {
case GST_MAKE_FOURCC('I','4','2','0'): case GST_MAKE_FOURCC('I','4','2','0'):
case GST_MAKE_FOURCC('I','Y','U','V'): case GST_MAKE_FOURCC('I','Y','U','V'):
divx_cs = ENC_CSP_I420; divx_cs = GST_MAKE_FOURCC('I','4','2','0');
break; break;
case GST_MAKE_FOURCC('Y','U','Y','2'): case GST_MAKE_FOURCC('Y','U','Y','2'):
divx_cs = ENC_CSP_YUY2; case GST_MAKE_FOURCC('Y','U','Y','V'):
divx_cs = GST_MAKE_FOURCC('Y','U','Y','2');
break; break;
case GST_MAKE_FOURCC('Y','V','1','2'): case GST_MAKE_FOURCC('Y','V','1','2'):
divx_cs = ENC_CSP_YV12; divx_cs = GST_MAKE_FOURCC('Y','V','1','2');
break;
case GST_MAKE_FOURCC('Y','V','Y','U'):
divx_cs = GST_MAKE_FOURCC('Y','V','Y','U');
break; break;
case GST_MAKE_FOURCC('U','Y','V','Y'): case GST_MAKE_FOURCC('U','Y','V','Y'):
divx_cs = ENC_CSP_UYVY; divx_cs = GST_MAKE_FOURCC('U','Y','V','Y');
break; break;
case GST_MAKE_FOURCC('R','G','B',' '): case GST_MAKE_FOURCC('R','G','B',' '):
gst_caps_get_int(caps, "depth", &d); gst_caps_get_int(caps, "depth", &d);
switch (d) { switch (d) {
case 24: case 24:
divx_cs = ENC_CSP_RGB24; divx_cs = 0;
bitcnt = 24;
break; break;
case 32: case 32:
divx_cs = ENC_CSP_RGB32; divx_cs = 0;
bitcnt = 32;
break; break;
default: default:
goto trynext; goto trynext;
@ -376,6 +443,7 @@ gst_divxenc_connect (GstPad *pad,
* linking, so we accept here, get the fps on * linking, so we accept here, get the fps on
* the first cycle and set it all up then */ * the first cycle and set it all up then */
divxenc->csp = divx_cs; divxenc->csp = divx_cs;
divxenc->bitcnt = bitcnt;
divxenc->width = w; divxenc->width = w;
divxenc->height = h; divxenc->height = h;
return gst_pad_try_set_caps(divxenc->srcpad, return gst_pad_try_set_caps(divxenc->srcpad,
@ -409,12 +477,12 @@ gst_divxenc_set_property (GObject *object,
case ARG_BITRATE: case ARG_BITRATE:
divxenc->bitrate = g_value_get_ulong(value); divxenc->bitrate = g_value_get_ulong(value);
break; break;
case ARG_BUFSIZE:
divxenc->buffer_size = g_value_get_ulong(value);
break;
case ARG_MAXKEYINTERVAL: case ARG_MAXKEYINTERVAL:
divxenc->max_key_interval = g_value_get_int(value); divxenc->max_key_interval = g_value_get_int(value);
break; break;
case ARG_QUALITY:
divxenc->quality = g_value_get_int(value);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
@ -444,6 +512,9 @@ gst_divxenc_get_property (GObject *object,
case ARG_MAXKEYINTERVAL: case ARG_MAXKEYINTERVAL:
g_value_set_int(value, divxenc->max_key_interval); g_value_set_int(value, divxenc->max_key_interval);
break; break;
case ARG_QUALITY:
g_value_set_int(value, divxenc->quality);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
@ -456,6 +527,15 @@ plugin_init (GModule *module,
GstPlugin *plugin) GstPlugin *plugin)
{ {
GstElementFactory *factory; GstElementFactory *factory;
int lib_version;
lib_version = encore(NULL, ENC_OPT_VERSION, 0, 0);
if (lib_version != ENCORE_VERSION) {
g_warning("Version mismatch! This plugin was compiled for "
"DivX version %d, while your library has version %d!",
ENCORE_VERSION, lib_version);
return FALSE;
}
if (!gst_library_load("gstvideo")) if (!gst_library_load("gstvideo"))
return FALSE; return FALSE;

View file

@ -56,10 +56,14 @@ struct _GstDivxEnc {
/* max key interval */ /* max key interval */
gint max_key_interval; gint max_key_interval;
/* amount of motion estimation to do */
gint quality;
/* divx handle */ /* divx handle */
void *handle; void *handle;
int csp; guint32 csp;
int width, height; gint bitcnt;
gint width, height;
}; };
struct _GstDivxEncClass { struct _GstDivxEncClass {