mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-23 02:01:12 +00:00
formatter: Enhance error reporting
And add a "loading-error" signal in GESProject so we can report issue when loading async elements for the timeline.
This commit is contained in:
parent
c125093bb1
commit
6f9e6d3586
6 changed files with 99 additions and 24 deletions
|
@ -88,6 +88,8 @@ struct _GESBaseXmlFormatterPrivate
|
|||
/* List of asset waited to be created */
|
||||
GList *pending_assets;
|
||||
|
||||
GError *asset_error;
|
||||
|
||||
/* current track element */
|
||||
GESTrackElement *current_track_element;
|
||||
|
||||
|
@ -273,6 +275,7 @@ _load_from_uri (GESFormatter * self, GESTimeline * timeline, const gchar * uri,
|
|||
{
|
||||
GESBaseXmlFormatterPrivate *priv = _GET_PRIV (self);
|
||||
|
||||
GST_INFO_OBJECT (self, "Loading %s in %" GST_PTR_FORMAT, uri, timeline);
|
||||
ges_timeline_set_auto_transition (timeline, FALSE);
|
||||
|
||||
priv->parsecontext =
|
||||
|
@ -431,7 +434,7 @@ ges_base_xml_formatter_class_init (GESBaseXmlFormatterClass * self_class)
|
|||
|
||||
self_class->save = NULL;
|
||||
|
||||
GST_DEBUG_CATEGORY_INIT (base_xml_formatter, "base-xml-formatter",
|
||||
GST_DEBUG_CATEGORY_INIT (base_xml_formatter, "gesbasexmlformatter",
|
||||
GST_DEBUG_FG_BLUE | GST_DEBUG_BOLD, "Base XML Formatter");
|
||||
}
|
||||
|
||||
|
@ -490,9 +493,9 @@ static void
|
|||
_loading_done (GESFormatter * self)
|
||||
{
|
||||
GList *assets, *tmp;
|
||||
GError *error = NULL;
|
||||
GESBaseXmlFormatterPrivate *priv = GES_BASE_XML_FORMATTER (self)->priv;
|
||||
|
||||
|
||||
if (priv->parsecontext)
|
||||
g_markup_parse_context_free (priv->parsecontext);
|
||||
priv->parsecontext = NULL;
|
||||
|
@ -504,10 +507,16 @@ _loading_done (GESFormatter * self)
|
|||
}
|
||||
g_list_free_full (assets, g_object_unref);
|
||||
|
||||
if (priv->state == STATE_LOADING_ASSETS_AND_SYNC) {
|
||||
if (priv->asset_error) {
|
||||
error = priv->asset_error;
|
||||
priv->asset_error = NULL;
|
||||
} else if (priv->state == STATE_LOADING_ASSETS_AND_SYNC) {
|
||||
GMarkupParseContext *context =
|
||||
_parse (GES_BASE_XML_FORMATTER (self), &error, STATE_LOADING_CLIPS);
|
||||
GST_INFO_OBJECT (self, "Assets cached... now loading the timeline.");
|
||||
g_markup_parse_context_free (_parse (GES_BASE_XML_FORMATTER (self), NULL,
|
||||
STATE_LOADING_CLIPS));
|
||||
|
||||
if (context)
|
||||
g_markup_parse_context_free (context);
|
||||
g_assert (priv->pending_assets == NULL);
|
||||
}
|
||||
|
||||
|
@ -516,7 +525,8 @@ _loading_done (GESFormatter * self)
|
|||
priv->timeline_auto_transition);
|
||||
|
||||
g_hash_table_foreach (priv->layers, (GHFunc) _set_auto_transition, NULL);
|
||||
ges_project_set_loaded (self->project, self);
|
||||
ges_project_set_loaded (self->project, self, error);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@ -565,14 +575,17 @@ _add_object_to_layer (GESBaseXmlFormatterPrivate * priv, const gchar * id,
|
|||
GESLayer * layer, GESAsset * asset, GstClockTime start,
|
||||
GstClockTime inpoint, GstClockTime duration,
|
||||
GESTrackType track_types, const gchar * metadatas,
|
||||
GstStructure * properties, GstStructure * children_properties)
|
||||
GstStructure * properties, GstStructure * children_properties,
|
||||
GError ** error)
|
||||
{
|
||||
GESClip *clip = ges_layer_add_asset (layer,
|
||||
asset, start, inpoint, duration, track_types);
|
||||
|
||||
if (clip == NULL) {
|
||||
GST_WARNING_OBJECT (clip, "Could not add object from asset: %s",
|
||||
ges_asset_get_id (asset));
|
||||
g_set_error (error, GES_ERROR, GES_ERROR_FORMATTER_MALFORMED_INPUT_FILE,
|
||||
"Could not add clip %s [ %" GST_TIME_FORMAT ", ( %" GST_TIME_FORMAT
|
||||
") - %" GST_TIME_FORMAT "]", id, GST_TIME_ARGS (start),
|
||||
GST_TIME_ARGS (inpoint), GST_TIME_ARGS (duration));
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -667,6 +680,8 @@ new_asset_cb (GESAsset * source, GAsyncResult * res, PendingAsset * passet)
|
|||
error->message);
|
||||
|
||||
_free_pending_asset (priv, passet);
|
||||
if (!priv->asset_error)
|
||||
priv->asset_error = g_error_copy (error);
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
@ -827,7 +842,7 @@ ges_base_xml_formatter_add_asset (GESBaseXmlFormatter * self,
|
|||
GESBaseXmlFormatterPrivate *priv = _GET_PRIV (self);
|
||||
|
||||
if (priv->state != STATE_LOADING_ASSETS_AND_SYNC) {
|
||||
GST_INFO ("Not parsing assets in %s state",
|
||||
GST_DEBUG_OBJECT (self, "Not parsing assets in %s state",
|
||||
loading_state_name (priv->state));
|
||||
|
||||
return;
|
||||
|
@ -880,15 +895,14 @@ ges_base_xml_formatter_add_clip (GESBaseXmlFormatter * self,
|
|||
asset = ges_asset_request (type, asset_id, NULL);
|
||||
if (!asset) {
|
||||
g_set_error (error, GES_ERROR, GES_ERROR_FORMATTER_MALFORMED_INPUT_FILE,
|
||||
"Clip references asset %s which was not present in the list of ressource"
|
||||
" the file seems to be malformed.", asset_id);
|
||||
GST_ERROR_OBJECT (self, "%s", (*error)->message);
|
||||
"Clip references asset %s of type %s which was not present in the list of ressource,"
|
||||
" the file seems to be malformed.", asset_id, g_type_name (type));
|
||||
return;
|
||||
}
|
||||
|
||||
nclip = _add_object_to_layer (priv, id, entry->layer,
|
||||
asset, start, inpoint, duration, track_types, metadatas, properties,
|
||||
children_properties);
|
||||
children_properties, error);
|
||||
|
||||
gst_object_unref (asset);
|
||||
if (!nclip)
|
||||
|
|
|
@ -229,7 +229,8 @@ _find_formatter_asset_for_id (const gchar *id);
|
|||
/* FIXME This should probably become public, but we need to make sure it
|
||||
* is the right API before doing so */
|
||||
G_GNUC_INTERNAL gboolean ges_project_set_loaded (GESProject * project,
|
||||
GESFormatter *formatter);
|
||||
GESFormatter *formatter,
|
||||
GError *error);
|
||||
G_GNUC_INTERNAL gchar * ges_project_try_updating_id (GESProject *self,
|
||||
GESAsset *asset,
|
||||
GError *error);
|
||||
|
|
|
@ -437,7 +437,7 @@ track_element_added_cb (GESClip * clip,
|
|||
priv->sources_to_load = g_list_remove (priv->sources_to_load, clip);
|
||||
if (!priv->sources_to_load && GES_FORMATTER (formatter)->project)
|
||||
ges_project_set_loaded (GES_FORMATTER (formatter)->project,
|
||||
GES_FORMATTER (formatter));
|
||||
GES_FORMATTER (formatter), NULL);
|
||||
}
|
||||
|
||||
/* Disconnect the signal */
|
||||
|
@ -668,7 +668,7 @@ load_pitivi_file_from_uri (GESFormatter * self,
|
|||
*/
|
||||
if (!g_hash_table_size (priv->clips_table) && GES_FORMATTER (self)->project) {
|
||||
ges_project_set_loaded (GES_FORMATTER (self)->project,
|
||||
GES_FORMATTER (self));
|
||||
GES_FORMATTER (self), NULL);
|
||||
} else {
|
||||
if (!make_clips (self)) {
|
||||
GST_ERROR ("Couldn't deserialise the project properly");
|
||||
|
|
|
@ -97,6 +97,7 @@ enum
|
|||
{
|
||||
LOADING_SIGNAL,
|
||||
LOADED_SIGNAL,
|
||||
ERROR_LOADING,
|
||||
ERROR_LOADING_ASSET,
|
||||
ASSET_ADDED_SIGNAL,
|
||||
ASSET_REMOVED_SIGNAL,
|
||||
|
@ -591,6 +592,20 @@ ges_project_class_init (GESProjectClass * klass)
|
|||
NULL, NULL, g_cclosure_marshal_generic,
|
||||
G_TYPE_NONE, 3, G_TYPE_ERROR, G_TYPE_STRING, G_TYPE_GTYPE);
|
||||
|
||||
/**
|
||||
* GESProject::error-loading:
|
||||
* @project: the #GESProject on which a problem happend when creted a #GESAsset
|
||||
* @timeline: The timeline that failed loading
|
||||
* @error: The #GError defining the error that occured
|
||||
*
|
||||
* Since: 1.18
|
||||
*/
|
||||
_signals[ERROR_LOADING] =
|
||||
g_signal_new ("error-loading", G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST, 0,
|
||||
NULL, NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 2, GES_TYPE_TIMELINE,
|
||||
G_TYPE_ERROR);
|
||||
|
||||
object_class->dispose = _dispose;
|
||||
object_class->finalize = _finalize;
|
||||
|
||||
|
@ -731,8 +746,15 @@ new_asset_cb (GESAsset * source, GAsyncResult * res, GESProject * project)
|
|||
* Returns: %TRUE if the signale could be emitted %FALSE otherwize
|
||||
*/
|
||||
gboolean
|
||||
ges_project_set_loaded (GESProject * project, GESFormatter * formatter)
|
||||
ges_project_set_loaded (GESProject * project, GESFormatter * formatter,
|
||||
GError * error)
|
||||
{
|
||||
if (error) {
|
||||
GST_ERROR_OBJECT (project, "Emit project error-loading %s", error->message);
|
||||
g_signal_emit (project, _signals[ERROR_LOADING], 0, formatter->timeline,
|
||||
error);
|
||||
}
|
||||
|
||||
GST_INFO_OBJECT (project, "Emit project loaded");
|
||||
if (GST_STATE (formatter->timeline) < GST_STATE_PAUSED) {
|
||||
timeline_fill_gaps (formatter->timeline);
|
||||
|
|
|
@ -142,6 +142,7 @@ typedef struct
|
|||
GError *error;
|
||||
gulong loaded_sigid;
|
||||
gulong error_sigid;
|
||||
gulong error_asset_sigid;
|
||||
} TimelineConstructionData;
|
||||
|
||||
static void
|
||||
|
@ -156,8 +157,8 @@ project_loaded_cb (GESProject * project, GESTimeline * timeline,
|
|||
}
|
||||
|
||||
static void
|
||||
error_loading_asset_cb (GESProject * project, GError * error, gchar * id,
|
||||
GType extractable_type, TimelineConstructionData * data)
|
||||
error_loading_cb (GESProject * project, GESTimeline * timeline,
|
||||
GError * error, TimelineConstructionData * data)
|
||||
{
|
||||
data->error = g_error_copy (error);
|
||||
g_signal_handler_disconnect (project, data->error_sigid);
|
||||
|
@ -166,6 +167,17 @@ error_loading_asset_cb (GESProject * project, GError * error, gchar * id,
|
|||
g_main_loop_quit (data->ml);
|
||||
}
|
||||
|
||||
static void
|
||||
error_loading_asset_cb (GESProject * project, GError * error, gchar * id,
|
||||
GType extractable_type, TimelineConstructionData * data)
|
||||
{
|
||||
data->error = g_error_copy (error);
|
||||
g_signal_handler_disconnect (project, data->error_asset_sigid);
|
||||
data->error_asset_sigid = 0;
|
||||
|
||||
g_main_loop_quit (data->ml);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
ges_demux_src_probe (GstPad * pad, GstPadProbeInfo * info, GstElement * parent)
|
||||
{
|
||||
|
@ -337,9 +349,12 @@ ges_demux_create_timeline (GESDemux * self, gchar * uri, GError ** error)
|
|||
data.loaded_sigid =
|
||||
g_signal_connect (project, "loaded", G_CALLBACK (project_loaded_cb),
|
||||
&data);
|
||||
data.error_sigid =
|
||||
data.error_asset_sigid =
|
||||
g_signal_connect_after (project, "error-loading-asset",
|
||||
G_CALLBACK (error_loading_asset_cb), &data);
|
||||
data.error_sigid =
|
||||
g_signal_connect_after (project, "error-loading",
|
||||
G_CALLBACK (error_loading_cb), &data);
|
||||
|
||||
unused = GES_TIMELINE (ges_asset_extract (GES_ASSET (project), &data.error));
|
||||
if (data.error) {
|
||||
|
@ -350,6 +365,9 @@ ges_demux_create_timeline (GESDemux * self, gchar * uri, GError ** error)
|
|||
|
||||
g_main_loop_run (data.ml);
|
||||
g_main_loop_unref (data.ml);
|
||||
if (data.error)
|
||||
goto done;
|
||||
|
||||
ges_demux_adapt_timeline_duration (self, data.timeline);
|
||||
|
||||
query = gst_query_new_uri ();
|
||||
|
@ -387,13 +405,21 @@ done:
|
|||
if (data.error_sigid)
|
||||
g_signal_handler_disconnect (project, data.error_sigid);
|
||||
|
||||
if (data.error_asset_sigid)
|
||||
g_signal_handler_disconnect (project, data.error_asset_sigid);
|
||||
|
||||
g_clear_object (&project);
|
||||
|
||||
GST_INFO_OBJECT (self, "Timeline properly loaded: %" GST_PTR_FORMAT,
|
||||
data.timeline);
|
||||
ges_base_bin_set_timeline (GES_BASE_BIN (self), data.timeline);
|
||||
gst_element_foreach_src_pad (GST_ELEMENT (self), ges_demux_set_srcpad_probe,
|
||||
NULL);
|
||||
|
||||
if (!data.error) {
|
||||
ges_base_bin_set_timeline (GES_BASE_BIN (self), data.timeline);
|
||||
gst_element_foreach_src_pad (GST_ELEMENT (self), ges_demux_set_srcpad_probe,
|
||||
NULL);
|
||||
} else {
|
||||
*error = data.error;
|
||||
}
|
||||
|
||||
g_main_context_pop_thread_default (ctx);
|
||||
|
||||
|
|
|
@ -172,6 +172,16 @@ retry:
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
_project_loading_error_cb (GESProject * project, GESTimeline * timeline,
|
||||
GError * error, GESLauncher * self)
|
||||
{
|
||||
g_printerr ("Error loading timeline: '%s'\n", error->message);
|
||||
self->priv->seenerrors = TRUE;
|
||||
|
||||
g_application_quit (G_APPLICATION (self));
|
||||
}
|
||||
|
||||
static void
|
||||
_project_loaded_cb (GESProject * project, GESTimeline * timeline,
|
||||
GESLauncher * self)
|
||||
|
@ -256,6 +266,8 @@ _create_timeline (GESLauncher * self, const gchar * serialized_timeline,
|
|||
g_signal_connect (project, "error-loading-asset",
|
||||
G_CALLBACK (_error_loading_asset_cb), self);
|
||||
g_signal_connect (project, "loaded", G_CALLBACK (_project_loaded_cb), self);
|
||||
g_signal_connect (project, "error-loading",
|
||||
G_CALLBACK (_project_loading_error_cb), self);
|
||||
|
||||
self->priv->timeline =
|
||||
GES_TIMELINE (ges_asset_extract (GES_ASSET (project), &error));
|
||||
|
|
Loading…
Reference in a new issue