cheese r711 - in branches/cheese-vala: . src
- From: jhaitsma svn gnome org
- To: svn-commits-list gnome org
- Subject: cheese r711 - in branches/cheese-vala: . src
- Date: Sun, 4 May 2008 22:34:48 +0100 (BST)
Author: jhaitsma
Date: Sun May 4 21:34:48 2008
New Revision: 711
URL: http://svn.gnome.org/viewvc/cheese?rev=711&view=rev
Log:
More webcam stuff implemented
Modified:
branches/cheese-vala/ (props changed)
branches/cheese-vala/src/Makefile.am
branches/cheese-vala/src/cheese-webcam.vala
Modified: branches/cheese-vala/src/Makefile.am
==============================================================================
--- branches/cheese-vala/src/Makefile.am (original)
+++ branches/cheese-vala/src/Makefile.am Sun May 4 21:34:48 2008
@@ -42,7 +42,7 @@
$(cheese_VALASOURCES:.vala=.h)
cheese.vala.stamp: $(cheese_VALASOURCES)
- $(VALAC) -C -g $(VALA_CFLAGS) $^
+ $(VALAC) -C $(VALA_CFLAGS) $^
touch $@
cheese_LDADD = \
Modified: branches/cheese-vala/src/cheese-webcam.vala
==============================================================================
--- branches/cheese-vala/src/cheese-webcam.vala (original)
+++ branches/cheese-vala/src/cheese-webcam.vala Sun May 4 21:34:48 2008
@@ -40,8 +40,7 @@
DICE = (1 << 9),
WARP = (1 << 10)
}
-
-
+
public class FrameRate : GLib.Object {
public int numerator;
public int denominator;
@@ -107,6 +106,11 @@
}
}
+ public string udi { get; construct; }
+ int cur_device_num = -1;
+ VideoFormat cur_video_format;
+ FrameRate cur_frame_rate;
+
ArrayList<Device> devices = new ArrayList<Device> ();
Pipeline pipeline;
Gst.Bus bus;
@@ -129,29 +133,19 @@
Element effect_filter;
Element csp_post_effect;
- ulong photo_handler_signal_id;
+ ulong photo_handler_id;
- bool is_recording;
- bool pipeline_is_playing;
+ bool is_recording = false;
+ bool pipeline_is_playing = false;
string photo_filename;
/* Dummy variable used to increase ref count */
Element sink_ref;
+
/*
XF86VidModeGamma normal_gamma;
float flash_intensity;
*/
- int num_webcam_devices;
- string device_name;
- /*
- CheeseWebcamDevice *webcam_devices;
- int x_resolution;
- int y_resolution;
- int selected_device;
- CheeseVideoFormat *current_format;
- GHashTable *supported_resolutions;
-
-*/
public Webcam (Widget window) {
this.video_window = window;
}
@@ -159,9 +153,28 @@
public void setup () {
detect_webcam_devices ();
print_devices ();
+ create_video_display_bin ();
+ create_photo_save_bin ();
+ create_video_save_bin ();
+
+ pipeline = new Pipeline ("pipeline");
+
+ pipeline.add_many (video_display_bin, photo_save_bin);
+ bool ok;
+ ok = video_display_bin.link (photo_save_bin);
+
+ var bus = pipeline.get_bus ();
+ bus.add_signal_watch ();
+
+ bus.message += on_bus_message;
+ if (!ok)
+ error ("Unable link pipeline for photo");
+
+ threads_enter();
+ // FIXME XF86VidModeGetGamma (GDK_DISPLAY (), 0, &(priv->normal_gamma));
+ threads_leave();
}
-
-
+
void print_devices () {
int i = 0;
print ("Following devices have been detected\n");
@@ -181,23 +194,39 @@
}
print ("\n");
}
-
}
}
public void play () {
+ pipeline.set_state (State.PLAYING);
+ set_x_overlay ();
+ pipeline_is_playing = true;
}
public void stop () {
+ pipeline.set_state (State.NULL);
+ pipeline_is_playing = false;
}
- public void start_recording (string filename) {
+ public void start_recording (string filename) {
+ video_file_sink.set ("location", filename);
+ change_sink (video_display_bin, video_save_bin, photo_save_bin);
+ is_recording = true;
}
public void stop_recording () {
+ /* Send EOS message down the pipeline by stopping video and audio source*/
+ video_source.set_state (State.NULL);
+ video_source.set_locked_state (true);
+ audio_source.set_state (State.NULL);
+ audio_source.set_locked_state (true);
}
public void take_photo (string filename) {
+ photo_filename = filename;
+ /* Take the photo by connecting the handoff signal */
+ photo_handler_id = Signal.connect (photo_sink, "handoff", (GLib.Callback)on_photo_data, this);
+ flash ();
}
public ArrayList<Device> get_devices () {
@@ -218,12 +247,37 @@
set_x_overlay ();
}
- void on_photo_data (Element element, Buffer buffer, Pad pad) {
+
+ void on_photo_data (Element element, Buffer buffer, Pad pad) {
+ var caps = buffer.get_caps ();
+ weak Structure structure;
+ structure = caps.get_structure (0);
+ int width, height;
+ structure.get_int ("width", out width);
+ structure.get_int ("height", out height);
+
+ int stride = (int)buffer.size/height;
+ var pixbuf = new Pixbuf.from_data (buffer.data, Colorspace.RGB,
+ false, 8, width, height, stride,
+ null);
+
+ pixbuf.save (photo_filename, "jpeg");
+ /* Emit photo_saved signal */
+ photo_saved ();
+ SignalHandler.disconnect (photo_sink, photo_handler_id);
}
void on_bus_message (Gst.Bus bus, Message message) {
-
+ if (message.type == Gst.MessageType.EOS) {
+ /* Emit video saved signal */
+ video_saved ();
+
+ video_source.set_locked_state (false);
+ audio_source.set_locked_state (false);
+ change_sink (video_display_bin, photo_save_bin, video_save_bin);
+ is_recording = false;
+ }
}
void get_video_devices_from_hal () throws WebcamError {
@@ -433,22 +487,142 @@
}
}
- bool create_webcam_source_bin () {
- return false;
+ void create_webcam_source_bin () throws WebcamError {
+ if (devices.size == 0) {
+ // FIXME: throw error
+ webcam_source_bin = (Gst.Bin)parse_bin_from_description ("videotestsrc name=video_source ! capsfilter name=capsfilter ! identity", true);
+ } else {
+ /* If we have a matching video device use that one, otherwise use the first */
+ cur_device_num = 0;
+ for (int i = 1; i < devices.size; i++) {
+ if (devices[i].udi == udi)
+ cur_device_num = i;
+ }
+
+ int max_res = 0;
+ /* Select highest resolution */
+ foreach (VideoFormat format in devices[cur_device_num].video_format) {
+ if (format.width > max_res) {
+ max_res = format.width;
+ cur_video_format = format;
+ }
+ }
+ float max_frame_rate = 0.0f;
+ /* Select highest frame rate */
+ foreach (FrameRate frame_rate in cur_video_format.frame_rate) {
+ float f = (float)frame_rate.numerator / frame_rate.denominator;
+ if (f > max_frame_rate) {
+ max_frame_rate = f;
+ cur_frame_rate = frame_rate;
+ }
+ }
+ var webcam_input = "%s name=video_source device=%s ! capsfilter name=capsfilter caps=%s,width=%d,height=%d,framerate=%d/%d ! identity".printf (
+ devices[cur_device_num].gstreamer_element_name,
+ devices[cur_device_num].device,
+ cur_video_format.mime_type,
+ cur_video_format.width,
+ cur_video_format.height,
+ cur_frame_rate.numerator,
+ cur_frame_rate.denominator);
+ print ("%s\n", webcam_input);
+ // FIXME: throw error
+ webcam_source_bin = (Gst.Bin)parse_bin_from_description (webcam_input, true);
+
+ }
+ video_source = webcam_source_bin.get_by_name ("video_source");
+ capsfilter = webcam_source_bin.get_by_name ("capsfilter");
}
-
- bool create_video_display_bin () {
- return false;
+
+ void create_video_display_bin () throws WebcamError {
+ video_display_bin = new Gst.Bin ("video_display_bin");
+ create_webcam_source_bin ();
+
+ effect_filter = ElementFactory.make ("identity", "effect");
+ csp_post_effect = ElementFactory.make ("ffmpegcolorspace", "csp_post_effect");
+
+ var tee = ElementFactory.make ("tee", "tee");
+ var save_queue = ElementFactory.make ("queue", "save_queue");
+ var video_display_queue = ElementFactory.make ("queue", "video_display_queue");
+
+ var video_scale = ElementFactory.make ("videoscale", "video_scale");
+ /* Use bilinear scaling */
+ video_scale.set ("method", 1);
+
+ var video_sink = ElementFactory.make ("gconfvideosink", "video_sink");
+
+ video_display_bin.add_many (webcam_source_bin, effect_filter, csp_post_effect,
+ tee, save_queue, video_display_queue, video_scale, video_sink);
+ bool ok;
+ ok = webcam_source_bin.link_many (effect_filter, csp_post_effect, tee);
+ ok &= tee.link_many (save_queue);
+ ok &= tee.link_many (video_display_queue, video_scale, video_sink);
+
+ if (!ok)
+ throw new WebcamError.FAILED ("create_video_display_bin (): Error linking gstreamer elements together");
+
+ /* add ghostpad */
+ var pad = save_queue.get_pad ("src");
+ video_display_bin.add_pad (new GhostPad("src", pad));
}
- bool create_photo_save_bin () {
- return false;
+ void create_photo_save_bin () throws WebcamError {
+ photo_save_bin = new Gst.Bin ("photo_save_bin");
+ var csp_photo_save_bin = ElementFactory.make ("ffmpegcolorspace", "csp_photo_save_bin");
+ photo_sink = ElementFactory.make ("fakesink", "photo_sink");
+
+ photo_save_bin.add_many (csp_photo_save_bin,photo_sink);
+
+ /* add ghostpad */
+ var pad = csp_photo_save_bin.get_pad ("sink");
+ photo_save_bin.add_pad (new GhostPad ("sink", pad));
+
+ var caps = new Caps.simple ("video/x-raw-rgb", "bpp", typeof (int), 24,
+ "depth", typeof (int), 24);
+ bool ok;
+ ok = csp_photo_save_bin.link_filtered (photo_sink, caps);
+ if (!ok)
+ throw new WebcamError.FAILED ("create_photo_save_bin (): Error linking gstreamer elements together");
+
+ photo_sink.set ("signal-handoffs", true);
}
- bool create_video_save_bin () {
- return false;
+ void create_video_save_bin () throws WebcamError {
+ video_save_bin = new Gst.Bin ("video_save_bin");
+
+ audio_source = ElementFactory.make ("gconfaudiosrc", "audio_source");
+ var audio_queue = ElementFactory.make ("queue", "audio_queue");
+ var audio_convert = ElementFactory.make ("audioconvert", "audio_convert");
+ var audio_enc = ElementFactory.make ("vorbisenc", "audio_enc");
+
+ var video_save_csp = ElementFactory.make ("ffmpegcolorspace", "video_save_csp");
+ var video_enc = ElementFactory.make ("theoraenc", "video_enc");
+ video_enc.set ("keyframe-force", 1);
+ var video_save_scale = ElementFactory.make ("videoscale", "video_save_scale");
+ /* Use bilinear scaling */
+ video_save_scale.set ("method", 1);
+
+ var mux = ElementFactory.make ("oggmux", "mux");
+ video_file_sink = ElementFactory.make ("filesink", "video_file_sink");
+
+ video_save_bin.add_many (audio_source, audio_queue, audio_convert,
+ audio_enc, video_save_csp, video_save_scale, video_enc,
+ mux, video_file_sink);
+
+ /* add ghostpad */
+ var pad = video_save_csp.get_pad ("sink");
+ video_save_bin.add_pad (new GhostPad ("sink", pad));
+ bool ok;
+ ok = audio_source.link_many (audio_queue, audio_convert, audio_enc, mux,
+ video_file_sink);
+
+ ok &= video_save_csp.link_many (video_save_scale, video_enc);
+ ok &= video_enc.link (mux);
+ if (!ok)
+ throw new WebcamError.FAILED ("create_video_save_bin (): Error linking gstreamer elements together");
}
- void flash_set_intensity (float intesity) {
+
+
+ void flash_set_intensity (float intensity) {
}
void on_flash_dim () {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]