169
149
typedef struct _BraseroCapsLinkList BraseroCapsLinkList;
170
150
struct _BraseroCapsLinkList {
171
BraseroCapsLinkList *next;
172
151
BraseroCapsLink *link;
173
152
BraseroPlugin *plugin;
176
static BraseroCapsLinkList *
177
brasero_caps_link_list_insert (BraseroCapsLinkList *list,
178
BraseroCapsLinkList *node,
181
BraseroCapsLinkList *iter;
186
if (brasero_plugin_get_priority (node->plugin) >
187
brasero_plugin_get_priority (list->plugin)) {
192
if (brasero_plugin_get_priority (node->plugin) ==
193
brasero_plugin_get_priority (list->plugin)) {
199
node->next = list->next;
210
/* Need a node with at least the same priority. Stop if end is reached */
213
brasero_plugin_get_priority (node->plugin) <
214
brasero_plugin_get_priority (iter->next->plugin))
218
/* reached the end of the list, put it at the end */
222
else if (brasero_plugin_get_priority (node->plugin) <
223
brasero_plugin_get_priority (iter->next->plugin)) {
224
/* Put it at the end of the list */
226
iter->next->next = node;
228
else if (brasero_plugin_get_priority (node->plugin) >
229
brasero_plugin_get_priority (iter->next->plugin)) {
230
/* insert it before iter->next */
231
node->next = iter->next;
235
/* insert it before the link with the same priority */
236
node->next = iter->next;
240
/* insert it after the link with the same priority */
241
node->next = iter->next->next;
242
iter->next->next = node;
156
brasero_caps_link_list_sort (gconstpointer a,
159
const BraseroCapsLinkList *node1 = a;
160
const BraseroCapsLinkList *node2 = b;
161
return brasero_plugin_get_priority (node2->plugin) -
162
brasero_plugin_get_priority (node1->plugin);
166
brasero_caps_get_best_path (GSList *path1,
169
GSList *iter1, *iter2;
174
for (; iter1 && iter2; iter1 = iter1->next, iter2 = iter2->next) {
175
gint priority1, priority2;
176
BraseroCapsLinkList *node1, *node2;
180
priority1 = brasero_plugin_get_priority (node1->plugin);
181
priority2 = brasero_plugin_get_priority (node2->plugin);
182
if (priority1 > priority2) {
183
g_slist_foreach (path2, (GFunc) g_free, NULL);
184
g_slist_free (path2);
188
if (priority1 < priority2) {
189
g_slist_foreach (path1, (GFunc) g_free, NULL);
190
g_slist_free (path1);
195
/* equality all along or one of them is shorter. Keep the shorter or
196
* path1 in case of complete equality. */
197
if (!iter2 && iter1) {
198
/* This one seems shorter */
199
g_slist_foreach (path1, (GFunc) g_free, NULL);
200
g_slist_free (path1);
204
g_slist_foreach (path2, (GFunc) g_free, NULL);
205
g_slist_free (path2);
210
brasero_caps_find_best_link (BraseroCaps *caps,
213
BraseroBurnFlag session_flags,
215
BraseroTrackType *input,
216
BraseroPluginIOFlag io_flags);
219
brasero_caps_get_plugin_results (BraseroCapsLinkList *node,
222
BraseroBurnFlag session_flags,
224
BraseroTrackType *input,
225
BraseroPluginIOFlag io_flags)
228
guint search_group_id;
229
GSList *plugin_used_caps = g_slist_copy (used_caps);
231
/* determine the group_id for the search */
232
if (brasero_plugin_get_group (node->plugin) > 0 && group_id <= 0)
233
search_group_id = brasero_plugin_get_group (node->plugin);
235
search_group_id = group_id;
237
/* It's not a perfect fit. First see if a plugin with the same
238
* priority don't have the right input. Then see if we can reach
239
* the right input by going through all previous nodes */
240
results = brasero_caps_find_best_link (node->link->caps,
247
g_slist_free (plugin_used_caps);
252
brasero_caps_link_list_have_processing_plugin (GSList *list)
255
BraseroPluginProcessFlag position;
257
position = BRASERO_PLUGIN_RUN_BEFORE_TARGET;
259
for (iter = list; iter; iter = iter->next) {
260
BraseroCapsLinkList *node;
265
caps = node->link->caps;
267
if (brasero_track_type_get_has_medium (&caps->type))
271
position = BRASERO_PLUGIN_RUN_PREPROCESSING;
273
for (modifiers = caps->modifiers; modifiers; modifiers = modifiers->next) {
274
BraseroPluginProcessFlag flags;
275
BraseroPlugin *plugin;
277
plugin = modifiers->data;
278
if (!brasero_plugin_get_active (plugin, 0))
281
brasero_plugin_get_process_flags (plugin, &flags);
282
if ((flags & position) == position)
357
407
/* Then, go through this list (starting with highest priority links)
358
408
* The rule is we prefer the links with the highest priority; if two
359
* links have the same priority and one of them leads to a caps
360
* with the correct type then choose this one. */
361
for (node = list; node; node = node->next) {
362
guint search_group_id;
409
* links have the same priority and one of them leads to a caps with
410
* the correct type then choose this one. */
411
for (iter = list; iter; iter = iter->next) {
412
BraseroCapsLinkList *iter_node;
414
iter_node = iter->data;
416
BRASERO_BURN_LOG ("Trying %s with a priority of %i",
417
brasero_plugin_get_name (iter_node->plugin),
418
brasero_plugin_get_priority (iter_node->plugin));
364
420
/* see if that's a perfect fit; if so, then we're good.
365
421
* - it must have the same caps (type + subtype)
366
* - it must have the proper IO (file) */
367
if ((node->link->caps->flags & BRASERO_PLUGIN_IO_ACCEPT_FILE)
368
&& brasero_caps_is_compatible_type (node->link->caps, input)) {
369
results = g_slist_prepend (NULL, node->link);
422
* - it must have the proper IO (file).
423
* The only case where we don't want a perfect fit is when the
424
* other possibility allows for the inclusion and expression
425
* of active track processing plugins. It allows for example to
427
* mkisofs => checksum image => growisofs
430
if ((iter_node->link->caps->flags & BRASERO_PLUGIN_IO_ACCEPT_FILE)
431
&& brasero_caps_is_compatible_type (iter_node->link->caps, input)) {
373
/* determine the group_id for the search */
374
if (brasero_plugin_get_group (node->plugin) > 0 && group_id <= 0)
375
search_group_id = brasero_plugin_get_group (node->plugin);
377
search_group_id = group_id;
379
/* It's not a perfect fit. First see if a plugin with the same
380
* priority don't have the right input. Then see if we can reach
381
* the right input by going through all previous nodes */
382
results = brasero_caps_find_best_link (node->link->caps,
436
results = brasero_caps_get_plugin_results (iter_node,
390
results = g_slist_prepend (results, node->link);
444
have_processing_plugin = brasero_caps_link_list_have_processing_plugin (results);
449
/* Do not check for results that could be NULL in case of a perfect fit */
455
/* Stage 3: there may be other link with the same priority (most the
456
* time because it is the same plugin) so we try them as well and keep
457
* the one whose next plugin in the list has the highest priority. */
458
for (iter = iter->next; iter; iter = iter->next) {
459
GSList *other_results;
460
BraseroCapsLinkList *iter_node;
462
iter_node = iter->data;
463
if (brasero_plugin_get_priority (iter_node->plugin) !=
464
brasero_plugin_get_priority (node->plugin))
467
BRASERO_BURN_LOG ("Trying %s with a priority of %i",
468
brasero_plugin_get_name (iter_node->plugin),
469
brasero_plugin_get_priority (iter_node->plugin));
471
/* see if that's a perfect fit */
472
if ((iter_node->link->caps->flags & BRASERO_PLUGIN_IO_ACCEPT_FILE) == 0
473
|| !brasero_caps_is_compatible_type (iter_node->link->caps, input)) {
474
other_results = brasero_caps_get_plugin_results (iter_node,
485
have_processing_plugin = brasero_caps_link_list_have_processing_plugin (other_results);
486
if (have_processing_plugin) {
487
/* Note: results == NULL for perfect fit */
488
results = other_results;
494
g_slist_foreach (other_results, (GFunc) g_free, NULL);
495
g_slist_free (other_results);
499
results = brasero_caps_get_best_path (results, other_results);
500
if (results == other_results) {
501
have_processing_plugin = brasero_caps_link_list_have_processing_plugin (other_results);
506
else if (!perfect_fit && !have_processing_plugin) {
507
g_slist_foreach (results, (GFunc) g_free, NULL);
508
g_slist_free (results);
516
results = g_slist_prepend (results, node);
517
list = g_slist_remove (list, node);
396
522
used_caps = g_slist_remove (used_caps, caps);
397
for (node = list; node; node = list) {
523
g_slist_foreach (list, (GFunc) g_free, NULL);
503
627
GSList *retval = NULL;
504
628
GSList *iter, *list;
505
629
BraseroMedia media;
509
632
/* determine the output and the flags for this task */
510
if (brasero_burn_session_is_dest_file (session)) {
634
output.type = temp_output->type;
635
output.subtype.img_format = temp_output->subtype.img_format;
638
brasero_burn_session_get_output_type (session, &output);
640
if (brasero_track_type_get_has_medium (&output))
641
media = brasero_track_type_get_medium_type (&output);
511
643
media = BRASERO_MEDIUM_FILE;
513
output.type = BRASERO_TRACK_TYPE_IMAGE;
514
output.subtype.img_format = brasero_burn_session_get_output_format (session);
517
media = brasero_burn_session_get_dest_media (session);
519
output.type = BRASERO_TRACK_TYPE_DISC;
520
output.subtype.media = media;
523
645
if (BRASERO_BURN_SESSION_NO_TMP_FILE (session))
524
646
flags = BRASERO_PLUGIN_IO_ACCEPT_PIPE;
619
741
/* reverse the list of links to have them in the right order */
620
742
list = g_slist_reverse (list);
621
743
position = BRASERO_PLUGIN_RUN_PREPROCESSING;
622
group_id = self->priv->group_id;
624
745
brasero_burn_session_get_input_type (session, &plugin_input);
625
746
for (iter = list; iter; iter = iter->next) {
626
747
BraseroTrackType plugin_output;
627
BraseroCapsLink *link;
628
BraseroPlugin *plugin;
748
BraseroCapsLinkList *node;
635
/* determine the plugin output */
755
/* determine the plugin output:
756
* if it's not the last one it takes the input of the next
757
* plugin as its output.
758
* Otherwise it uses the final output type */
636
759
if (iter->next) {
637
BraseroCapsLink *next_link;
760
BraseroCapsLinkList *next_node;
639
next_link = iter->next->data;
640
if (next_link == link) {
641
/* That's a processing plugin so the output must
642
* be the exact same as the input, which is not
643
* necessarily the caps type referred to by the
644
* link if the link is amongst the first. In
645
* that case that's the session input. */
646
memcpy (&plugin_output,
648
sizeof (BraseroTrackType));
651
memcpy (&plugin_output,
652
&next_link->caps->type,
653
sizeof (BraseroTrackType));
762
next_node = iter->next->data;
763
memcpy (&plugin_output,
764
&next_node->link->caps->type,
765
sizeof (BraseroTrackType));
657
768
memcpy (&plugin_output,
661
772
/* first see if there are track processing plugins */
662
773
result = brasero_caps_add_processing_plugins_to_task (session,
667
778
retval = g_slist_concat (retval, result);
669
/* create job from the best plugin in link */
670
plugin = brasero_caps_link_find_plugin (link,
678
BRASERO_BURN_ERROR_GENERAL,
679
_("An internal error occured"));
680
g_slist_foreach (retval, (GFunc) g_object_unref, NULL);
681
g_slist_free (retval);
686
/* This is meant to have plugins in the same group id as much as
688
if (brasero_plugin_get_group (plugin) > 0 && group_id <= 0)
689
group_id = brasero_plugin_get_group (plugin);
691
type = brasero_plugin_get_gtype (plugin);
780
/* Create an object from the plugin */
781
type = brasero_plugin_get_gtype (node->plugin);
692
782
job = BRASERO_JOB (g_object_new (type,
693
783
"output", &plugin_output,
695
785
g_signal_connect (job,
697
787
G_CALLBACK (brasero_burn_caps_job_error_cb),
701
|| !(link->caps->flags & BRASERO_PLUGIN_IO_ACCEPT_PIPE)
791
|| !(node->link->caps->flags & BRASERO_PLUGIN_IO_ACCEPT_PIPE)
702
792
|| !BRASERO_BURN_SESSION_NO_TMP_FILE (session)) {
703
793
/* only the last task will be doing the proper action
704
794
* all other are only steps to take to reach the final
896
985
plugin_output = &last_caps->type;
898
/* find the best plugin */
899
candidate_plugin = NULL;
900
for (plugins = link->plugins; plugins; plugins = plugins->next) {
901
BraseroPlugin *plugin;
903
plugin = plugins->data;
905
if (!brasero_plugin_get_active (plugin))
908
if (!candidate_plugin)
909
candidate_plugin = plugin;
910
else if (brasero_plugin_get_priority (plugin) >
911
brasero_plugin_get_priority (candidate_plugin))
912
candidate_plugin = plugin;
915
987
/* create the object */
916
type = brasero_plugin_get_gtype (candidate_plugin);
988
type = brasero_plugin_get_gtype (node->plugin);
917
989
job = BRASERO_JOB (g_object_new (type,
918
990
"output", plugin_output,
920
992
g_signal_connect (job,
922
994
G_CALLBACK (brasero_burn_caps_job_error_cb),
925
997
brasero_task_add_item (task, BRASERO_TASK_ITEM (job));
927
BRASERO_BURN_LOG ("%s added to task", brasero_plugin_get_name (candidate_plugin));
999
BRASERO_BURN_LOG ("%s added to task", brasero_plugin_get_name (node->plugin));
1001
g_slist_foreach (list, (GFunc) g_free, NULL);
929
1002
g_slist_free (list);
931
1004
/* Create the candidate */