rtph264depay: expose request-keyframe property
authorMathieu Duponchelle <mathieu@centricular.com>
Wed, 9 Dec 2020 00:40:45 +0000 (01:40 +0100)
committerGStreamer Merge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Thu, 18 Feb 2021 01:54:03 +0000 (01:54 +0000)
When set, the depayloader will request new keyframes on packet
loss

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-good/-/merge_requests/834>

gst/rtp/gstrtph264depay.c
gst/rtp/gstrtph264depay.h

index 41ba21d..9194026 100644 (file)
@@ -39,11 +39,13 @@ GST_DEBUG_CATEGORY_STATIC (rtph264depay_debug);
 #define DEFAULT_BYTE_STREAM   TRUE
 #define DEFAULT_ACCESS_UNIT   FALSE
 #define DEFAULT_WAIT_FOR_KEYFRAME FALSE
+#define DEFAULT_REQUEST_KEYFRAME FALSE
 
 enum
 {
   PROP_0,
-  PROP_WAIT_FOR_KEYFRAME
+  PROP_WAIT_FOR_KEYFRAME,
+  PROP_REQUEST_KEYFRAME,
 };
 
 
@@ -117,6 +119,9 @@ gst_rtp_h264_depay_set_property (GObject * object, guint prop_id,
     case PROP_WAIT_FOR_KEYFRAME:
       self->wait_for_keyframe = g_value_get_boolean (value);
       break;
+    case PROP_REQUEST_KEYFRAME:
+      self->request_keyframe = g_value_get_boolean (value);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -133,6 +138,9 @@ gst_rtp_h264_depay_get_property (GObject * object, guint prop_id,
     case PROP_WAIT_FOR_KEYFRAME:
       g_value_set_boolean (value, self->wait_for_keyframe);
       break;
+    case PROP_REQUEST_KEYFRAME:
+      g_value_set_boolean (value, self->request_keyframe);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -169,6 +177,19 @@ gst_rtp_h264_depay_class_init (GstRtpH264DepayClass * klass)
           DEFAULT_WAIT_FOR_KEYFRAME,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
+  /**
+   * GstRtpH264Depay:request-keyframe:
+   *
+   * Request new keyframe when packet loss is detected
+   *
+   * Since: 1.20
+   */
+  g_object_class_install_property (gobject_class, PROP_REQUEST_KEYFRAME,
+      g_param_spec_boolean ("request-keyframe", "Request Keyframe",
+          "Request new keyframe when packet loss is detected",
+          DEFAULT_REQUEST_KEYFRAME,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
   gst_element_class_add_static_pad_template (gstelement_class,
       &gst_rtp_h264_depay_src_template);
   gst_element_class_add_static_pad_template (gstelement_class,
@@ -197,6 +218,7 @@ gst_rtp_h264_depay_init (GstRtpH264Depay * rtph264depay)
   rtph264depay->pps = g_ptr_array_new_with_free_func (
       (GDestroyNotify) gst_buffer_unref);
   rtph264depay->wait_for_keyframe = DEFAULT_WAIT_FOR_KEYFRAME;
+  rtph264depay->request_keyframe = DEFAULT_REQUEST_KEYFRAME;
 }
 
 static void
@@ -1138,6 +1160,12 @@ gst_rtp_h264_depay_process (GstRTPBaseDepayload * depayload, GstRTPBuffer * rtp)
     if (rtph264depay->merge && rtph264depay->wait_for_keyframe) {
       rtph264depay->waiting_for_keyframe = TRUE;
     }
+
+
+    if (rtph264depay->request_keyframe)
+      gst_pad_push_event (GST_RTP_BASE_DEPAYLOAD_SINKPAD (depayload),
+          gst_video_event_new_upstream_force_key_unit (GST_CLOCK_TIME_NONE,
+              TRUE, 0));
   }
 
   {
index 27818e6..2805841 100644 (file)
@@ -73,6 +73,7 @@ struct _GstRtpH264Depay
   GstAllocationParams params;
 
   gboolean wait_for_keyframe;
+  gboolean request_keyframe;
   gboolean waiting_for_keyframe;
 };