Merge lp:~l-admin-3/snap-elementary/dynamic-video-size into lp:snap-elementary

Proposed by Marcus Wichelmann
Status: Merged
Approved by: Cody Garver
Approved revision: 324
Merged at revision: 324
Proposed branch: lp:~l-admin-3/snap-elementary/dynamic-video-size
Merge into: lp:snap-elementary
Diff against target: 236 lines (+68/-24)
4 files modified
CMakeLists.txt (+2/-2)
src/Services/ThumbnailProvider.vala (+8/-6)
src/SnapWindow.vala (+21/-10)
src/Widgets/Camera.vala (+37/-6)
To merge this branch: bzr merge lp:~l-admin-3/snap-elementary/dynamic-video-size
Reviewer Review Type Date Requested Status
elementary Apps team Pending
Review via email: mp+251171@code.launchpad.net

Commit message

Automatically resize the window based on the resolution of the webcam. The window size is limited to 80% of the screen.

Description of the change

This branch enables the automatically resizing of the window depending on the resolution of the webcam and fixes the FIXME. The window size is limited to 80% of the screen.

To post a comment you must log in.
321. By Marcus Wichelmann

Use the uri of the first detected camera

322. By Marcus Wichelmann

Fix the broken gallery-view

323. By Marcus Wichelmann

Calculate the thumbnail-width correctly so all four rows are shown

Revision history for this message
Danielle Foré (danrabbit) wrote :

Hm I like that it sets the aspect ratio correctly, but I don't like that it can't be resized. But I guess that's a problem in trunk as well.

324. By Marcus Wichelmann

