[longomatch] Add support to apply ROI when exporting to video



commit dda91c352615a6a414cc54829819d196ddf06fe3
Author: Josep Torra <n770galaxy gmail com>
Date:   Mon Apr 27 17:26:13 2015 +0200

    Add support to apply ROI when exporting to video

 libcesarplayer/gst-nle-source.c   |   71 +++++++++++++++++++++++++++++-------
 libcesarplayer/gst-nle-source.h   |   13 ++++++-
 libcesarplayer/gst-video-editor.c |    6 ++-
 3 files changed, 73 insertions(+), 17 deletions(-)
---
diff --git a/libcesarplayer/gst-nle-source.c b/libcesarplayer/gst-nle-source.c
index 665528e..c9a95e3 100644
--- a/libcesarplayer/gst-nle-source.c
+++ b/libcesarplayer/gst-nle-source.c
@@ -62,6 +62,7 @@ typedef struct
   guint64 duration;
   gfloat rate;
   gboolean still_picture;
+  GstNleRectangle roi;
 } GstNleSrcItem;
 
 static GstBinClass *parent_class = NULL;
@@ -80,7 +81,8 @@ G_DEFINE_TYPE (GstNleSource, gst_nle_source, GST_TYPE_BIN);
 
 static GstNleSrcItem *
 gst_nle_source_item_new (const gchar * file_path, const gchar * title,
-    guint64 start, guint64 stop, gfloat rate, gboolean still_picture)
+    guint64 start, guint64 stop, gfloat rate, gboolean still_picture,
+    GstNleRectangle roi)
 {
   GstNleSrcItem *item;
 
@@ -94,6 +96,7 @@ gst_nle_source_item_new (const gchar * file_path, const gchar * title,
   if (still_picture) {
     item->rate = 1;
   }
+  item->roi = roi;
   item->duration = stop - start;
   return item;
 }
@@ -185,6 +188,7 @@ gst_nle_source_setup (GstNleSource * nlesrc)
 
   nlesrc->video_appsrc = gst_element_factory_make ("appsrc", NULL);
   videorate = gst_element_factory_make ("videorate", NULL);
+  nlesrc->videocrop = gst_element_factory_make ("videocrop", NULL);
   videoscale = gst_element_factory_make ("videoscale", NULL);
   colorspace = gst_element_factory_make ("ffmpegcolorspace", NULL);
   v_capsfilter = gst_element_factory_make ("capsfilter", NULL);
@@ -209,9 +213,10 @@ gst_nle_source_setup (GstNleSource * nlesrc)
       NULL);
 
   gst_bin_add_many (GST_BIN (nlesrc), nlesrc->video_appsrc, videorate,
+      nlesrc->videocrop, videoscale, colorspace, v_capsfilter,
+      nlesrc->textoverlay, vident, NULL);
+  gst_element_link_many (nlesrc->video_appsrc, videorate, nlesrc->videocrop,
       videoscale, colorspace, v_capsfilter, nlesrc->textoverlay, vident, NULL);
-  gst_element_link_many (nlesrc->video_appsrc, videorate, videoscale,
-      colorspace, v_capsfilter, nlesrc->textoverlay, vident, NULL);
 
   v_pad = gst_element_get_pad (vident, "src");
   gst_ghost_pad_set_target (GST_GHOST_PAD (nlesrc->video_pad), v_pad);
@@ -273,6 +278,36 @@ gst_nle_source_update_overlay_title (GstNleSource * nlesrc)
   }
 }
 
