dvdspu: cache overlay composition
authorArnaud Vrac <avrac@freebox.fr>
Mon, 2 Sep 2013 15:48:50 +0000 (17:48 +0200)
committerJan Schmidt <jan@centricular.com>
Sat, 26 Sep 2015 13:22:44 +0000 (23:22 +1000)
This avoids rendering the overlay buffer for each video frame.

https://bugzilla.gnome.org/show_bug.cgi?id=663750

gst/dvdspu/gstdvdspu.c
gst/dvdspu/gstdvdspu.h

index 2bf5a91..cf0a63b 100644 (file)
@@ -180,6 +180,15 @@ gst_dvd_spu_init (GstDVDSpu * dvdspu)
 }
 
 static void
+gst_dvd_spu_reset_composition (GstDVDSpu * dvdspu)
+{
+  if (dvdspu->composition) {
+    gst_video_overlay_composition_unref (dvdspu->composition);
+    dvdspu->composition = NULL;
+  }
+}
+
+static void
 gst_dvd_spu_clear (GstDVDSpu * dvdspu)
 {
   gst_dvd_spu_flush_spu_info (dvdspu, FALSE);
@@ -269,6 +278,8 @@ gst_dvd_spu_flush_spu_info (GstDVDSpu * dvdspu, gboolean keep_events)
     default:
       break;
   }
+
+  gst_dvd_spu_reset_composition (dvdspu);
 }
 
 static gboolean
@@ -799,26 +810,27 @@ gstspu_render (GstDVDSpu * dvdspu, GstBuffer * buf)
   GstVideoOverlayComposition *composition;
   GstVideoFrame frame;
 
-  composition = gstspu_render_composition (dvdspu);
-  if (!composition)
-    return;
+  if (!dvdspu->composition) {
+    dvdspu->composition = gstspu_render_composition (dvdspu);
+    if (!dvdspu->composition)
+      return;
+  }
+
+  composition = dvdspu->composition;
 
   if (dvdspu->attach_compo_to_buffer) {
     gst_buffer_add_video_overlay_composition_meta (buf, composition);
-    goto done;
+    return;
   }
 
   if (!gst_video_frame_map (&frame, &dvdspu->spu_state.info, buf,
           GST_MAP_READWRITE)) {
     GST_WARNING_OBJECT (dvdspu, "failed to map video frame for blending");
-    goto done;
+    return;
   }
 
   gst_video_overlay_composition_blend (composition, &frame);
   gst_video_frame_unmap (&frame);
-
-done:
-  gst_video_overlay_composition_unref (composition);
 }
 
 /* With SPU LOCK */
@@ -887,6 +899,9 @@ gst_dvd_spu_handle_dvd_event (GstDVDSpu * dvdspu, GstEvent * event)
       break;
   }
 
+  if (hl_change)
+    gst_dvd_spu_reset_composition (dvdspu);
+
   if (hl_change && (dvdspu->spu_state.flags & SPU_STATE_STILL_FRAME)) {
     gst_dvd_spu_redraw_still (dvdspu, FALSE);
   }
@@ -940,6 +955,8 @@ gst_dvd_spu_advance_spu (GstDVDSpu * dvdspu, GstClockTime new_ts)
           GST_TIME_ARGS (dvdspu->video_seg.position),
           packet->buf ? "buffer" : "event");
 
+      gst_dvd_spu_reset_composition (dvdspu);
+
       if (packet->buf) {
         switch (dvdspu->spu_input_type) {
           case SPU_INPUT_TYPE_VOBSUB:
@@ -1051,6 +1068,8 @@ gst_dvd_spu_negotiate (GstDVDSpu * dvdspu)
   GstCaps *caps;
   gboolean attach = FALSE;
 
+  gst_dvd_spu_reset_composition (dvdspu);
+
   GST_DEBUG_OBJECT (dvdspu, "performing negotiation");
 
   caps = gst_pad_get_current_caps (dvdspu->srcpad);
index 0512082..6fa700c 100644 (file)
@@ -115,6 +115,7 @@ struct _GstDVDSpu {
 
   /* Overlay composition */
   gboolean attach_compo_to_buffer;
+  GstVideoOverlayComposition *composition;
 };
 
 struct _GstDVDSpuClass {