diff options
author | Wim Taymans <wim.taymans@gmail.com> | 2008-06-13 18:03:16 +0000 |
---|---|---|
committer | Wim Taymans <wim.taymans@gmail.com> | 2008-06-13 18:03:16 +0000 |
commit | 1a39f60d9f9fa8ad7b664787f162f9fa7e616957 (patch) | |
tree | 8dcc50b600e09463ecfa5375cc00541a3fb7bc38 /gst/real/gstrealvideodec.c | |
parent | 7ce74ccd5db8cc084ebe07da9e33366712064ee0 (diff) | |
download | gst-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.c | 179 |
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", |