+static void
+gst_nle_source_update_videocrop (GstNleSource * nlesrc, GstCaps * caps)
+{
+  GstNleSrcItem *item;
+  gint left, right, top, bottom;
+
+  left = right = top = bottom = 0;
+
+  item = (GstNleSrcItem *) g_list_nth_data (nlesrc->queue, nlesrc->index);
+
+  if (item->roi.width && item->roi.height) {
+    GstStructure *structure;
+    gint vwidth = 0, vheight = 0;
+
+    structure = gst_caps_get_structure (caps, 0);
+
+    if (gst_structure_get_int (structure, "width", &vwidth) &&
+             gst_structure_get_int (structure, "height", &vheight)) {
+      left = item->roi.x;
+      top = item->roi.y;
+      right = vwidth - item->roi.x - item->roi.width;
+      bottom = vheight - item->roi.y - item->roi.height;
+    }
+  }
+
+  g_object_set (G_OBJECT (nlesrc->videocrop), "left", left, "right", right,
+      "top", top, "bottom", bottom, NULL);
+  nlesrc->roi_setup = TRUE;
+}
+
 static GstFlowReturn
 gst_nle_source_push_buffer (GstNleSource * nlesrc, GstBuffer * buf,
     gboolean is_audio)
@@ -484,17 +519,24 @@ gst_nle_source_on_audio_eos (GstAppSink * appsink, gpointer data)
 }
 
 static gboolean
