171
171
typedef struct _BraseroCapsLinkList BraseroCapsLinkList;
172
172
struct _BraseroCapsLinkList {
173
BraseroCapsLinkList *next;
174
173
BraseroCapsLink *link;
175
174
BraseroPlugin *plugin;
178
static BraseroCapsLinkList *
179
brasero_caps_link_list_insert (BraseroCapsLinkList *list,
180
BraseroCapsLinkList *node,
183
BraseroCapsLinkList *iter;
188
if (brasero_plugin_get_priority (node->plugin) >
189
brasero_plugin_get_priority (list->plugin)) {
194
if (brasero_plugin_get_priority (node->plugin) ==
195
brasero_plugin_get_priority (list->plugin)) {
201
node->next = list->next;
212
/* Need a node with at least the same priority. Stop if end is reached */
215
brasero_plugin_get_priority (node->plugin) <
216
brasero_plugin_get_priority (iter->next->plugin))
220
/* reached the end of the list, put it at the end */
224
else if (brasero_plugin_get_priority (node->plugin) <
225
brasero_plugin_get_priority (iter->next->plugin)) {
226
/* Put it at the end of the list */
228
iter->next->next = node;
230
else if (brasero_plugin_get_priority (node->plugin) >
231
brasero_plugin_get_priority (iter->next->plugin)) {
232
/* insert it before iter->next */
233
node->next = iter->next;
237
/* insert it before the link with the same priority */
238
node->next = iter->next;
242
/* insert it after the link with the same priority */
243
node->next = iter->next->next;
244
iter->next->next = node;
178
brasero_caps_link_list_sort (gconstpointer a,
181
const BraseroCapsLinkList *node1 = a;
182
const BraseroCapsLinkList *node2 = b;
183
return brasero_plugin_get_priority (node2->plugin) -
184
brasero_plugin_get_priority (node1->plugin);
188
brasero_caps_get_best_path (GSList *path1,
191
GSList *iter1, *iter2;
196
for (; iter1 && iter2; iter1 = iter1->next, iter2 = iter2->next) {
197
gint priority1, priority2;
198
BraseroCapsLinkList *node1, *node2;
202
priority1 = brasero_plugin_get_priority (node1->plugin);
203
priority2 = brasero_plugin_get_priority (node2->plugin);
204
if (priority1 > priority2) {
205
g_slist_foreach (path2, (GFunc) g_free, NULL);
206
g_slist_free (path2);
210
if (priority1 < priority2) {
211
g_slist_foreach (path1, (GFunc) g_free, NULL);
212
g_slist_free (path1);
217
/* equality all along or one of them is shorter. Keep the shorter or
218
* path1 in case of complete equality. */
219
if (!iter2 && iter1) {
220
/* This one seems shorter */
221
g_slist_foreach (path1, (GFunc) g_free, NULL);
222
g_slist_free (path1);
226
g_slist_foreach (path2, (GFunc) g_free, NULL);
227
g_slist_free (path2);
232
brasero_caps_find_best_link (BraseroCaps *caps,
235
BraseroBurnFlag session_flags,
237
BraseroTrackType *input,
238
BraseroPluginIOFlag io_flags);
241
brasero_caps_get_plugin_results (BraseroCapsLinkList *node,
244
BraseroBurnFlag session_flags,
246
BraseroTrackType *input,
247
BraseroPluginIOFlag io_flags)
250
guint search_group_id;
251
GSList *plugin_used_caps = g_slist_copy (used_caps);
253
/* determine the group_id for the search */
254
if (brasero_plugin_get_group (node->plugin) > 0 && group_id <= 0)
255
search_group_id = brasero_plugin_get_group (node->plugin);
257
search_group_id = group_id;
259
/* It's not a perfect fit. First see if a plugin with the same
260
* priority don't have the right input. Then see if we can reach
261
* the right input by going through all previous nodes */
262
results = brasero_caps_find_best_link (node->link->caps,
269
g_slist_free (plugin_used_caps);
274
brasero_caps_link_list_have_processing_plugin (GSList *list)
277
BraseroPluginProcessFlag position;
279
position = BRASERO_PLUGIN_RUN_BEFORE_TARGET;
281
for (iter = list; iter; iter = iter->next) {
282
BraseroCapsLinkList *node;
287
caps = node->link->caps;
289
if (brasero_track_type_get_has_medium (&caps->type))
293
position = BRASERO_PLUGIN_RUN_PREPROCESSING;
295
for (modifiers = caps->modifiers; modifiers; modifiers = modifiers->next) {
296
BraseroPluginProcessFlag flags;
297
BraseroPlugin *plugin;
299
plugin = modifiers->data;
300
if (!brasero_plugin_get_active (plugin, 0))
303
brasero_plugin_get_process_flags (plugin, &flags);
304
if ((flags & position) == position)
359
429
/* Then, go through this list (starting with highest priority links)
360
430
* The rule is we prefer the links with the highest priority; if two
361
* links have the same priority and one of them leads to a caps
362
* with the correct type then choose this one. */
363
for (node = list; node; node = node->next) {
364
guint search_group_id;
431
* links have the same priority and one of them leads to a caps with
432
* the correct type then choose this one. */
433
for (iter = list; iter; iter = iter->next) {
434
BraseroCapsLinkList *iter_node;
436
iter_node = iter->data;
438
BRASERO_BURN_LOG ("Trying %s with a priority of %i",
439
brasero_plugin_get_name (iter_node->plugin),
440
brasero_plugin_get_priority (iter_node->plugin));
366
442
/* see if that's a perfect fit; if so, then we're good.
367
443
* - it must have the same caps (type + subtype)
368
* - it must have the proper IO (file) */
369
if ((node->link->caps->flags & BRASERO_PLUGIN_IO_ACCEPT_FILE)
370
&& brasero_caps_is_compatible_type (node->link->caps, input)) {
371
results = g_slist_prepend (NULL, node->link);
444
* - it must have the proper IO (file).
445
* The only case where we don't want a perfect fit is when the
446
* other possibility allows for the inclusion and expression
447
* of active track processing plugins. It allows for example to
449
* mkisofs => checksum image => growisofs
452
if ((iter_node->link->caps->flags & BRASERO_PLUGIN_IO_ACCEPT_FILE)
453
&& brasero_caps_is_compatible_type (iter_node->link->caps, input)) {
375
/* determine the group_id for the search */
376
if (brasero_plugin_get_group (node->plugin) > 0 && group_id <= 0)
377
search_group_id = brasero_plugin_get_group (node->plugin);
379
search_group_id = group_id;
381
/* It's not a perfect fit. First see if a plugin with the same
382
* priority don't have the right input. Then see if we can reach
383
* the right input by going through all previous nodes */
384
results = brasero_caps_find_best_link (node->link->caps,
458
results = brasero_caps_get_plugin_results (iter_node,
392
results = g_slist_prepend (results, node->link);
466
have_processing_plugin = brasero_caps_link_list_have_processing_plugin (results);
471
/* Do not check for results that could be NULL in case of a perfect fit */
477
/* Stage 3: there may be other link with the same priority (most the
478
* time because it is the same plugin) so we try them as well and keep
479
* the one whose next plugin in the list has the highest priority. */
480
for (iter = iter->next; iter; iter = iter->next) {
481
GSList *other_results;
482
BraseroCapsLinkList *iter_node;
484
iter_node = iter->data;
485
if (brasero_plugin_get_priority (iter_node->plugin) !=
486
brasero_plugin_get_priority (node->plugin))
489
BRASERO_BURN_LOG ("Trying %s with a priority of %i",
490
brasero_plugin_get_name (iter_node->plugin),
491
brasero_plugin_get_priority (iter_node->plugin));
493
/* see if that's a perfect fit */
494
if ((iter_node->link->caps->flags & BRASERO_PLUGIN_IO_ACCEPT_FILE) == 0
495
|| !brasero_caps_is_compatible_type (iter_node->link->caps, input)) {
496
other_results = brasero_caps_get_plugin_results (iter_node,
507
have_processing_plugin = brasero_caps_link_list_have_processing_plugin (other_results);
508
if (have_processing_plugin) {
509
/* Note: results == NULL for perfect fit */
510
results = other_results;
516
g_slist_foreach (other_results, (GFunc) g_free, NULL);
517
g_slist_free (other_results);
521
results = brasero_caps_get_best_path (results, other_results);
522
if (results == other_results) {
523
have_processing_plugin = brasero_caps_link_list_have_processing_plugin (other_results);
528
else if (!perfect_fit && !have_processing_plugin) {
529
g_slist_foreach (results, (GFunc) g_free, NULL);
530
g_slist_free (results);
538
results = g_slist_prepend (results, node);
539
list = g_slist_remove (list, node);
398
544
used_caps = g_slist_remove (used_caps, caps);
399
for (node = list; node; node = list) {
545
g_slist_foreach (list, (GFunc) g_free, NULL);
621
763
/* reverse the list of links to have them in the right order */
622
764
list = g_slist_reverse (list);
623
765
position = BRASERO_PLUGIN_RUN_PREPROCESSING;
624
group_id = self->priv->group_id;
626
767
brasero_burn_session_get_input_type (session, &plugin_input);
627
768
for (iter = list; iter; iter = iter->next) {
628
769
BraseroTrackType plugin_output;
629
BraseroCapsLink *link;
630
BraseroPlugin *plugin;
770
BraseroCapsLinkList *node;
637
777
/* determine the plugin output:
638
* if it's not the last one it takes the input
639
* of the next plugin as its output.
778
* if it's not the last one it takes the input of the next
779
* plugin as its output.
640
780
* Otherwise it uses the final output type */
782
BraseroCapsLinkList *next_node;
784
next_node = iter->next->data;
642
785
memcpy (&plugin_output,
643
&((BraseroCapsLink *) (iter->next->data))->caps->type,
786
&next_node->link->caps->type,
644
787
sizeof (BraseroTrackType));
646
790
memcpy (&plugin_output,
650
794
/* first see if there are track processing plugins */
651
795
result = brasero_caps_add_processing_plugins_to_task (session,
656
800
retval = g_slist_concat (retval, result);
658
/* create job from the best plugin in link */
659
plugin = brasero_caps_link_find_plugin (link,
667
BRASERO_BURN_ERROR_GENERAL,
668
_("An internal error occurred"));
669
g_slist_foreach (retval, (GFunc) g_object_unref, NULL);
670
g_slist_free (retval);
675
/* This is meant to have plugins in the same group id as much as
677
if (brasero_plugin_get_group (plugin) > 0 && group_id <= 0)
678
group_id = brasero_plugin_get_group (plugin);
680
type = brasero_plugin_get_gtype (plugin);
802
/* Create an object from the plugin */
803
type = brasero_plugin_get_gtype (node->plugin);
681
804
job = BRASERO_JOB (g_object_new (type,
682
805
"output", &plugin_output,
684
807
g_signal_connect (job,
686
809
G_CALLBACK (brasero_burn_caps_job_error_cb),
690
|| !(link->caps->flags & BRASERO_PLUGIN_IO_ACCEPT_PIPE)
813
|| !(node->link->caps->flags & BRASERO_PLUGIN_IO_ACCEPT_PIPE)
691
814
|| !BRASERO_BURN_SESSION_NO_TMP_FILE (session)) {
692
815
/* only the last task will be doing the proper action
693
816
* all other are only steps to take to reach the final
885
1007
plugin_output = &last_caps->type;
887
/* find the best plugin */
888
candidate_plugin = NULL;
889
for (plugins = link->plugins; plugins; plugins = plugins->next) {
890
BraseroPlugin *plugin;
892
plugin = plugins->data;
894
if (!brasero_plugin_get_active (plugin, 0))
897
if (!candidate_plugin)
898
candidate_plugin = plugin;
899
else if (brasero_plugin_get_priority (plugin) >
900
brasero_plugin_get_priority (candidate_plugin))
901
candidate_plugin = plugin;
904
1009
/* create the object */
905
type = brasero_plugin_get_gtype (candidate_plugin);
1010
type = brasero_plugin_get_gtype (node->plugin);
906
1011
job = BRASERO_JOB (g_object_new (type,
907
1012
"output", plugin_output,
909
1014
g_signal_connect (job,
911
1016
G_CALLBACK (brasero_burn_caps_job_error_cb),
914
1019
brasero_task_add_item (task, BRASERO_TASK_ITEM (job));
916
BRASERO_BURN_LOG ("%s added to task", brasero_plugin_get_name (candidate_plugin));
1021
BRASERO_BURN_LOG ("%s added to task", brasero_plugin_get_name (node->plugin));
1023
g_slist_foreach (list, (GFunc) g_free, NULL);
918
1024
g_slist_free (list);
920
1026
/* Create the candidate */