mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-24 02:31:03 +00:00
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:
parent
8e1ee4564b
commit
c4eefdd7bc
5 changed files with 274 additions and 147 deletions
50
configure.ac
50
configure.ac
|
@ -531,16 +531,48 @@ GST_CHECK_FEATURE(DIVX, [divx plugins], divx, [
|
|||
AC_CHECK_HEADER(encore2.h, ,
|
||||
[ AC_MSG_WARN([Divx4linux encore headers not found]) &&
|
||||
HAVE_DIVX=no ] )
|
||||
AC_CHECK_HEADER(decore.h, ,
|
||||
[ AC_MSG_WARN([Divx4linux decoder 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"
|
||||
AC_CHECK_LIB(divxencore, encore, ,
|
||||
[ AC_MSG_WARN([Divx4linux encore libs not found]) &&
|
||||
HAVE_DIVX=no ] )
|
||||
AC_CHECK_LIB(divxdecore, decore, ,
|
||||
[ AC_MSG_WARN([Divx4linux decore libs not found]) &&
|
||||
HAVE_DIVX=no ] )
|
||||
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"
|
||||
|
|
|
@ -89,6 +89,35 @@ static GstElementClass *parent_class = NULL;
|
|||
/* 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
|
||||
gst_divxdec_get_type(void)
|
||||
{
|
||||
|
@ -145,7 +174,7 @@ gst_divxdec_init (GstDivxDec *divxdec)
|
|||
gst_element_add_pad(GST_ELEMENT(divxdec), divxdec->srcpad);
|
||||
|
||||
/* bitrate, etc. */
|
||||
divxdec->width = divxdec->height = divxdec->csp = -1;
|
||||
divxdec->width = divxdec->height = divxdec->csp = divxdec->bitcnt = -1;
|
||||
|
||||
/* set divx handle to NULL */
|
||||
divxdec->handle = NULL;
|
||||
|
@ -155,20 +184,9 @@ gst_divxdec_init (GstDivxDec *divxdec)
|
|||
static void
|
||||
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) {
|
||||
/* unref this instance */
|
||||
decore((gulong) divxdec->handle, DEC_OPT_RELEASE,
|
||||
NULL, NULL);
|
||||
decore(divxdec->handle, DEC_OPT_RELEASE, NULL, NULL);
|
||||
divxdec->handle = NULL;
|
||||
}
|
||||
}
|
||||
|
@ -177,76 +195,40 @@ gst_divxdec_unset (GstDivxDec *divxdec)
|
|||
static gboolean
|
||||
gst_divxdec_setup (GstDivxDec *divxdec)
|
||||
{
|
||||
DEC_PARAM xdec;
|
||||
DEC_MEM_REQS xreq;
|
||||
void *handle;
|
||||
DEC_INIT xinit;
|
||||
DivXBitmapInfoHeader output;
|
||||
int ret;
|
||||
|
||||
/* initialise parameters, see divx documentation */
|
||||
memset(&xdec, 0, sizeof(DEC_PARAM));
|
||||
xdec.x_dim = divxdec->width;
|
||||
xdec.y_dim = divxdec->height;
|
||||
xdec.time_incr = 15; /* default - what is this? */
|
||||
xdec.output_format = divxdec->csp;
|
||||
|
||||
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);
|
||||
/* initialize the handle */
|
||||
memset(&xinit, 0, sizeof(DEC_INIT));
|
||||
if ((ret = decore(&handle, DEC_OPT_INIT, &xinit, NULL)) != 0) {
|
||||
gst_element_error(GST_ELEMENT(divxdec),
|
||||
"Error initializing divx decoding library: %s (%d)",
|
||||
gst_divxdec_error(ret), ret);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* allocate memory */
|
||||
xdec.buffers.mp4_edged_ref_buffers = g_malloc(xreq.mp4_edged_ref_buffers_size);
|
||||
memset(xdec.buffers.mp4_edged_ref_buffers, 0, xreq.mp4_edged_ref_buffers_size);
|
||||
/* we've got a handle now */
|
||||
divxdec->handle = handle;
|
||||
|
||||
xdec.buffers.mp4_edged_for_buffers = g_malloc(xreq.mp4_edged_for_buffers_size);
|
||||
memset(xdec.buffers.mp4_edged_for_buffers, 0, xreq.mp4_edged_for_buffers_size);
|
||||
/* initialise parameters, see divx documentation */
|
||||
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);
|
||||
memset(xdec.buffers.mp4_edged_back_buffers, 0, xreq.mp4_edged_back_buffers_size);
|
||||
|
||||
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) {
|
||||
if ((ret = decore(divxdec->handle, DEC_OPT_SETOUT,
|
||||
&output, NULL)) != 0) {
|
||||
gst_element_error(GST_ELEMENT(divxdec),
|
||||
"Expected error when confirming current settings: %d",
|
||||
ret);
|
||||
"Error setting output format: %s (%d)",
|
||||
gst_divxdec_error(ret), ret);
|
||||
gst_divxdec_unset(divxdec);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* don't tell me this sucks - this is how divx4linux works... */
|
||||
divxdec->handle = divxdec;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -294,13 +276,14 @@ gst_divxdec_chain (GstPad *pad,
|
|||
xframe.bitstream = (void *) GST_BUFFER_DATA(buf);
|
||||
xframe.bmp = (void *) GST_BUFFER_DATA(outbuf);
|
||||
xframe.length = GST_BUFFER_SIZE(buf);
|
||||
xframe.stride = divxdec->width * divxdec->bpp / 8;
|
||||
xframe.stride = 0;
|
||||
xframe.render_flag = 1;
|
||||
|
||||
if ((ret = decore((gulong) divxdec->handle, DEC_OPT_FRAME,
|
||||
if ((ret = decore(divxdec->handle, DEC_OPT_FRAME,
|
||||
&xframe, NULL))) {
|
||||
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);
|
||||
return;
|
||||
}
|
||||
|
@ -319,18 +302,36 @@ gst_divxdec_connect (GstPad *pad,
|
|||
struct {
|
||||
guint32 fourcc;
|
||||
gint depth, bpp;
|
||||
gint csp;
|
||||
guint32 csp;
|
||||
gint bitcnt;
|
||||
} fmt_list[] = {
|
||||
{ GST_MAKE_FOURCC('Y','U','Y','V'), 16, 16, DEC_YUY2 },
|
||||
{ GST_MAKE_FOURCC('U','Y','V','Y'), 16, 16, DEC_UYVY },
|
||||
{ GST_MAKE_FOURCC('I','4','2','0'), 12, 12, DEC_420 },
|
||||
{ GST_MAKE_FOURCC('I','Y','U','V'), 12, 12, DEC_420 },
|
||||
{ GST_MAKE_FOURCC('Y','V','1','2'), 12, 12, DEC_YV12 },
|
||||
{ GST_MAKE_FOURCC('R','G','B',' '), 32, 32, DEC_RGB32 },
|
||||
{ GST_MAKE_FOURCC('R','G','B',' '), 24, 24, DEC_RGB24 },
|
||||
{ GST_MAKE_FOURCC('R','G','B',' '), 16, 16, DEC_RGB555 },
|
||||
{ GST_MAKE_FOURCC('R','G','B',' '), 15, 16, DEC_RGB565 },
|
||||
{ 0, 0, 0 }
|
||||
{ GST_MAKE_FOURCC('Y','U','Y','2'), 16, 16,
|
||||
GST_MAKE_FOURCC('Y','U','Y','2'), 0 },
|
||||
{ GST_MAKE_FOURCC('U','Y','V','Y'), 16, 16,
|
||||
GST_MAKE_FOURCC('U','Y','V','Y'), 0 },
|
||||
{ GST_MAKE_FOURCC('I','4','2','0'), 12, 12,
|
||||
GST_MAKE_FOURCC('I','4','2','0'), 0 },
|
||||
{ GST_MAKE_FOURCC('I','Y','U','V'), 12, 12,
|
||||
GST_MAKE_FOURCC('I','4','2','0'), 0 },
|
||||
{ GST_MAKE_FOURCC('Y','V','1','2'), 12, 12,
|
||||
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;
|
||||
|
||||
|
@ -392,8 +393,9 @@ gst_divxdec_connect (GstPad *pad,
|
|||
}
|
||||
|
||||
if (gst_pad_try_set_caps(divxdec->srcpad, caps) > 0) {
|
||||
divxdec->csp = fmt_list[i].csp;
|
||||
divxdec->bpp = fmt_list[i].bpp;
|
||||
divxdec->csp = fmt_list[i].csp;
|
||||
divxdec->bpp = fmt_list[i].bpp;
|
||||
divxdec->bitcnt = fmt_list[i].bitcnt;
|
||||
if (gst_divxdec_setup(divxdec))
|
||||
return GST_PAD_LINK_OK;
|
||||
}
|
||||
|
@ -409,6 +411,15 @@ plugin_init (GModule *module,
|
|||
GstPlugin *plugin)
|
||||
{
|
||||
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 */
|
||||
factory = gst_element_factory_new("divxdec", GST_TYPE_DIVXDEC,
|
||||
|
|
|
@ -50,10 +50,10 @@ struct _GstDivxDec {
|
|||
|
||||
/* divx handle */
|
||||
void *handle;
|
||||
DEC_BUFFERS bufinfo;
|
||||
|
||||
/* video (output) settings */
|
||||
int csp, bpp;
|
||||
guint32 csp;
|
||||
int bitcnt, bpp;
|
||||
int width, height;
|
||||
};
|
||||
|
||||
|
|
|
@ -76,7 +76,8 @@ enum {
|
|||
ARG_0,
|
||||
ARG_BITRATE,
|
||||
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 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
|
||||
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_param_spec_ulong("buffer_size", "Buffer Size",
|
||||
"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->get_property = gst_divxenc_get_property;
|
||||
|
@ -187,10 +226,11 @@ gst_divxenc_init (GstDivxEnc *divxenc)
|
|||
gst_element_add_pad(GST_ELEMENT(divxenc), divxenc->srcpad);
|
||||
|
||||
/* bitrate, etc. */
|
||||
divxenc->width = divxenc->height = divxenc->csp = -1;
|
||||
divxenc->width = divxenc->height = divxenc->csp = divxenc->bitcnt = -1;
|
||||
divxenc->bitrate = 512 * 1024;
|
||||
divxenc->max_key_interval = -1; /* default - 2*fps */
|
||||
divxenc->buffer_size = 512 * 1024;
|
||||
divxenc->quality = 3;
|
||||
|
||||
/* set divx handle to NULL */
|
||||
divxenc->handle = NULL;
|
||||
|
@ -200,43 +240,63 @@ gst_divxenc_init (GstDivxEnc *divxenc)
|
|||
static gboolean
|
||||
gst_divxenc_setup (GstDivxEnc *divxenc)
|
||||
{
|
||||
ENC_PARAM xenc;
|
||||
void *handle;
|
||||
SETTINGS output;
|
||||
DivXBitmapInfoHeader input;
|
||||
gdouble fps;
|
||||
int ret;
|
||||
|
||||
fps = gst_video_frame_rate(GST_PAD_PEER(divxenc->sinkpad));
|
||||
|
||||
/* set it up */
|
||||
memset(&xenc, 0, sizeof(ENC_PARAM));
|
||||
xenc.x_dim = divxenc->width;
|
||||
xenc.y_dim = divxenc->height;
|
||||
xenc.framerate = fps;
|
||||
memset(&input, 0, sizeof(DivXBitmapInfoHeader));
|
||||
input.biSize = sizeof(DivXBitmapInfoHeader);
|
||||
input.biWidth = divxenc->width;
|
||||
input.biHeight = divxenc->height;
|
||||
input.biBitCount = divxenc->bitcnt;
|
||||
input.biCompression = divxenc->csp;
|
||||
|
||||
xenc.rc_period = 2000;
|
||||
xenc.rc_reaction_period = 10;
|
||||
xenc.rc_reaction_ratio = 20;
|
||||
memset(&output, 0, sizeof(SETTINGS));
|
||||
output.vbr_mode = 0;
|
||||
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;
|
||||
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))) {
|
||||
if ((ret = encore(&handle, ENC_OPT_INIT, &input, &output))) {
|
||||
gst_element_error(GST_ELEMENT(divxenc),
|
||||
"Error setting up divx encoder: %d\n",
|
||||
ret);
|
||||
"Error setting up divx encoder: %s (%d)",
|
||||
gst_divxenc_error(ret), ret);
|
||||
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;
|
||||
}
|
||||
|
@ -245,8 +305,10 @@ gst_divxenc_setup (GstDivxEnc *divxenc)
|
|||
static void
|
||||
gst_divxenc_unset (GstDivxEnc *divxenc)
|
||||
{
|
||||
encore(divxenc->handle, ENC_OPT_RELEASE, NULL, NULL);
|
||||
divxenc->handle = NULL;
|
||||
if (divxenc->handle) {
|
||||
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.bitstream = (void *) GST_BUFFER_DATA(outbuf);
|
||||
xframe.length = GST_BUFFER_MAXSIZE(outbuf);
|
||||
xframe.mvs = NULL;
|
||||
xframe.colorspace = divxenc->csp;
|
||||
xframe.produce_empty_frame = 0;
|
||||
|
||||
if ((ret = encore(divxenc->handle, ENC_OPT_ENCODE,
|
||||
&xframe, &xres))) {
|
||||
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);
|
||||
return;
|
||||
}
|
||||
|
||||
GST_BUFFER_SIZE(outbuf) = xframe.length;
|
||||
if (xres.is_key_frame)
|
||||
if (xres.cType == 'I')
|
||||
GST_BUFFER_FLAG_SET(outbuf, GST_BUFFER_KEY_UNIT);
|
||||
|
||||
/* go out, multiply! */
|
||||
|
@ -325,9 +387,7 @@ gst_divxenc_connect (GstPad *pad,
|
|||
divxenc = GST_DIVXENC(gst_pad_get_parent (pad));
|
||||
|
||||
/* 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 */
|
||||
if (!GST_CAPS_IS_FIXED(vscaps))
|
||||
|
@ -336,7 +396,8 @@ gst_divxenc_connect (GstPad *pad,
|
|||
for (caps = vscaps; caps != NULL; caps = caps->next) {
|
||||
int w,h,d;
|
||||
guint32 fourcc;
|
||||
gint divx_cs;
|
||||
guint32 divx_cs;
|
||||
gint bitcnt = 0;
|
||||
gst_caps_get_int(caps, "width", &w);
|
||||
gst_caps_get_int(caps, "height", &h);
|
||||
gst_caps_get_fourcc_int(caps, "format", &fourcc);
|
||||
|
@ -344,25 +405,31 @@ gst_divxenc_connect (GstPad *pad,
|
|||
switch (fourcc) {
|
||||
case GST_MAKE_FOURCC('I','4','2','0'):
|
||||
case GST_MAKE_FOURCC('I','Y','U','V'):
|
||||
divx_cs = ENC_CSP_I420;
|
||||
divx_cs = GST_MAKE_FOURCC('I','4','2','0');
|
||||
break;
|
||||
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;
|
||||
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;
|
||||
case GST_MAKE_FOURCC('U','Y','V','Y'):
|
||||
divx_cs = ENC_CSP_UYVY;
|
||||
divx_cs = GST_MAKE_FOURCC('U','Y','V','Y');
|
||||
break;
|
||||
case GST_MAKE_FOURCC('R','G','B',' '):
|
||||
gst_caps_get_int(caps, "depth", &d);
|
||||
switch (d) {
|
||||
case 24:
|
||||
divx_cs = ENC_CSP_RGB24;
|
||||
divx_cs = 0;
|
||||
bitcnt = 24;
|
||||
break;
|
||||
case 32:
|
||||
divx_cs = ENC_CSP_RGB32;
|
||||
divx_cs = 0;
|
||||
bitcnt = 32;
|
||||
break;
|
||||
default:
|
||||
goto trynext;
|
||||
|
@ -376,6 +443,7 @@ gst_divxenc_connect (GstPad *pad,
|
|||
* linking, so we accept here, get the fps on
|
||||
* the first cycle and set it all up then */
|
||||
divxenc->csp = divx_cs;
|
||||
divxenc->bitcnt = bitcnt;
|
||||
divxenc->width = w;
|
||||
divxenc->height = h;
|
||||
return gst_pad_try_set_caps(divxenc->srcpad,
|
||||
|
@ -409,12 +477,12 @@ gst_divxenc_set_property (GObject *object,
|
|||
case ARG_BITRATE:
|
||||
divxenc->bitrate = g_value_get_ulong(value);
|
||||
break;
|
||||
case ARG_BUFSIZE:
|
||||
divxenc->buffer_size = g_value_get_ulong(value);
|
||||
break;
|
||||
case ARG_MAXKEYINTERVAL:
|
||||
divxenc->max_key_interval = g_value_get_int(value);
|
||||
break;
|
||||
case ARG_QUALITY:
|
||||
divxenc->quality = g_value_get_int(value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
@ -444,6 +512,9 @@ gst_divxenc_get_property (GObject *object,
|
|||
case ARG_MAXKEYINTERVAL:
|
||||
g_value_set_int(value, divxenc->max_key_interval);
|
||||
break;
|
||||
case ARG_QUALITY:
|
||||
g_value_set_int(value, divxenc->quality);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
@ -456,6 +527,15 @@ plugin_init (GModule *module,
|
|||
GstPlugin *plugin)
|
||||
{
|
||||
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"))
|
||||
return FALSE;
|
||||
|
|
|
@ -56,10 +56,14 @@ struct _GstDivxEnc {
|
|||
/* max key interval */
|
||||
gint max_key_interval;
|
||||
|
||||
/* amount of motion estimation to do */
|
||||
gint quality;
|
||||
|
||||
/* divx handle */
|
||||
void *handle;
|
||||
int csp;
|
||||
int width, height;
|
||||
guint32 csp;
|
||||
gint bitcnt;
|
||||
gint width, height;
|
||||
};
|
||||
|
||||
struct _GstDivxEncClass {
|
||||
|
|
Loading…
Reference in a new issue