-gst_nle_source_video_pad_probe_cb (GstPad * pad, GstEvent * event,
+gst_nle_source_video_pad_probe_cb (GstPad * pad,  GstMiniObject * obj,
     GstNleSource * nlesrc)
 {
-  if (event->type == GST_EVENT_NEWSEGMENT) {
-    g_mutex_lock (&nlesrc->stream_lock);
-    if (!nlesrc->video_seek_done && nlesrc->seek_done) {
-      GST_DEBUG_OBJECT (nlesrc, "NEWSEGMENT on the video pad");
-      nlesrc->video_seek_done = TRUE;
-      gst_nle_source_update_overlay_title (nlesrc);
+  if (GST_IS_EVENT (obj)) {
+    GstEvent *event = GST_EVENT_CAST (obj);
+    if (event->type == GST_EVENT_NEWSEGMENT) {
+      g_mutex_lock (&nlesrc->stream_lock);
+      if (!nlesrc->video_seek_done && nlesrc->seek_done) {
+        GST_DEBUG_OBJECT (nlesrc, "NEWSEGMENT on the video pad");
+        nlesrc->video_seek_done = TRUE;
+        nlesrc->roi_setup = FALSE;
+        gst_nle_source_update_overlay_title (nlesrc);
+      }
+      g_mutex_unlock (&nlesrc->stream_lock);
     }
-    g_mutex_unlock (&nlesrc->stream_lock);
+  } else if (!nlesrc->roi_setup && GST_IS_BUFFER (obj)) {
+    GstBuffer * buffer = GST_BUFFER_CAST (obj);
+    gst_nle_source_update_videocrop (nlesrc, GST_BUFFER_CAPS (buffer));
   }
   return TRUE;
 }
@@ -545,7 +587,7 @@ gst_nle_source_pad_added_cb (GstElement * element, GstPad * pad,
       gst_element_add_pad (GST_ELEMENT (nlesrc), nlesrc->video_pad);
       nlesrc->video_pad_added = TRUE;
     }
-    gst_pad_add_event_probe (GST_BASE_SINK_PAD (GST_BASE_SINK (appsink)),
+    gst_pad_add_data_probe (GST_BASE_SINK_PAD (GST_BASE_SINK (appsink)),
         (GCallback) gst_nle_source_video_pad_probe_cb, nlesrc);
     nlesrc->video_eos = FALSE;
   } else if (g_strrstr (mime, "audio") && nlesrc->with_audio
@@ -727,13 +769,14 @@ gst_nle_source_change_state (GstElement * element, GstStateChange transition)
 void
 gst_nle_source_add_item (GstNleSource * nlesrc, const gchar * file_path,
     const gchar * title, guint64 start, guint64 stop, gfloat rate,
-    gboolean still_picture)
+    gboolean still_picture, GstNleRectangle roi)
 {
   GstNleSrcItem *item;
   gchar *uri;
 
   uri = lgm_filename_to_uri (file_path);
-  item = gst_nle_source_item_new (uri, title, start, stop, rate, still_picture);
+  item = gst_nle_source_item_new (uri, title, start, stop, rate, still_picture,
+      roi);
   g_free (uri);
   nlesrc->queue = g_list_append (nlesrc->queue, item);
 
diff --git a/libcesarplayer/gst-nle-source.h b/libcesarplayer/gst-nle-source.h
index 4cdaabe..e1e956e 100644
--- a/libcesarplayer/gst-nle-source.h
+++ b/libcesarplayer/gst-nle-source.h
@@ -65,6 +65,7 @@ struct _GstNleSource
   GstPad *audio_pad;
   GstElement *video_appsrc;
   GstElement *audio_appsrc;
+  GstElement *videocrop;
   GstElement *textoverlay;
   gboolean video_linked;
   gboolean audio_linked;
@@ -82,6 +83,7 @@ struct _GstNleSource
   gboolean video_seek_done;
   gboolean audio_eos;
   gboolean video_eos;
+  gboolean roi_setup;
 
   GMutex stream_lock;
 
@@ -89,6 +91,14 @@ struct _GstNleSource
   gint index;
 };
 
+typedef struct
+{
+  guint x;
+  guint y;
+  guint width;
+  guint height;
+} GstNleRectangle;
+
 EXPORT GType gst_nle_source_get_type (void) G_GNUC_CONST;
 
 EXPORT GstNleSource *gst_nle_source_new (void);
@@ -106,7 +116,8 @@ EXPORT void gst_nle_source_add_item   (GstNleSource *nlesrc,
                                        guint64 start,
                                        guint64 stop,
                                        gfloat rate,
-                                       gboolean still_picture
+                                       gboolean still_picturie,
+                                       GstNleRectangle roi
                                      );
 G_END_DECLS
 #endif /* _GST_NLE_SOURCE_H_ */
diff --git a/libcesarplayer/gst-video-editor.c b/libcesarplayer/gst-video-editor.c
index bc57d9e..89b13ff 100644
--- a/libcesarplayer/gst-video-editor.c
+++ b/libcesarplayer/gst-video-editor.c
@@ -502,6 +502,7 @@ gst_video_editor_add_segment (GstVideoEditor * gve, gchar * file,
     guint roi_x, guint roi_y, guint roi_w, guint roi_h)
 {
   GstState cur_state;
+  GstNleRectangle roi = { roi_x, roi_y, roi_w, roi_h };
 
   g_return_if_fail (GST_IS_VIDEO_EDITOR (gve));
 
@@ -515,7 +516,7 @@ gst_video_editor_add_segment (GstVideoEditor * gve, gchar * file,
   start = start * GST_MSECOND;
 
   gst_nle_source_add_item (gve->priv->nle_source, file, title, start,
-      start + duration, rate, FALSE);
+      start + duration, rate, FALSE, roi);
 
   GST_INFO ("New segment: start={%" GST_TIME_FORMAT "} duration={%"
       GST_TIME_FORMAT "} ", GST_TIME_ARGS (gve->priv->duration),
@@ -530,6 +531,7 @@ gst_video_editor_add_image_segment (GstVideoEditor * gve, gchar * file,
     guint roi_x, guint roi_y, guint roi_w, guint roi_h)
 {
   GstState cur_state;
+  GstNleRectangle roi = { roi_x, roi_y, roi_w, roi_h };
 
   g_return_if_fail (GST_IS_VIDEO_EDITOR (gve));
 
@@ -543,7 +545,7 @@ gst_video_editor_add_image_segment (GstVideoEditor * gve, gchar * file,
   start = start * GST_MSECOND;
 
   gst_nle_source_add_item (gve->priv->nle_source, file, title, start,
-      start + duration, 1, TRUE);
+      start + duration, 1, TRUE, roi);
 
   GST_INFO ("New segment: start={%" GST_TIME_FORMAT "} duration={%"
       GST_TIME_FORMAT "} ", GST_TIME_ARGS (gve->priv->duration),


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]