diff --git a/meson.build b/meson.build index 66a9c55fe68e14aa8e90d50e290882ce27bfcc6c..78af813f491c00ef543d7d608d8ae0ecd1fc046b 100644 --- a/meson.build +++ b/meson.build @@ -53,19 +53,15 @@ queso_vala_sources = [ 'src/application.vala', 'src/application-main.vala', 'src/application-window.vala', - 'src/audio-device.vala', - 'src/audio-setup.vala', 'src/camera.vala', - 'src/device.vala', - 'src/device-type.vala', 'src/devices.vala', 'src/format.vala', 'src/framerate.vala', 'src/queso-event.vala', 'src/timestamp.vala', 'src/v4l-control-widget.vala', - 'src/video-device.vala', 'src/video-setup.vala', + 'src/video-source.vala', 'src/video-source-settings-dialog.vala' ] diff --git a/src/audio-device.vala b/src/audio-device.vala deleted file mode 100644 index 3b1c9352d8d4f0f3602d7c8b96c70ef7e9f00a16..0000000000000000000000000000000000000000 --- a/src/audio-device.vala +++ /dev/null @@ -1,125 +0,0 @@ -/* - * This file is part of queso. - * - * Copyright © 2020 Canek Peláez Valdés - * - * This program is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software - * Foundation, either version 3 of the License, or (at your option) any later - * version. - * - * This program 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 General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * along with this program. If not, see . - * - * Author: - * Canek Peláez Valdés - */ - -namespace Queso { - - /** - * Class for audio devices. - */ - public class AudioDevice : Device, Gee.Comparable { - - /** - * The device setups. - */ - public Gee.TreeSet setups { public get; private set; } - - /** - * Constructs an audio device. - * @param device the GStreamer device. - */ - public AudioDevice(Gst.Device device) { - base(device); - } - - /** - * Constructs a testing video device. - */ - public AudioDevice.test() { - base.test(); - name = "Test Audio Source"; - setups.add(new AudioSetup(AudioSetup.RAW, - new Gee.TreeSet(), - null, 1, 2147483647, 1, 2)); - } - - /** - * Initializes the audio device setups. - */ - protected override void init_setups() { - setups = new Gee.TreeSet(); - } - - /** - * Parse an structure in the device. - * @param structure the structure to parse. - */ - protected override void parse_structure(Gst.Structure structure) { - string n = ""; - string l = null; - int r1 = -1; - int r2 = -1; - int c1 = -1; - int c2 = -1; - n = structure.get_name(); - if (n == null) - return; - var fmts = new Gee.TreeSet(); - l = structure.get_string("layout"); - GLib.Value? f = structure.get_value("format"); - GLib.Value? r = structure.get_value("rate"); - GLib.Value? c = structure.get_value("channels"); - if (f != null && f.type() == typeof(Gst.ValueList)) { - for (int i = 0; i < Gst.ValueList.get_size(f); i ++) { - var vf = Gst.ValueList.get_value(f, i); - if (vf.type() != typeof(string)) - continue; - fmts.add(new Format(vf.dup_string())); - } - } else if (f != null && f.type() == typeof(string)) { - fmts.add(new Format(f.dup_string())); - } - if (r.type() == typeof(Gst.IntRange)) - parse_range(r, out r1, out r2); - if (c.type() == typeof(Gst.IntRange)) - parse_range(c, out c1, out c2); - setups.add(new AudioSetup(n, fmts, l, r1, r2, c1, c2)); - } - - /* Parses a range. */ - private void parse_range(GLib.Value range, out int min, out int max) { - min = Gst.Value.get_int_range_min(range); - max = Gst.Value.get_int_range_max(range); - } - - /** - * Compares the two audio devices. - * @param dev the audio device to compare with. - * @return -1 if this device it's better than the one received; 0 if - * they are equal; 1 if it's worse. - */ - public int compare_to(AudioDevice dev) { - if (!is_test && dev.is_test) - return -1; - if (is_test && !dev.is_test) - return 1; - var ts = this.setups.first(); - var ds = dev.setups.first(); - return ts.compare_to(ds); - } - - public new Gst.Element create_element(string name) { - if (is_test) - return Gst.ElementFactory.make("testaudiosrc", name); - return base.create_element(name); - } - } -} diff --git a/src/camera.vala b/src/camera.vala index 69fb479b4c503539a85c7ba345436e2a83a96f9b..2e6f1a22e319b997a0dc1c02bad6ab956491d561 100644 --- a/src/camera.vala +++ b/src/camera.vala @@ -219,12 +219,10 @@ namespace Queso { /* The video and audio devices. */ private Devices devices; - private VideoDevice videodev; - private VideoDevice new_videodev; - private AudioDevice audiodev; + private VideoSource videodev; + private VideoSource new_videodev; private VideoSetup video_setup; private VideoSetup new_video_setup; - private AudioSetup audio_setup; /* Pipeline and elements. */ protected Gst.Pipeline pipeline; @@ -263,7 +261,6 @@ namespace Queso { private Gst.Element file_mp4mux; /* File sink*/ - //private Gst.Element file_queue; private Gst.Element file_sink; /* Temporary filename . */ @@ -285,9 +282,7 @@ namespace Queso { this.devices = devices; devices.device_changed.connect(device_changed); videodev = devices.video_device; - audiodev = devices.audio_device; video_setup = videodev.setups.first(); - audio_setup = audiodev.setups.first(); pipeline = new Gst.Pipeline("queso"); @@ -442,7 +437,6 @@ namespace Queso { audio_encoder.set_state(Gst.State.NULL); audio_queue_mp4mux.set_state(Gst.State.NULL); - //file_queue.set_state(Gst.State.NULL); file_sink.set_state(Gst.State.NULL); pipeline.remove_many(video_tee, @@ -458,7 +452,6 @@ namespace Queso { audio_encoder, audio_queue_mp4mux, file_mp4mux, - //file_queue, file_sink); var src_pad = video_queue_decoder.get_static_pad("src"); var sink_pad = video_convert_gtk.get_static_pad("sink"); @@ -483,7 +476,6 @@ namespace Queso { audio_encoder = null; audio_queue_mp4mux = null; file_mp4mux = null; - //file_queue = null; file_sink = null; } @@ -617,7 +609,6 @@ namespace Queso { /* Sets the H264 idle pipeline. */ private void h264_idle_pipeline() { - stderr.printf("%s\n", video_setup.to_string()); video_src = videodev.create_element("video-src"); video_filter = Gst.ElementFactory.make( "capsfilter", "video-filter"); @@ -733,17 +724,12 @@ namespace Queso { var sink_pad = video_queue_gtk.get_static_pad("sink"); src_pad.unlink(sink_pad); - audio_src = audiodev.create_element("audio-src"); + audio_src = Gst.ElementFactory.make("pulsesrc", "audio-src"); audio_filter = Gst.ElementFactory.make("capsfilter", "audio-filter"); - int rate = get_audio_rate(); - int channels = audio_setup.max_rate > 1 ? 2 : 1; - var fmt = audio_setup.formats.first(); - var acaps = new Gst.Caps.empty_simple(audio_setup.media_type); - acaps.set_simple("format", typeof(string), fmt.format, - "rate", typeof(int), rate, - "channels", typeof(int), channels); - audio_filter.set("caps", acaps); + var caps = new Gst.Caps.empty_simple("audio/x-raw"); + caps.set_simple("channels", typeof(int), 2); + audio_filter.set("caps", caps); audio_queue_rate = Gst.ElementFactory.make("queue", "audio-queue-rate"); audio_rate = Gst.ElementFactory.make("audiorate", "audio-rate"); @@ -806,12 +792,6 @@ namespace Queso { audio_queue_mp4mux, file_mp4mux); - // video_saving = false; - // var pad = video_queue_file.get_static_pad("src"); - // pad.add_probe(Gst.PadProbeType.BUFFER, raw_analyze_video_buffer_probe); - // pad = audio_queue_mp4mux.get_static_pad("src"); - // pad.add_probe(Gst.PadProbeType.BUFFER, analyze_audio_buffer_probe); - audio_src.set_state(Gst.State.PLAYING); audio_filter.set_state(Gst.State.PLAYING); audio_queue_rate.set_state(Gst.State.PLAYING); @@ -833,18 +813,12 @@ namespace Queso { var sink_pad = video_queue_gtk.get_static_pad("sink"); src_pad.unlink(sink_pad); - // audiodev.create_element("audio-src"); audio_src = Gst.ElementFactory.make("pulsesrc", "audio-src"); audio_filter = Gst.ElementFactory.make("capsfilter", "audio-filter"); - int rate = get_audio_rate(); - int channels = audio_setup.max_rate > 1 ? 2 : 1; - var fmt = audio_setup.formats.first(); - var acaps = new Gst.Caps.empty_simple(audio_setup.media_type); - acaps.set_simple("format", typeof(string), fmt.format, - "rate", typeof(int), rate, - "channels", typeof(int), channels); - audio_filter.set("caps", acaps); + var caps = new Gst.Caps.empty_simple("audio/x-raw"); + caps.set_simple("channels", typeof(int), 2); + audio_filter.set("caps", caps); audio_queue_rate = Gst.ElementFactory.make("queue", "audio-queue-rate"); audio_rate = Gst.ElementFactory.make("audiorate", "audio-rate"); @@ -956,69 +930,7 @@ namespace Queso { return Gst.PadProbeReturn.OK; } - private Gst.PadProbeReturn - h264_remove_saving_pipeline_block_probe(Gst.Pad pad, Gst.PadProbeInfo info) { - stderr.printf("h264_remove_saving_pipeline_block_probe %s::%s\n", - pad.parent.name, pad.name); - pad.remove_probe(info.id); - video_h264_parse.unlink(video_tee); - video_tee.unlink(video_queue_gtk); - audio_queue_mp4mux.unlink(file_mp4mux); - video_h264_parse.link(video_queue_gtk); - video_queue_file.set_state(Gst.State.NULL); - video_tee.set_state(Gst.State.NULL); - audio_queue_mp4mux.set_state(Gst.State.NULL); - audio_encoder.set_state(Gst.State.NULL); - audio_convert.set_state(Gst.State.NULL); - audio_rate.set_state(Gst.State.NULL); - audio_queue_rate.set_state(Gst.State.NULL); - audio_filter.set_state(Gst.State.NULL); - audio_src.set_state(Gst.State.NULL); - - pipeline.remove_many(file_mp4mux, - file_sink, - audio_queue_mp4mux, - audio_encoder, - audio_convert, - audio_rate, - audio_queue_rate, - audio_filter, - audio_src, - video_queue_file, - video_tee); - - video_tee = null; - video_queue_file = null; - - /* FIXME: This causes a warning: - gst_object_unref: - assertion '((GObject *) object)->ref_count > 0' failed - Find why. */ - audio_src = null; - - audio_filter = null; - audio_queue_rate = null; - audio_rate = null; - audio_convert = null; - audio_encoder = null; - audio_queue_mp4mux = null; - file_mp4mux = null; - file_sink = null; - - return Gst.PadProbeReturn.DROP; - } - - private void device_changed(DeviceType device_type) { - if (saving) - return; - switch (device_type) { - case VIDEO: - video_device_changed(); - break; - } - } - - private void video_device_changed() { + private void device_changed() { new_videodev = devices.video_device; new_video_setup = new_videodev.setups.first(); if (video_setup.media_type == VideoSetup.RAW && @@ -1212,20 +1124,10 @@ namespace Queso { "queso-%08X.mp4".printf(ts)); } - private int get_audio_rate() { - int rate = DEFAULT_AUDIO_RATE; - while (rate > audio_setup.max_rate) - rate /= 2; - return rate; - } - private string get_info() { var r = new StringBuilder(); r.append("Video source: "); r.append(videodev.name); - r.append("\n"); - r.append("Audio source: "); - r.append(audiodev.name); return r.str; } diff --git a/src/devices.vala b/src/devices.vala index 8fff8fef82ffb28fd00e4ea7a91c140cb68c24b4..64458b2c74c81aaef456efada3e56a326ec2a030 100644 --- a/src/devices.vala +++ b/src/devices.vala @@ -27,7 +27,7 @@ namespace Queso { */ public class Devices : GLib.Object { - public signal void device_changed(DeviceType device_type); + public signal void device_changed(); /** * Null device. @@ -37,24 +37,14 @@ namespace Queso { /** * The video devices. */ - public Gee.TreeSet video_devices { public get; private set; } - - /** - * The audio devices. - */ - public Gee.TreeSet audio_devices { public get; private set; } + public Gee.TreeSet video_devices { public get; private set; } /** * The selected video device. */ - public VideoDevice video_device { public get; private set; } + public VideoSource video_device { public get; private set; } - /** - * The selected audio device. - */ - public AudioDevice audio_device { public get; private set; } - - private Gee.Iterator vd_iter; + private Gee.Iterator vd_iter; /* The device monitor. */ private Gst.DeviceMonitor monitor; @@ -63,16 +53,12 @@ namespace Queso { /* Constructs a device manager. */ construct { - audio_devices = new Gee.TreeSet(); - video_devices = new Gee.TreeSet(); - audio_devices.add(new AudioDevice.test()); - video_devices.add(new VideoDevice.test()); + video_devices = new Gee.TreeSet(); + video_devices.add(new VideoSource.test()); monitor = new Gst.DeviceMonitor(); bus = monitor.get_bus(); bus.add_watch(GLib.Priority.DEFAULT, monitor_devices); - monitor.add_filter("Audio/Source", - new Gst.Caps.empty_simple(AudioSetup.RAW)); monitor.add_filter("Video/Source", new Gst.Caps.empty_simple(VideoSetup.RAW)); monitor.add_filter("Video/Source", @@ -83,14 +69,9 @@ namespace Queso { var devices = monitor.get_devices(); unowned GLib.List t = devices; while (t != null) { - stderr.printf(">> %s\n", t.data.get_display_name()); switch (t.data.get_device_class()) { - case "Audio/Source": - if (!("Monitor of" in t.data.get_display_name())) - audio_devices.add(new AudioDevice(t.data)); - break; case "Video/Source": - video_devices.add(new VideoDevice(t.data)); + video_devices.add(new VideoSource(t.data)); break; } t = t.next; @@ -101,7 +82,6 @@ namespace Queso { vd_iter.next(); video_device = vd_iter.get(); } - audio_device = audio_devices.first(); } public void next_video_device() { @@ -109,7 +89,7 @@ namespace Queso { vd_iter = video_devices.iterator(); vd_iter.next(); video_device = vd_iter.get(); - device_changed(DeviceType.VIDEO); + device_changed(); } public void update_video_device(string name) { @@ -118,18 +98,7 @@ namespace Queso { foreach (var device in video_devices) { if (device.name == name) { video_device = device; - device_changed(DeviceType.VIDEO); - } - } - } - - public void update_audio_device(string name) { - if (video_device.name == name) - return; - foreach (var device in audio_devices) { - if (device.name == name) { - audio_device = device; - device_changed(DeviceType.AUDIO); + device_changed(); } } } diff --git a/src/video-source-settings-dialog.vala b/src/video-source-settings-dialog.vala index 458732f4fa0cee0198246100bfaf34a5c569a68c..fd71d995c953760f84dddcc652f8000efb2f34cc 100644 --- a/src/video-source-settings-dialog.vala +++ b/src/video-source-settings-dialog.vala @@ -29,7 +29,7 @@ namespace Queso { public class VideoSourceSettingsDialog : Gtk.Dialog { private Devices devices; - private VideoDevice videodev; + private VideoSource videodev; private V4LControlManager v4lmgr; private Gee.ArrayList v4lwidgets; @@ -57,7 +57,7 @@ namespace Queso { set_device(devices.video_device); } - private void set_device(VideoDevice videodev) { + private void set_device(VideoSource videodev) { if (videodev == this.videodev) return; this.videodev = videodev; @@ -110,9 +110,8 @@ namespace Queso { devices.update_video_device(video_source_combo.active_id); } - private void device_changed(DeviceType device_type) { - if (device_type != DeviceType.VIDEO || - devices.video_device == this.videodev) + private void device_changed() { + if (devices.video_device == this.videodev) return; vs_grid.foreach(c => vs_grid.remove(c)); v4lwidgets.clear(); diff --git a/src/video-device.vala b/src/video-source.vala similarity index 81% rename from src/video-device.vala rename to src/video-source.vala index bf9751f8980367d16f316db5ae8f976e8b004ee9..0b7dd74d836b619a0f299044d19977f3b863ca2f 100644 --- a/src/video-device.vala +++ b/src/video-source.vala @@ -25,10 +25,23 @@ namespace Queso { /** * Class for video devices. */ - public class VideoDevice : Device, Gee.Comparable { + public class VideoSource : GLib.Object, Gee.Comparable { public string device_path { public get; private set; } + /** + * Whether is a testing device. + */ + public bool is_test { public get; protected set; } + + /** + * The name of the device. + */ + public string name { public get; protected set; } + + /* The GStreamer device. */ + private Gst.Device device; + /** * The device setups. */ @@ -38,8 +51,14 @@ namespace Queso { * Constructs a video device. * @param device the GStreamer device. */ - public VideoDevice(Gst.Device device) { - base(device); + public VideoSource(Gst.Device device) { + name = device.get_display_name(); + var caps = device.get_caps(); + if (caps == null) + return; + setups = new Gee.TreeSet(); + for (uint i = 0; i < caps.get_size(); i++) + parse_structure(caps.get_structure(i)); var props = device.get_properties(); device_path = Devices.DEV_NULL; if (!props.has_field("device.path")) @@ -53,8 +72,8 @@ namespace Queso { /** * Constructs a testing video device. */ - public VideoDevice.test() { - base.test(); + public VideoSource.test() { + is_test = true; name = "Test Video Source"; device_path = Devices.DEV_NULL; var frs = new Gee.TreeSet(); @@ -62,18 +81,8 @@ namespace Queso { setups.add(new VideoSetup(VideoSetup.RAW, "I420", 640, 480, frs)); } - /** - * Initializes the video device setups. - */ - protected override void init_setups() { - setups = new Gee.TreeSet(); - } - - /** - * Parse an structure in the device. - * @param structure the structure to parse. - */ - protected override void parse_structure(Gst.Structure structure) { + /* Parse an structure in the device. */ + private void parse_structure(Gst.Structure structure) { string n = ""; string f = ""; int w = -1; @@ -123,7 +132,7 @@ namespace Queso { * @return -1 if this device it's better than the one received; 0 if * they are equal; 1 if it's worse. */ - public int compare_to(VideoDevice dev) { + public int compare_to(VideoSource dev) { if (!is_test && dev.is_test) return -1; if (is_test && !dev.is_test) @@ -133,9 +142,9 @@ namespace Queso { return ts.compare_to(ds); } - public new Gst.Element create_element(string name) { - if (!is_test) - return base.create_element(name); + public Gst.Element create_element(string name) { + if (is_test) + return device.create_element(name); var src = Gst.ElementFactory.make("videotestsrc", name); src.set("is-live", true); return src;