Constant added and window now resizable.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2014-10-24 07:15:47 +0000
3+++ CMakeLists.txt 2015-03-02 14:02:46 +0000
4@@ -40,7 +40,7 @@
5
6 # Dependencies
7 find_package (PkgConfig)
8-set (SNAP_DEPS gee-0.8 gobject-2.0 glib-2.0 gio-2.0 gtk+-3.0>=3.10 gdk-x11-3.0 granite gstreamer-1.0 gstreamer-video-1.0 x11 gudev-1.0 zeitgeist-2.0)
9+set (SNAP_DEPS gee-0.8 gobject-2.0 glib-2.0 gio-2.0 gtk+-3.0>=3.10 gdk-x11-3.0 granite gstreamer-1.0 gstreamer-video-1.0 gstreamer-pbutils-1.0 x11 gudev-1.0 zeitgeist-2.0)
10 pkg_check_modules (DEPS REQUIRED ${SNAP_DEPS})
11
12 set(NORMAL_CFLAGS ${DEPS_CFLAGS})
13@@ -57,4 +57,4 @@
14 add_subdirectory (po)
15
16 # Data
17-install (FILES ${CMAKE_CURRENT_SOURCE_DIR}/data/snap-photobooth.desktop DESTINATION share/applications)
18\ No newline at end of file
19+install (FILES ${CMAKE_CURRENT_SOURCE_DIR}/data/snap-photobooth.desktop DESTINATION share/applications)
20
21=== modified file 'src/Services/ThumbnailProvider.vala'
22--- src/Services/ThumbnailProvider.vala 2015-02-26 12:35:06 +0000
23+++ src/Services/ThumbnailProvider.vala 2015-03-02 14:02:46 +0000
24@@ -36,8 +36,8 @@
25 private Gee.Set<Thumbnail> cache;
26 private int temp_thumb;
27
28- public static const int THUMB_WIDTH = Widgets.Camera.WIDTH / 4;
29- public static const int THUMB_HEIGHT = Widgets.Camera.HEIGHT / 4;
30+ public uint thumb_width = 0;
31+ public uint thumb_height = 0;
32
33 public signal void thumbnail_loaded (Thumbnail thumbnail);
34
35@@ -46,10 +46,12 @@
36 * to obtain thumbnails for files in a specific path
37 * @param path the path where the provider will look for thumbnails
38 */
39- public ThumbnailProvider (File path) {
40+ public ThumbnailProvider (File path, uint thumb_width, uint thumb_height) {
41 this.path = path;
42 this.cache = new Gee.TreeSet<Thumbnail> ();
43 this.temp_thumb = 0;
44+ this.thumb_width = thumb_width;
45+ this.thumb_height = thumb_height;
46 }
47
48 /**
49@@ -88,7 +90,7 @@
50 Gdk.Pixbuf pix = null;
51 if (attr == null) pix = new Gdk.Pixbuf.from_file (file.get_path ());
52 else pix = new Gdk.Pixbuf.from_file (attr);
53- pix = pix.scale_simple (THUMB_WIDTH, THUMB_HEIGHT, 0);
54+ pix = pix.scale_simple ((int)thumb_width, (int)thumb_height, 0);
55 thumb = new Thumbnail (file, pix);
56 } catch (Error err) {
57 warning ("Error: get_thumbnail failed: %s", err.message);
58@@ -104,7 +106,7 @@
59 "-o", out_path, // Output file
60 "-c", "png",
61 "-f", "-t", "10",
62- "-s", THUMB_WIDTH.to_string () };
63+ "-s", thumb_width.to_string () };
64 string[] spawn_env = Environ.get ();
65 Pid child_pid;
66
67@@ -121,7 +123,7 @@
68 });
69
70 Gdk.Pixbuf pix = new Gdk.Pixbuf.from_file (out_path);
71- pix = pix.scale_simple (THUMB_WIDTH, THUMB_HEIGHT, 0);
72+ pix = pix.scale_simple ((int)thumb_width, (int)thumb_height, 0);
73 thumb = new Thumbnail (file, pix);
74 thumb.is_temp = true;
75 thumb.temp_file = File.new_for_path (out_path);
76
77=== modified file 'src/SnapWindow.vala'
78--- src/SnapWindow.vala 2015-02-26 12:35:06 +0000
79+++ src/SnapWindow.vala 2015-03-02 14:02:46 +0000
80@@ -41,28 +41,40 @@
81 private File video_path;
82
83 private bool camera_detected;
84+ private string camera_uri;
85
86 public SnapWindow (Snap.SnapApp snap_app) {
87 this.snap_app = snap_app;
88 this.set_application (this.snap_app);
89
90 this.title = "Snap";
91- this.window_position = Gtk.WindowPosition.CENTER;
92 this.icon_name = "snap-photobooth";
93 this.set_size_request (640, 480);
94- this.resizable = false;
95
96- // Init thumbnail providers
97+ // Get paths
98 photo_path = File.new_for_path (Resources.get_media_dir (Widgets.Camera.ActionType.PHOTO));
99 video_path = File.new_for_path (Resources.get_media_dir (Widgets.Camera.ActionType.VIDEO));
100- Resources.photo_thumb_provider = new Services.ThumbnailProvider (photo_path);
101- Resources.video_thumb_provider = new Services.ThumbnailProvider (video_path);
102
103 // camera
104- camera_detected = this.detect_camera ();
105+ camera_uri = this.detect_camera ();
106+ camera_detected = camera_uri != "";
107+
108+ // Setup the camera
109+ this.camera = new Snap.Widgets.Camera (camera_uri);
110+
111+ // Calculate thumbnail sizes
112+ var thumb_width = (camera.video_width - 19) / 4 - 18; // 19 = scrollbar_width + 2 * margin; 4 = row-count; 18 = 2 * item_padding + column_spacing
113+ var thumb_height = (int)(((float)thumb_width / camera.video_width) * camera.video_height);
114+
115+ // Init thumbnail providers
116+ Resources.photo_thumb_provider = new Services.ThumbnailProvider (photo_path, thumb_width, thumb_height);
117+ Resources.video_thumb_provider = new Services.ThumbnailProvider (video_path, thumb_width, thumb_height);
118
119 // Setup UI
120 setup_window ();
121+
122+ // Set the window position
123+ this.window_position = Gtk.WindowPosition.CENTER;
124 }
125
126 void setup_window () {
127@@ -151,7 +163,6 @@
128 this.gallery = new Snap.Widgets.Gallery ();
129
130 // Setup preview area
131- this.camera = new Snap.Widgets.Camera ();
132 this.camera.capture_start.connect (() => {
133 // Disable uneeded buttons
134 gallery_button.sensitive = false;
135@@ -189,7 +200,7 @@
136 this.show_all ();
137 }
138
139- private bool detect_camera () {
140+ private string detect_camera () {
141 try {
142 var video_devices = File.new_for_path ("/dev/.");
143 FileEnumerator enumerator = video_devices.enumerate_children (FileAttribute.STANDARD_NAME, 0);
144@@ -197,7 +208,7 @@
145 while ((info = enumerator.next_file (null)) != null) {
146 if (info.get_name ().has_prefix ("video")){
147 debug ("camera found: %s", info.get_name ());
148- return true;
149+ return "v4l2:///dev/%s".printf (info.get_name ());
150 }
151 }
152 } catch (Error err) {
153@@ -205,7 +216,7 @@
154 }
155
156 debug ("no camera");
157- return false;
158+ return "";
159 }
160
161 protected override bool delete_event (Gdk.EventAny event) {
162
163=== modified file 'src/Widgets/Camera.vala'
164--- src/Widgets/Camera.vala 2015-02-26 12:35:06 +0000
165+++ src/Widgets/Camera.vala 2015-03-02 14:02:46 +0000
166@@ -26,8 +26,10 @@
167 CAPTURING;
168 }
169
170- public static const int WIDTH = 640;
171- public static const int HEIGHT = 480;
172+ private const double PERCENTAGE_SCREEN = 0.6;
173+
174+ public uint video_width = 640;
175+ public uint video_height = 480;
176
177 private ActionType type;
178
179@@ -39,9 +41,7 @@
180 public signal void capture_start ();
181 public signal void capture_stop ();
182
183- public class Camera () {
184- this.set_size_request (WIDTH, HEIGHT); // FIXME
185-
186+ public class Camera (string camera_uri) {
187 this.videoflip = Gst.ElementFactory.make ("videoflip", "videoflip");
188 this.videoflip.set_property ("method", 4);
189
190@@ -54,7 +54,7 @@
191 return true;
192 });
193
194- var preview_caps = Gst.Caps.from_string ("video/x-raw, format=\"rgb\", width = (int) %d, height = (int) %d".printf (WIDTH, HEIGHT));
195+ var preview_caps = Gst.Caps.from_string ("video/x-raw, format=\"rgb\"");
196 this.camerabin.set_property ("preview-caps", preview_caps);
197
198 // Workaround to fix a CSD releated bug.
199@@ -65,6 +65,37 @@
200 this.set_visual (visual);
201 // workaround END
202
203+ try {
204+ var info = new Gst.PbUtils.Discoverer (10 * Gst.SECOND).discover_uri (camera_uri);
205+ var video = info.get_video_streams ();
206+
207+ if (video != null && video.data != null) {
208+ var video_info = (Gst.PbUtils.DiscovererVideoInfo)video.data;
209+
210+ video_width = video_info.get_width ();
211+ video_height = video_info.get_height ();
212+ }
213+
214+ var current_screen = this.get_screen ();
215+ var screen_width = current_screen.get_width ();
216+ var screen_height = current_screen.get_height ();
217+
218+ if (video_width >= screen_width * PERCENTAGE_SCREEN || video_height >= screen_height * PERCENTAGE_SCREEN) {
219+ if ((float)screen_width / video_width < (float)screen_height / video_height) {
220+ var new_video_width = (int)(screen_width * PERCENTAGE_SCREEN);
221+ video_height = (int)(((float)new_video_width / video_width) * video_height);
222+ video_width = new_video_width;
223+ } else {
224+ var new_video_height = (int)(screen_height * PERCENTAGE_SCREEN);
225+ video_width = (int)(((float)new_video_height / video_height) * video_width);
226+ video_height = new_video_height;
227+ }
228+ }
229+ } catch (Error e) {
230+ debug ("Getting the video-size failed: %s", e.message);
231+ }
232+
233+ this.set_size_request ((int)video_width, (int)video_height);
234 this.show_all ();
235 this.play ();
236 }

Subscribers

People subscribed via source and target branches