summaryrefslogtreecommitdiffstats
path: root/gst/real/gstrealvideodec.c
diff options
context:
space:
mode:
authorWim Taymans <wim.taymans@gmail.com>2008-06-13 18:03:16 +0000
committerWim Taymans <wim.taymans@gmail.com>2008-06-13 18:03:16 +0000
commit1a39f60d9f9fa8ad7b664787f162f9fa7e616957 (patch)
tree8dcc50b600e09463ecfa5375cc00541a3fb7bc38 /gst/real/gstrealvideodec.c
parent7ce74ccd5db8cc084ebe07da9e33366712064ee0 (diff)
downloadgst-plugins-bad-1a39f60d9f9fa8ad7b664787f162f9fa7e616957.tar.gz
gst-plugins-bad-1a39f60d9f9fa8ad7b664787f162f9fa7e616957.tar.bz2
gst-plugins-bad-1a39f60d9f9fa8ad7b664787f162f9fa7e616957.zip
gst/real/gstrealaudiodec.c: Add raversions we can support on the caps.
Original commit message from CVS: * gst/real/gstrealaudiodec.c: (gst_real_audio_dec_chain), (close_library), (open_library), (gst_real_audio_dec_probe_modules), (gst_real_audio_dec_getcaps), (gst_real_audio_dec_setcaps), (gst_real_audio_dec_init), (gst_real_audio_dec_change_state), (gst_real_audio_dec_finalize): Add raversions we can support on the caps. Refactor the loading of the real codecs like realvideo so that we can implement probing. Probe all supported formats by trying to load the .so files, only report the versions on the caps that we can actually load. * gst/real/gstrealvideodec.c: (gst_real_video_dec_chain), (gst_real_video_dec_getcaps), (gst_real_video_dec_setcaps), (open_library), (close_library), (gst_real_video_dec_probe_modules), (gst_real_video_dec_change_state), (gst_real_video_dec_init), (gst_real_video_dec_finalize), (gst_real_video_dec_class_init): * gst/real/gstrealvideodec.h: Change the loading of the library like the audio decoder. Probe the supported formats by trying to load the .so files and only report the versions on the caps that we can actually load.
Diffstat (limited to 'gst/real/gstrealvideodec.c')
-rw-r--r--gst/real/gstrealvideodec.c179
1 files changed, 135 insertions, 44 deletions
diff --git a/gst/real/gstrealvideodec.c b/gst/real/gstrealvideodec.c
index 3c471f5d..27558426 100644
--- a/gst/real/gstrealvideodec.c
+++ b/gst/real/gstrealvideodec.c
@@ -65,8 +65,8 @@ GST_BOILERPLATE (GstRealVideoDec, gst_real_video_dec, GstElement,
GST_TYPE_ELEMENT);
static gboolean open_library (GstRealVideoDec * dec,
- GstRealVideoDecHooks * hooks, GstRealVideoDecVersion version);
-static void close_library (GstRealVideoDecHooks hooks);
+ GstRealVideoDecVersion version, GstRVDecLibrary * lib);
+static void close_library (GstRealVideoDec * dec, GstRVDecLibrary * lib);
typedef struct
{
@@ -103,7 +103,7 @@ gst_real_video_dec_chain (GstPad * pad, GstBuffer * in)
dec = GST_REAL_VIDEO_DEC (GST_PAD_PARENT (pad));
- if (G_UNLIKELY (dec->hooks.transform == NULL || dec->hooks.module == NULL))
+ if (G_UNLIKELY (dec->lib.Transform == NULL || dec->lib.module == NULL))
goto not_negotiated;
data = GST_BUFFER_DATA (in);
@@ -162,9 +162,9 @@ gst_real_video_dec_chain (GstPad * pad, GstBuffer * in)
/* jump over the frag table to the fragments */
data += frag_size;
- result = dec->hooks.transform (
+ result = dec->lib.Transform (
(gchar *) data,
- (gchar *) GST_BUFFER_DATA (out), &tin, &tout, dec->hooks.context);
+ (gchar *) GST_BUFFER_DATA (out), &tin, &tout, dec->lib.context);
if (result)
goto could_not_transform;
@@ -243,10 +243,51 @@ could_not_push:
}
}
-static gboolean
-gst_real_video_dec_activate_push (GstPad * pad, gboolean active)
+static GstCaps *
+gst_real_video_dec_getcaps (GstPad * pad)
{
- return TRUE;
+ GstRealVideoDec *dec = GST_REAL_VIDEO_DEC (GST_PAD_PARENT (pad));
+ GstCaps *res;
+
+ if (dec->checked_modules) {
+ GValue versions = { 0 };
+ GValue version = { 0 };
+
+ GST_LOG_OBJECT (dec, "constructing caps");
+ res = gst_caps_new_empty ();
+
+ g_value_init (&versions, GST_TYPE_LIST);
+ g_value_init (&version, G_TYPE_INT);
+
+ if (dec->valid_rv20) {
+ g_value_set_int (&version, GST_REAL_VIDEO_DEC_VERSION_2);
+ gst_value_list_append_value (&versions, &version);
+ }
+ if (dec->valid_rv30) {
+ g_value_set_int (&version, GST_REAL_VIDEO_DEC_VERSION_3);
+ gst_value_list_append_value (&versions, &version);
+ }
+ if (dec->valid_rv40) {
+ g_value_set_int (&version, GST_REAL_VIDEO_DEC_VERSION_4);
+ gst_value_list_append_value (&versions, &version);
+ }
+
+ if (gst_value_list_get_size (&versions) > 0) {
+ res = gst_caps_new_simple ("video/x-pn-realvideo", NULL);
+ gst_structure_set_value (gst_caps_get_structure (res, 0),
+ "rmversion", &versions);
+ } else {
+ res = gst_caps_new_empty ();
+ }
+ g_value_unset (&versions);
+ g_value_unset (&version);
+ } else {
+ GST_LOG_OBJECT (dec, "returning padtemplate caps");
+ res = gst_caps_copy (gst_pad_get_pad_template_caps (pad));
+ }
+ GST_LOG_OBJECT (dec, "returning caps %" GST_PTR_FORMAT, res);
+
+ return res;
}
static gboolean
@@ -259,7 +300,6 @@ gst_real_video_dec_setcaps (GstPad * pad, GstCaps * caps)
gchar data[36];
gboolean bres;
const GValue *v;
- GstRealVideoDecHooks hooks = { 0, 0, 0, 0, 0, 0 };
if (!gst_structure_get_int (s, "rmversion", &version) ||
!gst_structure_get_int (s, "width", (gint *) & width) ||
@@ -272,8 +312,10 @@ gst_real_video_dec_setcaps (GstPad * pad, GstCaps * caps)
GST_LOG_OBJECT (dec, "Setting version to %d", version);
- if (!open_library (dec, &hooks, version))
- return FALSE;
+ close_library (dec, &dec->lib);
+
+ if (!open_library (dec, version, &dec->lib))
+ goto open_failed;
/* Initialize REAL driver. */
GST_WRITE_UINT16_LE (data + 0, 11);
@@ -285,8 +327,7 @@ gst_real_video_dec_setcaps (GstPad * pad, GstCaps * caps)
GST_WRITE_UINT32_LE (data + 16, 1);
GST_WRITE_UINT32_LE (data + 20, format);
- res = hooks.init (&data, &hooks.context);
- if (res)
+ if ((res = dec->lib.Init (&data, &dec->lib.context)))
goto could_not_initialize;
if ((v = gst_structure_get_value (s, "codec_data"))) {
@@ -328,7 +369,7 @@ gst_real_video_dec_setcaps (GstPad * pad, GstCaps * caps)
for (i = 0; i < bufsize; i++)
msgdata[i + 2] = 4 * (guint32) bufdata[i];
- res = hooks.custom_message (&msg, hooks.context);
+ res = dec->lib.Message (&msg, dec->lib.context);
g_free (msgdata);
if (res)
@@ -344,8 +385,6 @@ gst_real_video_dec_setcaps (GstPad * pad, GstCaps * caps)
if (!bres)
goto could_not_set_caps;
- close_library (dec->hooks);
- dec->hooks = hooks;
dec->version = version;
dec->width = width;
dec->height = height;
@@ -361,34 +400,35 @@ missing_keys:
GST_ERROR_OBJECT (dec, "Could not find all necessary keys in structure.");
return FALSE;
}
-
+open_failed:
+ {
+ GST_ERROR_OBJECT (dec, "failed to open library");
+ return FALSE;
+ }
could_not_initialize:
{
- close_library (hooks);
GST_ERROR_OBJECT (dec, "Initialization of REAL driver failed (%i).", res);
+ close_library (dec, &dec->lib);
return FALSE;
}
-
could_not_allocate:
{
- close_library (hooks);
GST_ERROR_OBJECT (dec, "Could not allocate memory.");
+ close_library (dec, &dec->lib);
return FALSE;
}
-
could_not_send_message:
{
- close_library (hooks);
GST_ERROR_OBJECT (dec, "Failed to send custom message needed for "
"initialization (%i).", res);
+ close_library (dec, &dec->lib);
return FALSE;
}
-
could_not_set_caps:
{
- close_library (hooks);
GST_ERROR_OBJECT (dec, "Could not convince peer to accept dimensions "
"%i x %i.", dec->width, dec->height);
+ close_library (dec, &dec->lib);
return FALSE;
}
}
@@ -396,8 +436,8 @@ could_not_set_caps:
/* Attempts to open the correct library for the configured version */
static gboolean
-open_library (GstRealVideoDec * dec, GstRealVideoDecHooks * hooks,
- GstRealVideoDecVersion version)
+open_library (GstRealVideoDec * dec, GstRealVideoDecVersion version,
+ GstRVDecLibrary * lib)
{
gpointer rv_custom_msg, rv_free, rv_init, rv_transform;
GModule *module = NULL;
@@ -464,11 +504,11 @@ codec_search_done:
goto could_not_load;
}
- hooks->init = (GstRealVideoDecInitFunc) rv_init;
- hooks->free = (GstRealVideoDecFreeFunc) rv_free;
- hooks->transform = (GstRealVideoDecTransformFunc) rv_transform;
- hooks->custom_message = (GstRealVideoDecMessageFunc) rv_custom_msg;
- hooks->module = module;
+ lib->Init = rv_init;
+ lib->Free = rv_free;
+ lib->Transform = rv_transform;
+ lib->Message = rv_custom_msg;
+ lib->module = module;
dec->error_count = 0;
@@ -479,44 +519,93 @@ unknown_version:
GST_ERROR_OBJECT (dec, "Cannot handle version %i.", version);
return FALSE;
}
-
could_not_open:
{
GST_ERROR_OBJECT (dec, "Could not open library '%s' in '%s': %s", names,
path, g_module_error ());
return FALSE;
}
-
could_not_load:
{
- close_library (*hooks);
+ close_library (dec, lib);
GST_ERROR_OBJECT (dec, "Could not load all symbols: %s", g_module_error ());
return FALSE;
}
}
static void
-close_library (GstRealVideoDecHooks hooks)
+close_library (GstRealVideoDec * dec, GstRVDecLibrary * lib)
+{
+ if (lib->context) {
+ GST_LOG_OBJECT (dec, "closing library");
+ if (lib->Free)
+ lib->Free (lib->context);
+ }
+ if (lib->module) {
+ GST_LOG_OBJECT (dec, "closing library module");
+ g_module_close (lib->module);
+ lib->module = NULL;
+ }
+ memset (lib, 0, sizeof (*lib));
+}
+
+static void
+gst_real_video_dec_probe_modules (GstRealVideoDec * dec)
+{
+ GstRVDecLibrary dummy = { NULL };
+
+ if ((dec->valid_rv20 =
+ open_library (dec, GST_REAL_VIDEO_DEC_VERSION_2, &dummy)))
+ close_library (dec, &dummy);
+ if ((dec->valid_rv30 =
+ open_library (dec, GST_REAL_VIDEO_DEC_VERSION_3, &dummy)))
+ close_library (dec, &dummy);
+ if ((dec->valid_rv40 =
+ open_library (dec, GST_REAL_VIDEO_DEC_VERSION_4, &dummy)))
+ close_library (dec, &dummy);
+}
+
+static GstStateChangeReturn
+gst_real_video_dec_change_state (GstElement * element,
+ GstStateChange transition)
{
- if (hooks.context && hooks.free)
- hooks.free (hooks.context);
+ GstStateChangeReturn ret;
+ GstRealVideoDec *dec = GST_REAL_VIDEO_DEC (element);
- if (hooks.module) {
- g_module_close (hooks.module);
- hooks.module = NULL;
+ switch (transition) {
+ case GST_STATE_CHANGE_NULL_TO_READY:
+ gst_real_video_dec_probe_modules (dec);
+ dec->checked_modules = TRUE;
+ break;
+ default:
+ break;
+ }
+
+ ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
+
+ switch (transition) {
+ case GST_STATE_CHANGE_PAUSED_TO_READY:
+ close_library (dec, &dec->lib);
+ break;
+ case GST_STATE_CHANGE_READY_TO_NULL:
+ dec->checked_modules = FALSE;
+ break;
+ default:
+ break;
}
+ return ret;
}
static void
gst_real_video_dec_init (GstRealVideoDec * dec, GstRealVideoDecClass * klass)
{
dec->snk = gst_pad_new_from_static_template (&snk_t, "sink");
+ gst_pad_set_getcaps_function (dec->snk,
+ GST_DEBUG_FUNCPTR (gst_real_video_dec_getcaps));
gst_pad_set_setcaps_function (dec->snk,
GST_DEBUG_FUNCPTR (gst_real_video_dec_setcaps));
gst_pad_set_chain_function (dec->snk,
GST_DEBUG_FUNCPTR (gst_real_video_dec_chain));
- gst_pad_set_activatepush_function (dec->snk,
- GST_DEBUG_FUNCPTR (gst_real_video_dec_activate_push));
gst_element_add_pad (GST_ELEMENT (dec), dec->snk);
dec->src = gst_pad_new_from_static_template (&src_t, "src");
@@ -542,8 +631,7 @@ gst_real_video_dec_finalize (GObject * object)
{
GstRealVideoDec *dec = GST_REAL_VIDEO_DEC (object);
- close_library (dec->hooks);
- memset (&dec->hooks, 0, sizeof (dec->hooks));
+ close_library (dec, &dec->lib);
if (dec->real_codecs_path) {
g_free (dec->real_codecs_path);
@@ -641,11 +729,14 @@ static void
gst_real_video_dec_class_init (GstRealVideoDecClass * klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
object_class->set_property = gst_real_video_dec_set_property;
object_class->get_property = gst_real_video_dec_get_property;
object_class->finalize = gst_real_video_dec_finalize;
+ element_class->change_state = gst_real_video_dec_change_state;
+
g_object_class_install_property (object_class, PROP_REAL_CODECS_PATH,
g_param_spec_string ("real-codecs-path",
"Path where to search for RealPlayer codecs",