mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-03-28 20:05:38 +00:00
preview: extract preview area as separate widget
This commit is contained in:
parent
9baeb2df3d
commit
9f2d0729ab
3 changed files with 149 additions and 68 deletions
|
@ -15,7 +15,8 @@ VALAFLAGS = \
|
|||
gst_mi_SOURCES = \
|
||||
mi.vala \
|
||||
mi-app.vala \
|
||||
mi-info.vala
|
||||
mi-info.vala \
|
||||
mi-preview.vala
|
||||
|
||||
gst_mi_LDADD = \
|
||||
$(MI_LIBS) -lgstinterfaces-0.10 -lgstpbutils-0.10
|
||||
|
|
|
@ -57,8 +57,7 @@ public class MediaInfo.Info : Box
|
|||
private Notebook video_streams; // depending on screen resolution
|
||||
private Notebook audio_streams;
|
||||
private Notebook subtitle_streams;
|
||||
private AspectFrame drawing_frame;
|
||||
private DrawingArea drawing_area;
|
||||
private Preview preview;
|
||||
private ScrolledWindow info_area;
|
||||
// gstreamer objects
|
||||
private Discoverer dc;
|
||||
|
@ -67,7 +66,6 @@ public class MediaInfo.Info : Box
|
|||
private uint num_video_streams;
|
||||
private uint num_audio_streams;
|
||||
private uint num_subtitle_streams;
|
||||
private float video_ratio = 1.0f;
|
||||
private ArrayList<Gdk.Point?> video_resolutions = null;
|
||||
// stream data
|
||||
private Gdk.Pixbuf album_art = null;
|
||||
|
@ -168,19 +166,9 @@ public class MediaInfo.Info : Box
|
|||
}
|
||||
|
||||
// add widgets
|
||||
drawing_frame = new AspectFrame (null, 0.5f, 0.5f, 1.25f, false);
|
||||
drawing_frame.set_size_request (160, 128);
|
||||
drawing_frame.set_shadow_type (Gtk.ShadowType.NONE);
|
||||
|
||||
pack_start (drawing_frame, true, true, 0);
|
||||
|
||||
drawing_area = new DrawingArea ();
|
||||
drawing_area.set_size_request (160, 128);
|
||||
drawing_area.draw.connect (on_drawing_area_draw);
|
||||
drawing_area.size_allocate.connect (on_drawing_area_size_allocate);
|
||||
drawing_area.realize.connect (on_drawing_area_realize);
|
||||
drawing_area.unrealize.connect (on_drawing_area_unrealize);
|
||||
drawing_frame.add (drawing_area);
|
||||
preview = new Preview ();
|
||||
preview.draw.connect (on_preview_draw);
|
||||
pack_start (preview, false, false, 0);
|
||||
|
||||
info_area = new ScrolledWindow (null, null);
|
||||
info_area.set_policy (PolicyType.NEVER, PolicyType.ALWAYS);
|
||||
|
@ -324,7 +312,6 @@ public class MediaInfo.Info : Box
|
|||
// stop previous playback
|
||||
pb.set_state (State.READY);
|
||||
album_art = null;
|
||||
drawing_area.queue_draw();
|
||||
|
||||
try {
|
||||
FileInfo finfo = file.query_info ("standard::*", FileQueryInfoFlags.NONE, null);
|
||||
|
@ -736,19 +723,12 @@ public class MediaInfo.Info : Box
|
|||
|
||||
if (have_video) {
|
||||
Gdk.Point res = video_resolutions[0];
|
||||
video_ratio = (float)(res.x) / (float)(res.y);
|
||||
debug ("video_ratio from video: %f", video_ratio);
|
||||
preview.set_content_size(res.x, res.y);
|
||||
} else if (album_art != null) {
|
||||
int sw=album_art.get_width ();
|
||||
int sh=album_art.get_height ();
|
||||
video_ratio = (float)sw / (float)sh;
|
||||
debug ("video_ratio from album art: %f", video_ratio);
|
||||
preview.set_static_content(album_art);
|
||||
} else {
|
||||
video_ratio = 1.0f;
|
||||
debug ("video_ratio --- : %f", video_ratio);
|
||||
preview.reset();
|
||||
}
|
||||
drawing_frame.set (0.5f, 0.5f, video_ratio, false);
|
||||
drawing_area.queue_resize();
|
||||
|
||||
//l = info.get_container_streams ();
|
||||
|
||||
|
@ -759,7 +739,8 @@ public class MediaInfo.Info : Box
|
|||
|
||||
// signal handlers
|
||||
|
||||
private void on_drawing_area_size_allocate (Widget widget, Gtk.Allocation frame)
|
||||
/*
|
||||
private void on_size_allocate (Widget widget, Gtk.Allocation box)
|
||||
{
|
||||
Gtk.Allocation alloc;
|
||||
get_allocation (out alloc);
|
||||
|
@ -768,57 +749,29 @@ public class MediaInfo.Info : Box
|
|||
Gtk.Requisition requisition;
|
||||
info_area.get_child ().get_preferred_size (null, out requisition);
|
||||
debug ("info_area: %d x %d", requisition.width, requisition.height);
|
||||
debug ("video_area: %d x %d", frame.width, frame.height);
|
||||
int frame_height = (int)(box.width / video_ratio);
|
||||
debug ("video_area: %d x %d", box.width, frame_height);
|
||||
|
||||
int max_h = alloc.height - frame.height;
|
||||
int max_h = alloc.height - frame_height;
|
||||
info_area.set_min_content_height (int.min (requisition.height, max_h));
|
||||
}
|
||||
*/
|
||||
|
||||
private bool on_drawing_area_draw (Widget widget, Cairo.Context cr)
|
||||
private bool on_preview_draw (Widget widget, Cairo.Context cr)
|
||||
{
|
||||
// redraw if not playing and if there is no video
|
||||
if (pb.current_state < State.PAUSED || !have_video) {
|
||||
widget.set_double_buffered (true);
|
||||
|
||||
Gtk.Allocation frame;
|
||||
widget.get_allocation (out frame);
|
||||
int w = frame.width;
|
||||
int h = frame.height;
|
||||
//debug ("on_drawing_area_draw:video_ratio: %d x %d : %f", w, h, video_ratio);
|
||||
|
||||
if (album_art != null) {
|
||||
Gdk.Pixbuf pb = album_art.scale_simple (w, h, Gdk.InterpType.BILINEAR);
|
||||
Gdk.cairo_set_source_pixbuf (cr, pb, 0, 0);
|
||||
} else {
|
||||
cr.set_source_rgb (0, 0, 0);
|
||||
}
|
||||
cr.rectangle (0, 0, w, h);
|
||||
cr.fill ();
|
||||
} else {
|
||||
widget.set_double_buffered (false);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void on_drawing_area_realize (Widget widget)
|
||||
{
|
||||
widget.get_window ().ensure_native ();
|
||||
widget.set_double_buffered (false);
|
||||
}
|
||||
|
||||
private void on_drawing_area_unrealize (Widget widget)
|
||||
{
|
||||
pb.set_state (State.NULL);
|
||||
}
|
||||
|
||||
private void on_element_sync_message (Gst.Bus bus, Message message)
|
||||
{
|
||||
if (Gst.Video.is_video_overlay_prepare_window_handle_message (message)) {
|
||||
Gst.Video.Overlay overlay = message.src as Gst.Video.Overlay;
|
||||
overlay.set_window_handle ((uint *)Gdk.X11Window.get_xid (drawing_area.get_window()));
|
||||
drawing_frame.set (0.5f, 0.5f, video_ratio, false);
|
||||
debug ("on_element_sync_message:video_ratio: %f", video_ratio);
|
||||
drawing_area.queue_resize();
|
||||
overlay.set_window_handle ((uint *)Gdk.X11Window.get_xid (preview.get_window ()));
|
||||
|
||||
/* playbin does this in 1.0
|
||||
if (message.src.get_class ().find_property ("force-aspect-ratio") != null) {
|
||||
|
@ -833,7 +786,12 @@ public class MediaInfo.Info : Box
|
|||
* - we can use:
|
||||
* - pad.get_stream_id() on playbin
|
||||
* - sinfo.get_stream_id() on discoverer
|
||||
*
|
||||
* - gather all stream-ids and build {audio,video,subtitle}_stream_map with
|
||||
* stream-id as a key and value initially set to -1
|
||||
* - have cur_{audio,video,subtile} = 0
|
||||
* - listen for playbin.pad_added and set the stream_id to cur_*
|
||||
* - ideally playbin will have api to switch to a stream-by-id
|
||||
* - or we sort the discoverer streams by stream-info too
|
||||
*/
|
||||
private void on_video_stream_switched (Notebook nb, Widget page, uint page_num)
|
||||
{
|
||||
|
@ -841,10 +799,7 @@ public class MediaInfo.Info : Box
|
|||
debug ("Switching video to: %u", page_num);
|
||||
((GLib.Object)pb).set_property ("current-video", (int)page_num);
|
||||
Gdk.Point res = video_resolutions[(int)page_num];
|
||||
video_ratio = (float)(res.x) / (float)(res.y);
|
||||
drawing_frame.set (0.5f, 0.5f, video_ratio, false);
|
||||
drawing_area.queue_resize();
|
||||
debug ("on_video_stream_switched:video_ratio: %f", video_ratio);
|
||||
preview.set_content_size(res.x, res.y);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
125
mediainfo/src/mi-preview.vala
Normal file
125
mediainfo/src/mi-preview.vala
Normal file
|
@ -0,0 +1,125 @@
|
|||
/* GStreamer media browser
|
||||
* Copyright (C) 2010-2013 Stefan Sauer <ensonic@user.sf.net>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Steet,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
using Gtk;
|
||||
|
||||
public class MediaInfo.Preview : DrawingArea {
|
||||
private Gdk.Pixbuf content = null;
|
||||
private int width = 0;
|
||||
private int height = 0;
|
||||
private float ratio = 0.0f;
|
||||
private int alloc_width;
|
||||
private int alloc_height;
|
||||
|
||||
construct {
|
||||
set_has_window (true);
|
||||
}
|
||||
|
||||
public void reset () {
|
||||
content = null;
|
||||
ratio = 0.0f;
|
||||
debug ("no content: 0.0");
|
||||
queue_resize ();
|
||||
}
|
||||
|
||||
public void set_static_content (Gdk.Pixbuf? content) {
|
||||
this.content = content;
|
||||
if (content != null) {
|
||||
width = content.get_width ();
|
||||
height = content.get_height ();
|
||||
ratio = (float)width / (float)height;
|
||||
debug ("ratio from album art: %f", ratio);
|
||||
queue_resize ();
|
||||
}
|
||||
}
|
||||
|
||||
public void set_content_size (uint width, uint height) {
|
||||
if (height != 0) {
|
||||
ratio = (float)width / (float)height;
|
||||
} else {
|
||||
ratio = 0.0f;
|
||||
}
|
||||
debug ("ratio from video: %f", ratio);
|
||||
queue_resize ();
|
||||
}
|
||||
|
||||
// vmethods
|
||||
|
||||
public override SizeRequestMode get_request_mode () {
|
||||
return SizeRequestMode.HEIGHT_FOR_WIDTH;
|
||||
}
|
||||
|
||||
public override void get_preferred_width (out int minimal_width, out int natural_width) {
|
||||
if (ratio != 0.0) {
|
||||
minimal_width = natural_width = (int)(alloc_height * ratio);
|
||||
} else {
|
||||
minimal_width = natural_width = 0;
|
||||
}
|
||||
debug ("width w,h: %d,%d", natural_width, alloc_height);
|
||||
}
|
||||
|
||||
public override void get_preferred_height (out int minimal_height, out int natural_height) {
|
||||
if (ratio != 0.0) {
|
||||
minimal_height = natural_height = (int)(alloc_width / ratio);
|
||||
} else {
|
||||
minimal_height = natural_height = 0;
|
||||
}
|
||||
debug ("height w,h: %d,%d", alloc_width, natural_height);
|
||||
}
|
||||
|
||||
public override void get_preferred_width_for_height (int height, out int minimal_width, out int natural_width) {
|
||||
if (ratio != 0.0) {
|
||||
minimal_width = natural_width = (int)(height * ratio);
|
||||
} else {
|
||||
minimal_width = natural_width = 0;
|
||||
}
|
||||
debug ("width_for_height w,h: %d,%d", natural_width, height);
|
||||
}
|
||||
|
||||
public override void get_preferred_height_for_width (int width, out int minimal_height, out int natural_height) {
|
||||
if (ratio != 0.0) {
|
||||
minimal_height = natural_height = (int)(width / ratio);
|
||||
} else {
|
||||
minimal_height = natural_height = 0;
|
||||
}
|
||||
debug ("height_for_width w,h: %d,%d", width, natural_height);
|
||||
}
|
||||
|
||||
public override void size_allocate (Gtk.Allocation alloc) {
|
||||
base.size_allocate (alloc);
|
||||
|
||||
alloc_width = alloc.width;
|
||||
alloc_height = alloc.height;
|
||||
debug ("alloc w,h: %d,%d", alloc_width, alloc_height);
|
||||
}
|
||||
|
||||
public override bool draw (Cairo.Context cr) {
|
||||
if (content != null) {
|
||||
Gdk.Pixbuf pb = content.scale_simple (alloc_width, alloc_height, Gdk.InterpType.BILINEAR);
|
||||
Gdk.cairo_set_source_pixbuf (cr, pb, 0, 0);
|
||||
} else {
|
||||
cr.set_source_rgb (0, 0, 0);
|
||||
}
|
||||
cr.rectangle (0, 0, alloc_width, alloc_height);
|
||||
cr.fill ();
|
||||
debug ("draw w,h: %d,%d", alloc_width, alloc_height);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in a new issue