diff options
author | Edward Hervey <bilboed@bilboed.com> | 2009-05-30 17:57:53 +0200 |
---|---|---|
committer | Edward Hervey <bilboed@bilboed.com> | 2009-05-30 18:00:07 +0200 |
commit | 9592436bc755308d6f5faf52528889661e22d294 (patch) | |
tree | 3817d516172a6b7ee757a77b344b9526b21b48a9 | |
parent | a61559d96d0c9defaee86ec3236c6df6f494e2ad (diff) |
GnlComposition: Use expandable GnlObject property.
-rw-r--r-- | gnl/gnlcomposition.c | 65 | ||||
-rw-r--r-- | tests/check/complex.c | 245 | ||||
-rw-r--r-- | tests/check/gnloperation.c | 219 |
3 files changed, 507 insertions, 22 deletions
diff --git a/gnl/gnlcomposition.c b/gnl/gnlcomposition.c index 4c34eaf..cf2b4c0 100644 --- a/gnl/gnlcomposition.c +++ b/gnl/gnlcomposition.c | |||
@@ -96,7 +96,8 @@ struct _GnlCompositionPrivate | |||
96 | /* current stack, list of GnlObject* */ | 96 | /* current stack, list of GnlObject* */ |
97 | GNode *current; | 97 | GNode *current; |
98 | 98 | ||
99 | GnlObject *defaultobject; | 99 | /* List of GnlObject whose start/duration will be the same as the composition */ |
100 | GList *expandables; | ||
100 | 101 | ||
101 | /* TRUE if the stack is valid. | 102 | /* TRUE if the stack is valid. |
102 | * This is meant to prevent the top-level pad to be unblocked before the stack | 103 | * This is meant to prevent the top-level pad to be unblocked before the stack |
@@ -328,8 +329,6 @@ gnl_composition_init (GnlComposition * comp, | |||
328 | 329 | ||
329 | comp->private->waitingpads = 0; | 330 | comp->private->waitingpads = 0; |
330 | 331 | ||
331 | comp->private->defaultobject = NULL; | ||
332 | |||
333 | comp->private->objects_hash = g_hash_table_new_full | 332 | comp->private->objects_hash = g_hash_table_new_full |
334 | (g_direct_hash, | 333 | (g_direct_hash, |
335 | g_direct_equal, NULL, (GDestroyNotify) hash_value_destroy); | 334 | g_direct_equal, NULL, (GDestroyNotify) hash_value_destroy); |
@@ -366,6 +365,11 @@ gnl_composition_dispose (GObject * object) | |||
366 | comp->private->current = NULL; | 365 | comp->private->current = NULL; |
367 | } | 366 | } |
368 | 367 | ||
368 | if (comp->private->expandables) { | ||
369 | g_list_free (comp->private->expandables); | ||
370 | comp->private->expandables = NULL; | ||
371 | } | ||
372 | |||
369 | G_OBJECT_CLASS (parent_class)->dispose (object); | 373 | G_OBJECT_CLASS (parent_class)->dispose (object); |
370 | } | 374 | } |
371 | 375 | ||
@@ -917,7 +921,7 @@ handle_seek_event (GnlComposition * comp, GstEvent * event) | |||
917 | 921 | ||
918 | /* crop the segment start/stop values */ | 922 | /* crop the segment start/stop values */ |
919 | /* Only crop segment start value if we don't have a default object */ | 923 | /* Only crop segment start value if we don't have a default object */ |
920 | if (comp->private->defaultobject == NULL) | 924 | if (comp->private->expandables == NULL) |
921 | comp->private->segment->start = MAX (comp->private->segment->start, | 925 | comp->private->segment->start = MAX (comp->private->segment->start, |
922 | ((GnlObject *) comp)->start); | 926 | ((GnlObject *) comp)->start); |
923 | comp->private->segment->stop = MIN (comp->private->segment->stop, | 927 | comp->private->segment->stop = MIN (comp->private->segment->stop, |
@@ -1262,9 +1266,14 @@ get_stack_list (GnlComposition * comp, GstClockTime timestamp, | |||
1262 | } | 1266 | } |
1263 | } | 1267 | } |
1264 | 1268 | ||
1265 | /* append the default source if we have one */ | 1269 | /* Insert the expandables */ |
1266 | if ((timestamp < ((GnlObject *) comp)->stop) && comp->private->defaultobject) | 1270 | if (G_LIKELY (timestamp < ((GnlObject *) comp)->stop)) |
1267 | stack = g_list_append (stack, comp->private->defaultobject); | 1271 | for (tmp = comp->private->expandables; tmp; tmp = g_list_next (tmp)) { |
1272 | GST_DEBUG_OBJECT (comp, "Adding expandable %s sorted to the list", | ||
1273 | GST_OBJECT_NAME (tmp->data)); | ||
1274 | stack = g_list_insert_sorted (stack, tmp->data, | ||
1275 | (GCompareFunc) priority_comp); | ||
1276 | } | ||
1268 | 1277 | ||
1269 | /* convert that list to a stack */ | 1278 | /* convert that list to a stack */ |
1270 | tmp = stack; | 1279 | tmp = stack; |
@@ -1529,7 +1538,7 @@ update_start_stop_duration (GnlComposition * comp) | |||
1529 | } | 1538 | } |
1530 | 1539 | ||
1531 | /* If we have a default object, the start position is 0 */ | 1540 | /* If we have a default object, the start position is 0 */ |
1532 | if (comp->private->defaultobject) { | 1541 | if (comp->private->expandables) { |
1533 | GST_LOG_OBJECT (cobj, | 1542 | GST_LOG_OBJECT (cobj, |
1534 | "Setting start to 0 because we have a default object"); | 1543 | "Setting start to 0 because we have a default object"); |
1535 | if (cobj->start != 0) { | 1544 | if (cobj->start != 0) { |
@@ -1551,10 +1560,13 @@ update_start_stop_duration (GnlComposition * comp) | |||
1551 | if (obj->stop != cobj->stop) { | 1560 | if (obj->stop != cobj->stop) { |
1552 | GST_LOG_OBJECT (obj, "setting stop from %s to %" GST_TIME_FORMAT, | 1561 | GST_LOG_OBJECT (obj, "setting stop from %s to %" GST_TIME_FORMAT, |
1553 | GST_OBJECT_NAME (obj), GST_TIME_ARGS (obj->stop)); | 1562 | GST_OBJECT_NAME (obj), GST_TIME_ARGS (obj->stop)); |
1554 | if (comp->private->defaultobject) { | 1563 | if (comp->private->expandables) { |
1555 | g_object_set (comp->private->defaultobject, "duration", obj->stop, NULL); | 1564 | GList *tmp = comp->private->expandables; |
1556 | g_object_set (comp->private->defaultobject, "media-duration", obj->stop, | 1565 | while (tmp) { |
1557 | NULL); | 1566 | g_object_set (tmp->data, "duration", obj->stop, NULL); |
1567 | g_object_set (tmp->data, "media-duration", obj->stop, NULL); | ||
1568 | tmp = g_list_next (tmp); | ||
1569 | } | ||
1558 | } | 1570 | } |
1559 | comp->private->segment->stop = obj->stop; | 1571 | comp->private->segment->stop = obj->stop; |
1560 | cobj->stop = obj->stop; | 1572 | cobj->stop = obj->stop; |
@@ -1730,7 +1742,8 @@ compare_relink_single_node (GnlComposition * comp, GNode * node, | |||
1730 | guint nbchilds = g_node_n_children (node); | 1742 | guint nbchilds = g_node_n_children (node); |
1731 | GnlOperation *oper = (GnlOperation *) newobj; | 1743 | GnlOperation *oper = (GnlOperation *) newobj; |
1732 | 1744 | ||
1733 | GST_LOG_OBJECT (newobj, "is operation, analyzing the %d childs", nbchilds); | 1745 | GST_LOG_OBJECT (newobj, "is a %s operation, analyzing the %d childs", |
1746 | oper->dynamicsinks ? "dynamic" : "regular", nbchilds); | ||
1734 | if (oper->dynamicsinks) | 1747 | if (oper->dynamicsinks) |
1735 | g_object_set (G_OBJECT (newobj), "sinks", nbchilds, NULL); | 1748 | g_object_set (G_OBJECT (newobj), "sinks", nbchilds, NULL); |
1736 | for (child = node->children; child; child = child->next) | 1749 | for (child = node->children; child; child = child->next) |
@@ -2330,10 +2343,11 @@ gnl_composition_add_object (GstBin * bin, GstElement * element) | |||
2330 | 2343 | ||
2331 | COMP_OBJECTS_LOCK (comp); | 2344 | COMP_OBJECTS_LOCK (comp); |
2332 | 2345 | ||
2333 | if ((((GnlObject *) element)->priority == G_MAXUINT32) | 2346 | if (((((GnlObject *) element)->priority == G_MAXUINT32) || |
2334 | && comp->private->defaultobject) { | 2347 | GNL_OBJECT_IS_EXPANDABLE (element)) && |
2348 | g_list_find (comp->private->expandables, element)) { | ||
2335 | GST_WARNING_OBJECT (comp, | 2349 | GST_WARNING_OBJECT (comp, |
2336 | "We already have a default source, remove it before adding new one"); | 2350 | "We already have an expandable, remove it before adding new one"); |
2337 | ret = FALSE; | 2351 | ret = FALSE; |
2338 | goto chiringuito; | 2352 | goto chiringuito; |
2339 | } | 2353 | } |
@@ -2352,7 +2366,8 @@ gnl_composition_add_object (GstBin * bin, GstElement * element) | |||
2352 | /* wrap new element in a GnlCompositionEntry ... */ | 2366 | /* wrap new element in a GnlCompositionEntry ... */ |
2353 | entry = g_new0 (GnlCompositionEntry, 1); | 2367 | entry = g_new0 (GnlCompositionEntry, 1); |
2354 | entry->object = (GnlObject *) element; | 2368 | entry->object = (GnlObject *) element; |
2355 | if ((((GnlObject *) element)->priority != G_MAXUINT32)) { | 2369 | if (G_LIKELY ((((GnlObject *) element)->priority != G_MAXUINT32) && |
2370 | !GNL_OBJECT_IS_EXPANDABLE (element))) { | ||
2356 | /* Only react on non-default objects properties */ | 2371 | /* Only react on non-default objects properties */ |
2357 | entry->starthandler = g_signal_connect (G_OBJECT (element), | 2372 | entry->starthandler = g_signal_connect (G_OBJECT (element), |
2358 | "notify::start", G_CALLBACK (object_start_stop_priority_changed), comp); | 2373 | "notify::start", G_CALLBACK (object_start_stop_priority_changed), comp); |
@@ -2380,9 +2395,11 @@ gnl_composition_add_object (GstBin * bin, GstElement * element) | |||
2380 | g_hash_table_insert (comp->private->objects_hash, element, entry); | 2395 | g_hash_table_insert (comp->private->objects_hash, element, entry); |
2381 | 2396 | ||
2382 | /* Special case for default source. */ | 2397 | /* Special case for default source. */ |
2383 | if (((GnlObject *) element)->priority == G_MAXUINT32) { | 2398 | if ((((GnlObject *) element)->priority == G_MAXUINT32) || |
2399 | GNL_OBJECT_IS_EXPANDABLE (element)) { | ||
2384 | /* It doesn't get added to objects_start and objects_stop. */ | 2400 | /* It doesn't get added to objects_start and objects_stop. */ |
2385 | comp->private->defaultobject = ((GnlObject *) element); | 2401 | comp->private->expandables = g_list_prepend (comp->private->expandables, |
2402 | element); | ||
2386 | goto chiringuito; | 2403 | goto chiringuito; |
2387 | } | 2404 | } |
2388 | 2405 | ||
@@ -2470,8 +2487,11 @@ gnl_composition_remove_object (GstBin * bin, GstElement * element) | |||
2470 | gst_element_set_locked_state (element, FALSE); | 2487 | gst_element_set_locked_state (element, FALSE); |
2471 | 2488 | ||
2472 | /* handle default source */ | 2489 | /* handle default source */ |
2473 | if (((GnlObject *) element)->priority == G_MAXUINT32) { | 2490 | if ((((GnlObject *) element)->priority == G_MAXUINT32) || |
2474 | comp->private->defaultobject = NULL; | 2491 | GNL_OBJECT_IS_EXPANDABLE (element)) { |
2492 | /* Find it in the list */ | ||
2493 | comp->private->expandables = | ||
2494 | g_list_remove (comp->private->expandables, element); | ||
2475 | } else { | 2495 | } else { |
2476 | /* remove it from the objects list and resort the lists */ | 2496 | /* remove it from the objects list and resort the lists */ |
2477 | comp->private->objects_start = g_list_remove | 2497 | comp->private->objects_start = g_list_remove |
@@ -2487,7 +2507,8 @@ gnl_composition_remove_object (GstBin * bin, GstElement * element) | |||
2487 | goto chiringuito; | 2507 | goto chiringuito; |
2488 | 2508 | ||
2489 | update_required = OBJECT_IN_ACTIVE_SEGMENT (comp, element) || | 2509 | update_required = OBJECT_IN_ACTIVE_SEGMENT (comp, element) || |
2490 | ((GnlObject *) element)->priority == G_MAXUINT32; | 2510 | (((GnlObject *) element)->priority == G_MAXUINT32) || |
2511 | GNL_OBJECT_IS_EXPANDABLE (element); | ||
2491 | 2512 | ||
2492 | if (update_required && comp->private->can_update) { | 2513 | if (update_required && comp->private->can_update) { |
2493 | curpos = get_current_position (comp); | 2514 | curpos = get_current_position (comp); |
diff --git a/tests/check/complex.c b/tests/check/complex.c index 06eca9e..ae9db2a 100644 --- a/tests/check/complex.c +++ b/tests/check/complex.c | |||
@@ -442,6 +442,250 @@ GST_START_TEST (test_one_default_another) | |||
442 | 442 | ||
443 | GST_END_TEST; | 443 | GST_END_TEST; |
444 | 444 | ||
445 | GST_START_TEST (test_one_expandable_another) | ||
446 | { | ||
447 | GstElement *pipeline; | ||
448 | GstElement *comp, *sink, *source1, *source2, *source3, *defaultsrc; | ||
449 | CollectStructure *collect; | ||
450 | GstBus *bus; | ||
451 | GstMessage *message; | ||
452 | gboolean carry_on = TRUE; | ||
453 | guint64 start, stop; | ||
454 | gint64 duration; | ||
455 | GstPad *sinkpad; | ||
456 | |||
457 | pipeline = gst_pipeline_new ("test_pipeline"); | ||
458 | comp = | ||
459 | gst_element_factory_make_or_warn ("gnlcomposition", "test_composition"); | ||
460 | fail_if (comp == NULL); | ||
461 | |||
462 | /* | ||
463 | defaultsrc source | ||
464 | Start : 0s | ||
465 | Duration : 5s | ||
466 | Priority : 1000 | ||
467 | */ | ||
468 | |||
469 | defaultsrc = videotest_gnl_src ("defaultsrc", 0, 5 * GST_SECOND, 2, 1000); | ||
470 | g_object_set (defaultsrc, "expandable", TRUE, NULL); | ||
471 | fail_if (defaultsrc == NULL); | ||
472 | check_start_stop_duration (defaultsrc, 0, 5 * GST_SECOND, 5 * GST_SECOND); | ||
473 | |||
474 | /* | ||
475 | Source 1 | ||
476 | Start : 1s | ||
477 | Duration : 1s | ||
478 | Priority : 1 | ||
479 | */ | ||
480 | source1 = videotest_gnl_src ("source1", 1 * GST_SECOND, 1 * GST_SECOND, 1, 1); | ||
481 | fail_if (source1 == NULL); | ||
482 | check_start_stop_duration (source1, GST_SECOND, 2 * GST_SECOND, | ||
483 | 1 * GST_SECOND); | ||
484 | |||
485 | /* | ||
486 | Source 2 | ||
487 | Start : 3s | ||
488 | Duration : 1s | ||
489 | Priority : 1 | ||
490 | */ | ||
491 | source2 = videotest_gnl_src ("source2", 3 * GST_SECOND, 1 * GST_SECOND, 2, 1); | ||
492 | fail_if (source2 == NULL); | ||
493 | check_start_stop_duration (source2, 3 * GST_SECOND, 4 * GST_SECOND, | ||
494 | 1 * GST_SECOND); | ||
495 | |||
496 | /* | ||
497 | Source 3 | ||
498 | Start : 4s | ||
499 | Duration : 1s | ||
500 | Priority : 1 | ||
501 | */ | ||
502 | source3 = videotest_gnl_src ("source3", 4 * GST_SECOND, 1 * GST_SECOND, 2, 1); | ||
503 | fail_if (source3 == NULL); | ||
504 | check_start_stop_duration (source3, 4 * GST_SECOND, 5 * GST_SECOND, | ||
505 | 1 * GST_SECOND); | ||
506 | |||
507 | |||
508 | /* Add one source */ | ||
509 | |||
510 | gst_bin_add (GST_BIN (comp), source1); | ||
511 | check_start_stop_duration (comp, GST_SECOND, 2 * GST_SECOND, 1 * GST_SECOND); | ||
512 | |||
513 | ASSERT_OBJECT_REFCOUNT (source1, "source1", 1); | ||
514 | |||
515 | /* defaultsrc source */ | ||
516 | |||
517 | gst_bin_add (GST_BIN (comp), defaultsrc); | ||
518 | check_start_stop_duration (comp, 0, 2 * GST_SECOND, 2 * GST_SECOND); | ||
519 | check_start_stop_duration (defaultsrc, 0, 2 * GST_SECOND, 2 * GST_SECOND); | ||
520 | |||
521 | ASSERT_OBJECT_REFCOUNT (defaultsrc, "defaultsrc", 1); | ||
522 | |||
523 | /* Second source */ | ||
524 | |||
525 | gst_bin_add (GST_BIN (comp), source2); | ||
526 | check_start_stop_duration (comp, 0, 4 * GST_SECOND, 4 * GST_SECOND); | ||
527 | check_start_stop_duration (defaultsrc, 0, 4 * GST_SECOND, 4 * GST_SECOND); | ||
528 | |||
529 | ASSERT_OBJECT_REFCOUNT (source2, "source2", 1); | ||
530 | |||
531 | |||
532 | /* Third source */ | ||
533 | |||
534 | gst_bin_add (GST_BIN (comp), source3); | ||
535 | check_start_stop_duration (comp, 0, 5 * GST_SECOND, 5 * GST_SECOND); | ||
536 | check_start_stop_duration (defaultsrc, 0, 5 * GST_SECOND, 5 * GST_SECOND); | ||
537 | |||
538 | ASSERT_OBJECT_REFCOUNT (source3, "source3", 1); | ||
539 | |||
540 | |||
541 | sink = gst_element_factory_make_or_warn ("fakesink", "sink"); | ||
542 | fail_if (sink == NULL); | ||
543 | |||
544 | gst_bin_add_many (GST_BIN (pipeline), comp, sink, NULL); | ||
545 | |||
546 | /* Shared data */ | ||
547 | collect = g_new0 (CollectStructure, 1); | ||
548 | collect->comp = comp; | ||
549 | collect->sink = sink; | ||
550 | |||
551 | /* Expected segments */ | ||
552 | collect->expected_segments = g_list_append (collect->expected_segments, | ||
553 | segment_new (1.0, GST_FORMAT_TIME, 0, 1 * GST_SECOND, 0)); | ||
554 | collect->expected_segments = g_list_append (collect->expected_segments, | ||
555 | segment_new (1.0, GST_FORMAT_TIME, | ||
556 | 1 * GST_SECOND, 2 * GST_SECOND, 1 * GST_SECOND)); | ||
557 | collect->expected_segments = g_list_append (collect->expected_segments, | ||
558 | segment_new (1.0, GST_FORMAT_TIME, | ||
559 | 2 * GST_SECOND, 3 * GST_SECOND, 2 * GST_SECOND)); | ||
560 | collect->expected_segments = g_list_append (collect->expected_segments, | ||
561 | segment_new (1.0, GST_FORMAT_TIME, | ||
562 | 3 * GST_SECOND, 4 * GST_SECOND, 3 * GST_SECOND)); | ||
563 | collect->expected_segments = g_list_append (collect->expected_segments, | ||
564 | segment_new (1.0, GST_FORMAT_TIME, | ||
565 | 4 * GST_SECOND, 5 * GST_SECOND, 4 * GST_SECOND)); | ||
566 | |||
567 | g_signal_connect (G_OBJECT (comp), "pad-added", | ||
568 | G_CALLBACK (composition_pad_added_cb), collect); | ||
569 | |||
570 | sinkpad = gst_element_get_pad (sink, "sink"); | ||
571 | gst_pad_add_event_probe (sinkpad, G_CALLBACK (sinkpad_event_probe), collect); | ||
572 | gst_pad_add_buffer_probe (sinkpad, G_CALLBACK (sinkpad_buffer_probe), | ||
573 | collect); | ||
574 | |||
575 | bus = gst_element_get_bus (GST_ELEMENT (pipeline)); | ||
576 | |||
577 | GST_DEBUG ("Setting pipeline to PLAYING"); | ||
578 | ASSERT_OBJECT_REFCOUNT (source1, "source1", 1); | ||
579 | |||
580 | fail_if (gst_element_set_state (GST_ELEMENT (pipeline), | ||
581 | GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE); | ||
582 | |||
583 | GST_DEBUG ("Let's poll the bus"); | ||
584 | |||
585 | while (carry_on) { | ||
586 | message = gst_bus_poll (bus, GST_MESSAGE_ANY, GST_SECOND / 2); | ||
587 | if (message) { | ||
588 | switch (GST_MESSAGE_TYPE (message)) { | ||
589 | case GST_MESSAGE_EOS: | ||
590 | /* we should check if we really finished here */ | ||
591 | GST_WARNING ("Got an EOS"); | ||
592 | carry_on = FALSE; | ||
593 | break; | ||
594 | case GST_MESSAGE_SEGMENT_START: | ||
595 | case GST_MESSAGE_SEGMENT_DONE: | ||
596 | /* We shouldn't see any segement messages, since we didn't do a segment seek */ | ||
597 | GST_WARNING ("Saw a Segment start/stop"); | ||
598 | fail_if (TRUE); | ||
599 | break; | ||
600 | case GST_MESSAGE_ERROR: | ||
601 | GST_WARNING ("Saw an ERROR"); | ||
602 | fail_if (TRUE); | ||
603 | default: | ||
604 | break; | ||
605 | } | ||
606 | gst_mini_object_unref (GST_MINI_OBJECT (message)); | ||
607 | } | ||
608 | } | ||
609 | |||
610 | GST_DEBUG ("Setting pipeline to NULL"); | ||
611 | |||
612 | fail_if (gst_element_set_state (GST_ELEMENT (pipeline), | ||
613 | GST_STATE_READY) == GST_STATE_CHANGE_FAILURE); | ||
614 | |||
615 | fail_if (collect->expected_segments != NULL); | ||
616 | |||
617 | GST_DEBUG ("Resetted pipeline to READY"); | ||
618 | |||
619 | /* Expected segments */ | ||
620 | /* Expected segments */ | ||
621 | collect->expected_segments = g_list_append (collect->expected_segments, | ||
622 | segment_new (1.0, GST_FORMAT_TIME, 0, 1 * GST_SECOND, 0)); | ||
623 | collect->expected_segments = g_list_append (collect->expected_segments, | ||
624 | segment_new (1.0, GST_FORMAT_TIME, | ||
625 | 1 * GST_SECOND, 2 * GST_SECOND, 1 * GST_SECOND)); | ||
626 | collect->expected_segments = g_list_append (collect->expected_segments, | ||
627 | segment_new (1.0, GST_FORMAT_TIME, | ||
628 | 2 * GST_SECOND, 3 * GST_SECOND, 2 * GST_SECOND)); | ||
629 | collect->expected_segments = g_list_append (collect->expected_segments, | ||
630 | segment_new (1.0, GST_FORMAT_TIME, | ||
631 | 3 * GST_SECOND, 4 * GST_SECOND, 3 * GST_SECOND)); | ||
632 | collect->expected_segments = g_list_append (collect->expected_segments, | ||
633 | segment_new (1.0, GST_FORMAT_TIME, | ||
634 | 4 * GST_SECOND, 5 * GST_SECOND, 4 * GST_SECOND)); | ||
635 | collect->gotsegment = FALSE; | ||
636 | |||
637 | |||
638 | GST_DEBUG ("Setting pipeline to PLAYING again"); | ||
639 | |||
640 | fail_if (gst_element_set_state (GST_ELEMENT (pipeline), | ||
641 | GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE); | ||
642 | |||
643 | carry_on = TRUE; | ||
644 | |||
645 | GST_DEBUG ("Let's poll the bus"); | ||
646 | |||
647 | while (carry_on) { | ||
648 | message = gst_bus_poll (bus, GST_MESSAGE_ANY, GST_SECOND / 2); | ||
649 | if (message) { | ||
650 | switch (GST_MESSAGE_TYPE (message)) { | ||
651 | case GST_MESSAGE_EOS: | ||
652 | /* we should check if we really finished here */ | ||
653 | carry_on = FALSE; | ||
654 | break; | ||
655 | case GST_MESSAGE_SEGMENT_START: | ||
656 | case GST_MESSAGE_SEGMENT_DONE: | ||
657 | /* We shouldn't see any segement messages, since we didn't do a segment seek */ | ||
658 | GST_WARNING ("Saw a Segment start/stop"); | ||
659 | fail_if (TRUE); | ||
660 | break; | ||
661 | case GST_MESSAGE_ERROR: | ||
662 | GST_ERROR ("Saw an ERROR"); | ||
663 | fail_if (TRUE); | ||
664 | default: | ||
665 | break; | ||
666 | } | ||
667 | gst_mini_object_unref (GST_MINI_OBJECT (message)); | ||
668 | } else { | ||
669 | GST_DEBUG ("bus_poll responded, but there wasn't any message..."); | ||
670 | } | ||
671 | } | ||
672 | |||
673 | fail_if (collect->expected_segments != NULL); | ||
674 | |||
675 | fail_if (gst_element_set_state (GST_ELEMENT (pipeline), | ||
676 | GST_STATE_NULL) == GST_STATE_CHANGE_FAILURE); | ||
677 | |||
678 | gst_object_unref (GST_OBJECT (sinkpad)); | ||
679 | ASSERT_OBJECT_REFCOUNT_BETWEEN (pipeline, "main pipeline", 1, 2); | ||
680 | gst_object_unref (pipeline); | ||
681 | ASSERT_OBJECT_REFCOUNT_BETWEEN (bus, "main bus", 1, 2); | ||
682 | gst_object_unref (bus); | ||
683 | |||
684 | g_free (collect); | ||
685 | } | ||
686 | |||
687 | GST_END_TEST; | ||
688 | |||
445 | 689 | ||
446 | 690 | ||
447 | GST_START_TEST (test_renegotiation) | 691 | GST_START_TEST (test_renegotiation) |
@@ -934,6 +1178,7 @@ gnonlin_suite (void) | |||
934 | 1178 | ||
935 | tcase_add_test (tc_chain, test_one_space_another); | 1179 | tcase_add_test (tc_chain, test_one_space_another); |
936 | tcase_add_test (tc_chain, test_one_default_another); | 1180 | tcase_add_test (tc_chain, test_one_default_another); |
1181 | tcase_add_test (tc_chain, test_one_expandable_another); | ||
937 | tcase_add_test (tc_chain, test_renegotiation); | 1182 | tcase_add_test (tc_chain, test_renegotiation); |
938 | tcase_add_test (tc_chain, test_one_bin_space_another); | 1183 | tcase_add_test (tc_chain, test_one_bin_space_another); |
939 | tcase_add_test (tc_chain, test_one_above_another); | 1184 | tcase_add_test (tc_chain, test_one_above_another); |
diff --git a/tests/check/gnloperation.c b/tests/check/gnloperation.c index aa668f0..4e3b74f 100644 --- a/tests/check/gnloperation.c +++ b/tests/check/gnloperation.c | |||
@@ -655,6 +655,224 @@ GST_START_TEST (test_pyramid_operations2) | |||
655 | 655 | ||
656 | GST_END_TEST; | 656 | GST_END_TEST; |
657 | 657 | ||
658 | GST_START_TEST (test_pyramid_operations_expandable) | ||
659 | { | ||
660 | GstElement *pipeline; | ||
661 | guint64 start, stop; | ||
662 | gint64 duration; | ||
663 | GstElement *comp, *oper, *source1, *source2, *def, *sink; | ||
664 | CollectStructure *collect; | ||
665 | GstBus *bus; | ||
666 | GstMessage *message; | ||
667 | gboolean carry_on = TRUE; | ||
668 | GstPad *sinkpad; | ||
669 | |||
670 | pipeline = gst_pipeline_new ("test_pipeline"); | ||
671 | comp = | ||
672 | gst_element_factory_make_or_warn ("gnlcomposition", "test_composition"); | ||
673 | |||
674 | /* | ||
675 | source1 | ||
676 | Start : 0s | ||
677 | Duration : 2s | ||
678 | Priority : 2 | ||
679 | */ | ||
680 | |||
681 | source1 = videotest_gnl_src ("source1", 0, 2 * GST_SECOND, 1, 2); | ||
682 | check_start_stop_duration (source1, 0, 2 * GST_SECOND, 2 * GST_SECOND); | ||
683 | |||
684 | /* | ||
685 | operation (expandable) | ||
686 | Start : XX | ||
687 | Duration : XX | ||
688 | Priority : 1 | ||
689 | */ | ||
690 | |||
691 | oper = new_operation ("oper", "identity", 1 * GST_SECOND, 4 * GST_SECOND, 1); | ||
692 | g_object_set (oper, "expandable", TRUE, NULL); | ||
693 | check_start_stop_duration (oper, 1 * GST_SECOND, 5 * GST_SECOND, | ||
694 | 4 * GST_SECOND); | ||
695 | |||
696 | /* | ||
697 | source2 | ||
698 | Start : 4s | ||
699 | Duration : 2s | ||
700 | Priority : 2 | ||
701 | */ | ||
702 | |||
703 | source2 = videotest_gnl_src ("source2", 4 * GST_SECOND, 2 * GST_SECOND, 1, 2); | ||
704 | check_start_stop_duration (source2, 4 * GST_SECOND, 6 * GST_SECOND, | ||
705 | 2 * GST_SECOND); | ||
706 | |||
707 | /* | ||
708 | def (default source) | ||
709 | Priority = G_MAXUINT32 | ||
710 | */ | ||
711 | def = | ||
712 | videotest_gnl_src ("default", 0 * GST_SECOND, 0 * GST_SECOND, 1, | ||
713 | G_MAXUINT32); | ||
714 | |||
715 | ASSERT_OBJECT_REFCOUNT (source1, "source1", 1); | ||
716 | ASSERT_OBJECT_REFCOUNT (source2, "source2", 1); | ||
717 | ASSERT_OBJECT_REFCOUNT (oper, "oper", 1); | ||
718 | ASSERT_OBJECT_REFCOUNT (def, "default", 1); | ||
719 | |||
720 | /* Add source 1 */ | ||
721 | |||
722 | gst_bin_add (GST_BIN (comp), source1); | ||
723 | check_start_stop_duration (comp, 0, 2 * GST_SECOND, 2 * GST_SECOND); | ||
724 | |||
725 | /* Add source 2 */ | ||
726 | |||
727 | gst_bin_add (GST_BIN (comp), source2); | ||
728 | check_start_stop_duration (comp, 0, 6 * GST_SECOND, 6 * GST_SECOND); | ||
729 | |||
730 | /* Add operation */ | ||
731 | |||
732 | gst_bin_add (GST_BIN (comp), oper); | ||
733 | check_start_stop_duration (comp, 0, 6 * GST_SECOND, 6 * GST_SECOND); | ||
734 | |||
735 | /* Add default */ | ||
736 | |||
737 | gst_bin_add (GST_BIN (comp), def); | ||
738 | check_start_stop_duration (comp, 0, 6 * GST_SECOND, 6 * GST_SECOND); | ||
739 | |||
740 | |||
741 | |||
742 | sink = gst_element_factory_make_or_warn ("fakesink", "sink"); | ||
743 | gst_bin_add_many (GST_BIN (pipeline), comp, sink, NULL); | ||
744 | |||
745 | /* Shared data */ | ||
746 | collect = g_new0 (CollectStructure, 1); | ||
747 | collect->comp = comp; | ||
748 | collect->sink = sink; | ||
749 | |||
750 | /* Expected segments */ | ||
751 | collect->expected_segments = g_list_append (collect->expected_segments, | ||
752 | segment_new (1.0, GST_FORMAT_TIME, 0, 2 * GST_SECOND, 0)); | ||
753 | collect->expected_segments = g_list_append (collect->expected_segments, | ||
754 | segment_new (1.0, GST_FORMAT_TIME, | ||
755 | 2 * GST_SECOND, 4 * GST_SECOND, 2 * GST_SECOND)); | ||
756 | collect->expected_segments = g_list_append (collect->expected_segments, | ||
757 | segment_new (1.0, GST_FORMAT_TIME, | ||
758 | 4 * GST_SECOND, 6 * GST_SECOND, 4 * GST_SECOND)); | ||
759 | |||
760 | g_signal_connect (G_OBJECT (comp), "pad-added", | ||
761 | G_CALLBACK (composition_pad_added_cb), collect); | ||
762 | |||
763 | sinkpad = gst_element_get_pad (sink, "sink"); | ||
764 | gst_pad_add_event_probe (sinkpad, G_CALLBACK (sinkpad_event_probe), collect); | ||
765 | gst_pad_add_buffer_probe (sinkpad, G_CALLBACK (sinkpad_buffer_probe), | ||
766 | collect); | ||
767 | |||
768 | bus = gst_element_get_bus (GST_ELEMENT (pipeline)); | ||
769 | |||
770 | GST_DEBUG ("Setting pipeline to PLAYING"); | ||
771 | ASSERT_OBJECT_REFCOUNT (source1, "source1", 1); | ||
772 | |||
773 | fail_if (gst_element_set_state (GST_ELEMENT (pipeline), | ||
774 | GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE); | ||
775 | |||
776 | GST_DEBUG ("Let's poll the bus"); | ||
777 | |||
778 | while (carry_on) { | ||
779 | message = gst_bus_poll (bus, GST_MESSAGE_ANY, GST_SECOND / 2); | ||
780 | if (message) { | ||
781 | switch (GST_MESSAGE_TYPE (message)) { | ||
782 | case GST_MESSAGE_EOS: | ||
783 | /* we should check if we really finished here */ | ||
784 | GST_WARNING ("Got an EOS"); | ||
785 | carry_on = FALSE; | ||
786 | break; | ||
787 | case GST_MESSAGE_SEGMENT_START: | ||
788 | case GST_MESSAGE_SEGMENT_DONE: | ||
789 | /* We shouldn't see any segement messages, since we didn't do a segment seek */ | ||
790 | GST_WARNING ("Saw a Segment start/stop"); | ||
791 | fail_if (TRUE); | ||
792 | break; | ||
793 | case GST_MESSAGE_ERROR: | ||
794 | GST_WARNING ("Saw an ERROR"); | ||
795 | fail_if (TRUE); | ||
796 | default: | ||
797 | break; | ||
798 | } | ||
799 | gst_mini_object_unref (GST_MINI_OBJECT (message)); | ||
800 | } | ||
801 | } | ||
802 | |||
803 | GST_DEBUG ("Setting pipeline to NULL"); | ||
804 | |||
805 | fail_if (gst_element_set_state (GST_ELEMENT (pipeline), | ||
806 | GST_STATE_READY) == GST_STATE_CHANGE_FAILURE); | ||
807 | |||
808 | fail_if (collect->expected_segments != NULL); | ||
809 | |||
810 | GST_DEBUG ("Resetted pipeline to READY"); | ||
811 | |||
812 | /* Expected segments */ | ||
813 | collect->expected_segments = g_list_append (collect->expected_segments, | ||
814 | segment_new (1.0, GST_FORMAT_TIME, 0, 2 * GST_SECOND, 0)); | ||
815 | collect->expected_segments = g_list_append (collect->expected_segments, | ||
816 | segment_new (1.0, GST_FORMAT_TIME, | ||
817 | 2 * GST_SECOND, 4 * GST_SECOND, 2 * GST_SECOND)); | ||
818 | collect->expected_segments = g_list_append (collect->expected_segments, | ||
819 | segment_new (1.0, GST_FORMAT_TIME, | ||
820 | 4 * GST_SECOND, 6 * GST_SECOND, 4 * GST_SECOND)); | ||
821 | |||
822 | collect->gotsegment = FALSE; | ||
823 | |||
824 | |||
825 | GST_DEBUG ("Setting pipeline to PLAYING again"); | ||
826 | |||
827 | fail_if (gst_element_set_state (GST_ELEMENT (pipeline), | ||
828 | GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE); | ||
829 | |||
830 | carry_on = TRUE; | ||
831 | |||
832 | GST_DEBUG ("Let's poll the bus"); | ||
833 | |||
834 | while (carry_on) { | ||
835 | message = gst_bus_poll (bus, GST_MESSAGE_ANY, GST_SECOND / 2); | ||
836 | if (message) { | ||
837 | switch (GST_MESSAGE_TYPE (message)) { | ||
838 | case GST_MESSAGE_EOS: | ||
839 | /* we should check if we really finished here */ | ||
840 | carry_on = FALSE; | ||
841 | break; | ||
842 | case GST_MESSAGE_SEGMENT_START: | ||
843 | case GST_MESSAGE_SEGMENT_DONE: | ||
844 | /* We shouldn't see any segement messages, since we didn't do a segment seek */ | ||
845 | GST_WARNING ("Saw a Segment start/stop"); | ||
846 | fail_if (TRUE); | ||
847 | break; | ||
848 | case GST_MESSAGE_ERROR: | ||
849 | GST_ERROR ("Saw an ERROR"); | ||
850 | fail_if (TRUE); | ||
851 | default: | ||
852 | break; | ||
853 | } | ||
854 | gst_mini_object_unref (GST_MINI_OBJECT (message)); | ||
855 | } else { | ||
856 | GST_DEBUG ("bus_poll responded, but there wasn't any message..."); | ||
857 | } | ||
858 | } | ||
859 | |||
860 | fail_if (collect->expected_segments != NULL); | ||
861 | |||
862 | fail_if (gst_element_set_state (GST_ELEMENT (pipeline), | ||
863 | GST_STATE_NULL) == GST_STATE_CHANGE_FAILURE); | ||
864 | |||
865 | gst_object_unref (GST_OBJECT (sinkpad)); | ||
866 | ASSERT_OBJECT_REFCOUNT_BETWEEN (pipeline, "main pipeline", 1, 2); | ||
867 | gst_object_unref (pipeline); | ||
868 | ASSERT_OBJECT_REFCOUNT_BETWEEN (bus, "main bus", 1, 2); | ||
869 | gst_object_unref (bus); | ||
870 | |||
871 | g_free (collect); | ||
872 | } | ||
873 | |||
874 | GST_END_TEST; | ||
875 | |||
658 | 876 | ||
659 | 877 | ||
660 | 878 | ||
@@ -888,6 +1106,7 @@ gnonlin_suite (void) | |||
888 | tcase_add_test (tc_chain, test_simple_operation); | 1106 | tcase_add_test (tc_chain, test_simple_operation); |
889 | tcase_add_test (tc_chain, test_pyramid_operations); | 1107 | tcase_add_test (tc_chain, test_pyramid_operations); |
890 | tcase_add_test (tc_chain, test_pyramid_operations2); | 1108 | tcase_add_test (tc_chain, test_pyramid_operations2); |
1109 | tcase_add_test (tc_chain, test_pyramid_operations_expandable); | ||
891 | tcase_add_test (tc_chain, test_complex_operations); | 1110 | tcase_add_test (tc_chain, test_complex_operations); |
892 | 1111 | ||
893 | return s; | 1112 | return s; |