rpicamsrc: Add force-key-unit event support
authorVivia Nikolaidou <n.vivia@gmail.com>
Thu, 9 Oct 2014 20:38:41 +0000 (20:38 +0000)
committerTim-Philipp Müller <tim@centricular.com>
Fri, 10 Jul 2020 15:42:55 +0000 (16:42 +0100)
sys/rpicamsrc/RaspiCapture.c
sys/rpicamsrc/RaspiCapture.h
sys/rpicamsrc/gstrpicamsrc.c

index 797147f..3688ae4 100644 (file)
@@ -752,6 +752,21 @@ static void destroy_camera_component(RASPIVID_STATE *state)
    }
 }
 
+gboolean raspi_capture_request_i_frame(RASPIVID_STATE *state)
+{
+   MMAL_PORT_T *encoder_output = NULL;
+   MMAL_STATUS_T status;
+   MMAL_PARAMETER_BOOLEAN_T param = {{  MMAL_PARAMETER_VIDEO_REQUEST_I_FRAME, sizeof(param)}, 1};
+   encoder_output = state->encoder_component->output[0];
+   status = mmal_port_parameter_set(encoder_output, &param.hdr);
+   if (status != MMAL_SUCCESS)
+   {
+      vcos_log_error("Unable to request I-frame");
+      return FALSE;
+   }
+   return TRUE;
+}
+
 /**
  * Create the encoder component, set up its ports
  *
index 3c6dcf5..37a7ba7 100644 (file)
@@ -92,6 +92,7 @@ gboolean raspi_capture_start(RASPIVID_STATE *state);
 GstFlowReturn raspi_capture_fill_buffer(RASPIVID_STATE *state, GstBuffer **buf);
 void raspi_capture_stop(RASPIVID_STATE *state);
 void raspi_capture_free(RASPIVID_STATE *state);
+gboolean raspi_capture_request_i_frame(RASPIVID_STATE *state);
 
 G_END_DECLS
 
index 2900bb2..5d2d0c3 100644 (file)
@@ -181,6 +181,8 @@ static GstFlowReturn gst_rpi_cam_src_create (GstPushSrc * parent,
 static GstCaps *gst_rpi_cam_src_get_caps (GstBaseSrc * src, GstCaps * filter);
 static gboolean gst_rpi_cam_src_set_caps (GstBaseSrc * src, GstCaps * caps);
 static GstCaps *gst_rpi_cam_src_fixate (GstBaseSrc * basesrc, GstCaps * caps);
+static gboolean gst_rpi_cam_src_event (GstBaseSrc * src, GstEvent * event);
+static gboolean gst_rpi_cam_src_send_event (GstElement * element, GstEvent * event);
 
 static void
 gst_rpi_cam_src_class_init (GstRpiCamSrcClass * klass)
@@ -312,6 +314,8 @@ gst_rpi_cam_src_class_init (GstRpiCamSrcClass * klass)
   basesrc_class->get_caps = GST_DEBUG_FUNCPTR (gst_rpi_cam_src_get_caps);
   basesrc_class->set_caps = GST_DEBUG_FUNCPTR (gst_rpi_cam_src_set_caps);
   basesrc_class->fixate = GST_DEBUG_FUNCPTR (gst_rpi_cam_src_fixate);
+  basesrc_class->event = GST_DEBUG_FUNCPTR (gst_rpi_cam_src_event);
+  gstelement_class->send_event = GST_DEBUG_FUNCPTR (gst_rpi_cam_src_send_event);
   pushsrc_class->create = GST_DEBUG_FUNCPTR (gst_rpi_cam_src_create);
 
   raspicapture_init ();
@@ -532,6 +536,58 @@ gst_rpi_cam_src_stop (GstBaseSrc * parent)
   return TRUE;
 }
 
+static gboolean
+gst_rpi_cam_src_send_event (GstElement * parent, GstEvent * event)
+{
+  GstRpiCamSrc *src = GST_RPICAMSRC (parent);
+  gboolean ret;
+  switch (GST_EVENT_TYPE (event)) {
+    case GST_EVENT_CUSTOM_DOWNSTREAM:
+    case GST_EVENT_CUSTOM_UPSTREAM:
+      if (gst_video_event_is_force_key_unit (event)) {
+        if (src->started) {
+          ret = raspi_capture_request_i_frame (src->capture_state);
+        } else {
+          ret = FALSE;
+        }
+        gst_event_unref (event);
+      } else {
+        ret = GST_ELEMENT_CLASS (parent_class)->send_event(parent, event);
+      }
+      break;
+    default:
+     ret = GST_ELEMENT_CLASS (parent_class)->send_event(parent, event);
+     break;
+  }
+  return ret;
+}
+
+static gboolean
+gst_rpi_cam_src_event (GstBaseSrc * parent, GstEvent * event)
+{
+  GstRpiCamSrc *src = GST_RPICAMSRC (parent);
+  gboolean ret;
+  switch (GST_EVENT_TYPE (event)) {
+    case GST_EVENT_CUSTOM_DOWNSTREAM:
+    case GST_EVENT_CUSTOM_UPSTREAM:
+      if (gst_video_event_is_force_key_unit (event)) {
+        if (src->started) {
+          ret = raspi_capture_request_i_frame (src->capture_state);
+        } else {
+          ret = FALSE;
+        }
+        gst_event_unref (event);
+      } else {
+        ret = GST_BASE_SRC_CLASS (parent_class)->event(parent, event);
+      }
+      break;
+    default:
+     ret = GST_BASE_SRC_CLASS (parent_class)->event(parent, event);
+     break;
+  }
+  return ret;
+}
+
 static GstCaps *
 gst_rpi_cam_src_get_caps (GstBaseSrc * bsrc, GstCaps * filter)
 {