validate: Add live-related features to scenarios and medias
authorEdward Hervey <edward@centricular.com>
Thu, 25 May 2017 11:55:52 +0000 (13:55 +0200)
committerEdward Hervey <bilboed@bilboed.com>
Thu, 25 May 2017 12:04:00 +0000 (14:04 +0200)
Note: The notion of "live" here is in the *content* sense and not in the
GStreamer sense.
Ex:
  * A rtsp stream is always "live" in the GStreamer sense but might not always
    provide live content.
  * HLS/DASH streams are not "live" in the GStreamer sense but might
    provide "live" content.

Some scenarios might:
* require live content
* not be compatible with live content

This patch adds two new properties for scenarios:
* live_content_required (default False) for scenarios that can only work with
  live content.
* live_content_compatible (default False) for scenarios that can work with
  both live and non-live content.
This patch adds support for reading a "live" property from stream_info

validate/launcher/baseclasses.py

index 6f17bd5..04f32d0 100644 (file)
@@ -1675,6 +1675,21 @@ class Scenario(object):
 
         return False
 
+    def needs_live_content(self):
+        # Scenarios that can only be used on live content
+        if hasattr(self, "live_content_required"):
+            return bool(self.live_content_required)
+        return False
+
+    def compatible_with_live_content(self):
+        # if a live content is required it's implicitely compatible with
+        # live content
+        if self.needs_live_content():
+            return True
+        if hasattr(self, "live_content_compatible"):
+            return bool(self.live_content_compatible)
+        return False
+
     def get_min_media_duration(self):
         if hasattr(self, "min_media_duration"):
             return float(self.min_media_duration)
@@ -1874,6 +1889,9 @@ class MediaDescriptor(Loggable):
     def is_seekable(self):
         raise NotImplemented
 
+    def is_live(self):
+        raise NotImplemented
+
     def is_image(self):
         raise NotImplemented
 
@@ -1900,6 +1918,15 @@ class MediaDescriptor(Loggable):
         if not self.can_play_reverse() and scenario.does_reverse_playback():
             return False
 
+        if not self.is_live() and scenario.needs_live_content():
+            self.debug("Do not run %s as %s is not a live content",
+                       scenario, self.get_uri())
+            return False
+
+        if self.is_live() and not scenario.compatible_with_live_content():
+            self.debug("Do not run %s as %s is a live content", scenario, self.get_uri())
+            return False
+
         if self.get_duration() and self.get_duration() / GST_SECOND < scenario.get_min_media_duration():
             self.debug(
                 "Do not run %s as %s is too short (%i < min media duation : %i",
@@ -2038,6 +2065,9 @@ class GstValidateMediaDescriptor(MediaDescriptor):
     def is_seekable(self):
         return self.media_xml.attrib["seekable"].lower() == "true"
 
+    def is_live(self):
+        return self.media_xml.get("live", "false").lower() == "true"
+
     def can_play_reverse(self):
         return True