[longomatch] Fix memory leak with unmanaged Pixbuf
- From: Andoni Morales Alastruey <amorales src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [longomatch] Fix memory leak with unmanaged Pixbuf
- Date: Mon, 14 Sep 2009 22:58:51 +0000 (UTC)
commit d9cd83954fc38cf378c46ba56ea4fcbcf32c83a8
Author: Andoni Morales Alastruey <ylatuya gmail com>
Date: Sun Sep 13 22:01:46 2009 +0200
Fix memory leak with unmanaged Pixbuf
CesarPlayer/Gui/PlayerBin.cs | 12 ++-----
CesarPlayer/Player/GstPlayer.cs | 35 +++++++++++++++++----
CesarPlayer/Player/IPlayer.cs | 10 +++---
CesarPlayer/Utils/FramesCapturer.cs | 18 +++++++++--
CesarPlayer/Utils/IFramesCapturer.cs | 6 ++--
CesarPlayer/Utils/PreviewMediaFile.cs | 18 +++++------
LongoMatch/Gui/FramesCaptureProgressDialog.cs | 14 ++------
LongoMatch/Handlers/EventsManager.cs | 2 +-
LongoMatch/Time/PixbufTimeNode.cs | 4 ++-
libcesarplayer/src/bacon-video-widget-gst-0.10.c | 5 +++
libcesarplayer/src/bacon-video-widget.h | 1 +
11 files changed, 76 insertions(+), 49 deletions(-)
---
diff --git a/CesarPlayer/Gui/PlayerBin.cs b/CesarPlayer/Gui/PlayerBin.cs
index b3e74ba..8eddc12 100644
--- a/CesarPlayer/Gui/PlayerBin.cs
+++ b/CesarPlayer/Gui/PlayerBin.cs
@@ -108,15 +108,9 @@ namespace LongoMatch.Gui
public Pixbuf CurrentFrame{
get{
- int h,w;
- double rate;
- Pixbuf pixbuf = player.CurrentFrame;
- if (pixbuf != null){
- h = pixbuf.Height;
- w = pixbuf.Width;
- rate = (double)w/(double)h;
- return pixbuf.ScaleSimple(THUMBNAIL_WIDTH,(int)(THUMBNAIL_WIDTH/rate),InterpType.Bilinear);
- }
+ Pixbuf pixbuf = player.GetCurrentFrame(50,50);
+ if (pixbuf != null)
+ return pixbuf;
else return null;
}
}
diff --git a/CesarPlayer/Player/GstPlayer.cs b/CesarPlayer/Player/GstPlayer.cs
index 2c3444b..18e320e 100644
--- a/CesarPlayer/Player/GstPlayer.cs
+++ b/CesarPlayer/Player/GstPlayer.cs
@@ -1099,13 +1099,34 @@ namespace LongoMatch.Video.Player {
[DllImport("libcesarplayer.dll")]
static extern IntPtr bacon_video_widget_get_current_frame(IntPtr raw);
-
- public Gdk.Pixbuf CurrentFrame {
- get {
- IntPtr raw_ret = bacon_video_widget_get_current_frame(Handle);
- Gdk.Pixbuf ret = GLib.Object.GetObject(raw_ret) as Gdk.Pixbuf;
- return ret;
- }
+
+ [DllImport("libcesarplayer.dll")]
+ static extern IntPtr bacon_video_widget_unref_pixbuf(IntPtr raw);
+
+
+ public Gdk.Pixbuf GetCurrentFrame(int outwidth, int outheight) {
+ IntPtr raw_ret = bacon_video_widget_get_current_frame(Handle);
+ Gdk.Pixbuf unmanaged = GLib.Object.GetObject(raw_ret) as Gdk.Pixbuf;
+ Gdk.Pixbuf managed;
+ int h = unmanaged.Height;
+ int w = unmanaged.Width;
+ double rate = (double)w/(double)h;
+ if (outwidth == -1 || outheight == -1){
+ outwidth = w;
+ outheight = h;
+ }else if (h>w){
+ outwidth = (int)(outheight*rate);
+ }else{
+ outheight = (int)(outwidth/rate);
+ }
+ managed = unmanaged.ScaleSimple(outwidth,outheight,Gdk.InterpType.Bilinear);
+ unmanaged.Dispose();
+ bacon_video_widget_unref_pixbuf(raw_ret);
+ return managed;
+ }
+
+ public Gdk.Pixbuf GetCurrentFrame() {
+ return GetCurrentFrame(-1,-1);
}
[DllImport("libcesarplayer.dll")]
diff --git a/CesarPlayer/Player/IPlayer.cs b/CesarPlayer/Player/IPlayer.cs
index a989b8b..f25f349 100644
--- a/CesarPlayer/Player/IPlayer.cs
+++ b/CesarPlayer/Player/IPlayer.cs
@@ -73,11 +73,7 @@ namespace LongoMatch.Video.Player
bool Playing {
get;
}
-
- Pixbuf CurrentFrame{
- get;
- }
-
+
string Logo {
set;
}
@@ -123,6 +119,10 @@ namespace LongoMatch.Video.Player
bool SeekToPreviousFrame(float rate,bool in_segment);
+ Pixbuf GetCurrentFrame(int outwidth, int outheight);
+
+ Pixbuf GetCurrentFrame();
+
void CancelProgramedStop();
}
diff --git a/CesarPlayer/Utils/FramesCapturer.cs b/CesarPlayer/Utils/FramesCapturer.cs
index 6a3437a..0a9e30c 100644
--- a/CesarPlayer/Utils/FramesCapturer.cs
+++ b/CesarPlayer/Utils/FramesCapturer.cs
@@ -40,6 +40,8 @@ namespace LongoMatch.Video.Utils
string seriesName;
string outputDir;
bool cancel;
+ private const int THUMBNAIL_MAX_HEIGHT=250;
+ private const int THUMBNAIL_MAX_WIDTH=300;
public event FramesProgressHandler Progress;
@@ -68,6 +70,7 @@ namespace LongoMatch.Video.Utils
public void CaptureFrames(){
long pos;
Pixbuf frame;
+ Pixbuf scaledFrame=null;
int i = 0;
System.IO.Directory.CreateDirectory(outputDir);
@@ -79,12 +82,21 @@ namespace LongoMatch.Video.Utils
if (!cancel){
capturer.SeekTime(pos,true);
capturer.Pause();
- frame = capturer.CurrentFrame;
+ frame = capturer.GetCurrentFrame();
if (frame != null) {
frame.Save(System.IO.Path.Combine(outputDir,seriesName+"_" + i +".png"),"png");
- }
+ int h = frame.Height;
+ int w = frame.Width;
+ double rate = (double)w/(double)h;
+ if (h>w)
+ scaledFrame = frame.ScaleSimple((int)(THUMBNAIL_MAX_HEIGHT*rate),THUMBNAIL_MAX_HEIGHT,InterpType.Bilinear);
+ else
+ scaledFrame = frame.ScaleSimple(THUMBNAIL_MAX_WIDTH,(int)(THUMBNAIL_MAX_WIDTH/rate),InterpType.Bilinear);
+ frame.Dispose();
+ }
+
if (Progress != null)
- Application.Invoke(delegate {Progress(i+1,totalFrames,frame);});
+ Application.Invoke(delegate {Progress(i+1,totalFrames,scaledFrame);});
pos += interval;
i++;
}
diff --git a/CesarPlayer/Utils/IFramesCapturer.cs b/CesarPlayer/Utils/IFramesCapturer.cs
index 545da0b..fec5eaf 100644
--- a/CesarPlayer/Utils/IFramesCapturer.cs
+++ b/CesarPlayer/Utils/IFramesCapturer.cs
@@ -31,8 +31,8 @@ namespace LongoMatch.Video.Utils
bool SeekTime(long time, bool accurate);
void Pause();
void Dispose();
- Pixbuf CurrentFrame{
- get;
- }
+ Pixbuf GetCurrentFrame(int outwidth, int outheight);
+ Pixbuf GetCurrentFrame();
+
}
}
diff --git a/CesarPlayer/Utils/PreviewMediaFile.cs b/CesarPlayer/Utils/PreviewMediaFile.cs
index 021b5ea..754aa23 100644
--- a/CesarPlayer/Utils/PreviewMediaFile.cs
+++ b/CesarPlayer/Utils/PreviewMediaFile.cs
@@ -58,15 +58,9 @@ namespace LongoMatch.Video.Utils
}
set{
if (value != null){
- int h = value.Height;
- int w = value.Width;
- double ratio = (double)w/(double)h;
- if (h>w)
- thumbnailBuf = value.ScaleSimple((int)(THUMBNAIL_MAX_HEIGHT*ratio),THUMBNAIL_MAX_HEIGHT,InterpType.Bilinear).SaveToBuffer("png");
- else
- thumbnailBuf = value.ScaleSimple(THUMBNAIL_MAX_WIDTH,(int)(THUMBNAIL_MAX_WIDTH/ratio),InterpType.Bilinear).SaveToBuffer("png");
+ thumbnailBuf = value.SaveToBuffer("png");
+ value.Dispose();
}
-
else thumbnailBuf = null;
}
}
@@ -101,7 +95,7 @@ namespace LongoMatch.Video.Utils
thumbnailer = factory.getFramesCapturer();
thumbnailer.Open(filePath);
thumbnailer.SeekTime(1000,false);
- preview = thumbnailer.CurrentFrame;
+ preview = thumbnailer.GetCurrentFrame(THUMBNAIL_MAX_WIDTH,THUMBNAIL_MAX_HEIGHT);
thumbnailer.Dispose();
}
height = (int) reader.GetMetadata(GstMetadataType.DimensionY);
@@ -109,7 +103,11 @@ namespace LongoMatch.Video.Utils
reader.Close();
reader.Dispose();
- return new PreviewMediaFile(filePath,duration*1000,(ushort)fps,hasAudio,hasVideo,videoCodec,audioCodec,(uint)height,(uint)width,preview);
+ return new PreviewMediaFile(filePath,duration*1000,
+ (ushort)fps,hasAudio,
+ hasVideo,videoCodec,
+ audioCodec,(uint)height,
+ (uint)width,preview);
}
catch (GLib.GException ex){
throw new Exception (Catalog.GetString("Invalid video file:")+"\n"+ex.Message);
diff --git a/LongoMatch/Gui/FramesCaptureProgressDialog.cs b/LongoMatch/Gui/FramesCaptureProgressDialog.cs
index d4be61f..aec1fba 100644
--- a/LongoMatch/Gui/FramesCaptureProgressDialog.cs
+++ b/LongoMatch/Gui/FramesCaptureProgressDialog.cs
@@ -32,9 +32,7 @@ namespace LongoMatch.Gui.Dialog
[System.ComponentModel.ToolboxItem(false)]
public partial class FramesCaptureProgressDialog : Gtk.Dialog
{
- private FramesSeriesCapturer capturer;
- private const int THUMBNAIL_MAX_HEIGHT=250;
- private const int THUMBNAIL_MAX_WIDTH=300;
+ private FramesSeriesCapturer capturer;
public FramesCaptureProgressDialog(FramesSeriesCapturer capturer)
{
@@ -50,13 +48,9 @@ namespace LongoMatch.Gui.Dialog
progressbar.Text= Catalog.GetString("Capturing frame: ")+actual+"/"+total;
progressbar.Fraction = (double)actual/(double)total;
if (frame != null){
- int h = frame.Height;
- int w = frame.Width;
- double rate = (double)w/(double)h;
- if (h>w)
- image.Pixbuf = frame.ScaleSimple((int)(THUMBNAIL_MAX_HEIGHT*rate),THUMBNAIL_MAX_HEIGHT,InterpType.Bilinear);
- else
- image.Pixbuf = frame.ScaleSimple(THUMBNAIL_MAX_WIDTH,(int)(THUMBNAIL_MAX_WIDTH/rate),InterpType.Bilinear);
+ if (image.Pixbuf != null)
+ image.Pixbuf.Dispose();
+ image.Pixbuf = frame;
}
}
if (actual == total){
diff --git a/LongoMatch/Handlers/EventsManager.cs b/LongoMatch/Handlers/EventsManager.cs
index bc977b1..b9b3d3c 100644
--- a/LongoMatch/Handlers/EventsManager.cs
+++ b/LongoMatch/Handlers/EventsManager.cs
@@ -134,7 +134,7 @@ namespace LongoMatch
Time fStop = (stop > length) ? length: stop;
Pixbuf miniature = player.CurrentFrame;
- MediaTimeNode tn = openedProject.AddTimeNode(section,fStart, fStop,miniature);
+ MediaTimeNode tn = openedProject.AddTimeNode(section,fStart, fStop,miniature);
treewidget.AddTimeNode(tn,section);
timeline.QueueDraw();
}
diff --git a/LongoMatch/Time/PixbufTimeNode.cs b/LongoMatch/Time/PixbufTimeNode.cs
index d465b3a..2c627b7 100644
--- a/LongoMatch/Time/PixbufTimeNode.cs
+++ b/LongoMatch/Time/PixbufTimeNode.cs
@@ -35,8 +35,10 @@ namespace LongoMatch.TimeNodes
public PixbufTimeNode(string name, Time start, Time stop, Pixbuf thumbnail): base (name,start,stop)
{
- if (thumbnail != null)
+ if (thumbnail != null){
this.thumbnailBuf = thumbnail.SaveToBuffer("png");
+ thumbnail.Dispose();
+ }
else thumbnailBuf = null;
}
#endregion
diff --git a/libcesarplayer/src/bacon-video-widget-gst-0.10.c b/libcesarplayer/src/bacon-video-widget-gst-0.10.c
index 905acbc..b91a6c6 100644
--- a/libcesarplayer/src/bacon-video-widget-gst-0.10.c
+++ b/libcesarplayer/src/bacon-video-widget-gst-0.10.c
@@ -4976,6 +4976,11 @@ destroy_pixbuf (guchar *pix, gpointer data)
gst_buffer_unref (GST_BUFFER (data));
}
+void
+bacon_video_widget_unref_pixbuf (GdkPixbuf *pixbuf){
+ g_object_unref(pixbuf);
+}
+
/**
* bacon_video_widget_get_current_frame:
* @bvw: a #BaconVideoWidget
diff --git a/libcesarplayer/src/bacon-video-widget.h b/libcesarplayer/src/bacon-video-widget.h
index 14cdb5a..e25a8d1 100644
--- a/libcesarplayer/src/bacon-video-widget.h
+++ b/libcesarplayer/src/bacon-video-widget.h
@@ -419,6 +419,7 @@ EXPORT gboolean bacon_video_widget_has_previous_track (BaconVideoWidget *bvw);
EXPORT gboolean bacon_video_widget_can_get_frames (BaconVideoWidget *bvw,
GError **error);
EXPORT GdkPixbuf *bacon_video_widget_get_current_frame (BaconVideoWidget *bvw);
+EXPORT void bacon_video_widget_unref_pixbuf (GdkPixbuf *pixbuf);
/* Audio-out functions */
/**
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]