diff --git a/repos/libports/src/lib/qemu-usb/README b/repos/libports/src/lib/qemu-usb/README index 2fd540be38..a160a7d69a 100644 --- a/repos/libports/src/lib/qemu-usb/README +++ b/repos/libports/src/lib/qemu-usb/README @@ -33,28 +33,21 @@ when the timer triggers. Usage webcam model attached to the xHCI model ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -If the xHCI model is enabled and used, then the webcam device model can be -enabled by specifying a XML node in the config ROM: +If the xHCI model is enabled and used, the webcam device model can be +enabled by specifying a XML node in the config ROM. - ... - - ... + ... + + ... -The webcam attributes are optional. The values shown above, are the default ones -when a attribute is not specified. When the webcam node is specified, the model -will open and will use a Genode capture session to obtain the -frames in the rate as specified by the frame per secondes (fps) attribute. The -'vertical_flip' attribute specifies, whether the frames are shown flipped -for guests. For Windows guests the value has to be false, for Linux guests -true. The format supported by the model is YUV2 or BGR3. If the 'screen_size' is set -to true, the webcam model will try to use the screen size as provided by the -capture session. If the screen size is invalid (e.g. 0x0), the attribute -values of 'width' and 'height' will be used instead. If the 'report' attribute -is set, a report will be generated whenever the guests starts/ends capturing and -if the capturing format choosen by the guest changes, - - -or - +Webcam attributes are optional, default values are depicted above. The model +supports YUV2 and BGR3 image formats reported to the guest via bFormatIndex. +It requests a Genode capture session to obtain the frames in the rate as +specified by the 'fps' (frame per seconds) attribute. The 'vertical_flip' +attribute specifies, whether the frames are shown flipped vertically for +guests. For Windows guests the value has to be false, for Linux guests true. +If the 'screen_size' attribute is set to true, the webcam model configures the +initial screen size to the size provided by the capture session. If the screen +size is invalid (e.g. 0x0), 'width' and 'height' will be used as fallback. diff --git a/repos/libports/src/lib/qemu-usb/dev-webcam.c b/repos/libports/src/lib/qemu-usb/dev-webcam.c index 8f48d43a85..a99d37b6df 100644 --- a/repos/libports/src/lib/qemu-usb/dev-webcam.c +++ b/repos/libports/src/lib/qemu-usb/dev-webcam.c @@ -435,18 +435,6 @@ static void usb_webcam_handle_reset(USBDevice *dev) usb_webcam_init_state(state); } -static void usb_webcam_capture_state_changed(bool const on) -{ - char const * format = "unknown"; - - if (vs_commit_state.bFormatIndex == DEVICE_VS_FORMAT_BGR) - format = "BGR3"; - else if (vs_commit_state.bFormatIndex == DEVICE_VS_FORMAT_YUV) - format = "YUY2"; - - capture_state_changed(on, format); -} - static void usb_webcam_setup_packet(USBWebcamState * const state, USBPacket * const p) { unsigned packet_size = vs_commit_state.dwMaxPayLoadTransferSize; @@ -458,7 +446,7 @@ static void usb_webcam_setup_packet(USBWebcamState * const state, USBPacket * co if (packet_size <= sizeof(header)) { p->status = USB_RET_STALL; if (state->capture) - usb_webcam_capture_state_changed(false); + capture_state_changed(false); usb_webcam_init_state(state); return; } @@ -466,7 +454,7 @@ static void usb_webcam_setup_packet(USBWebcamState * const state, USBPacket * co if (state->bytes_frame >= max_frame_size(active_format())) { p->status = USB_RET_STALL; if (state->capture) - usb_webcam_capture_state_changed(false); + capture_state_changed(false); usb_webcam_init_state(state); return; } @@ -478,7 +466,7 @@ static void usb_webcam_setup_packet(USBWebcamState * const state, USBPacket * co /* check for capture state change */ if (!state->capture) { state->capture = true; - usb_webcam_capture_state_changed(state->capture); + capture_state_changed(state->capture); } if (!state->timer_active) @@ -543,7 +531,7 @@ static void webcam_timeout(void *opague) if (state->delay_packet || (state->watchdog && state->watchdog >= fps)) { state->capture = false; state->delay_packet = false; - usb_webcam_capture_state_changed(state->capture); + capture_state_changed(state->capture); } else { state->watchdog ++; webcam_start_timer(state); @@ -625,7 +613,7 @@ static void usb_webcam_handle_control(USBDevice * const dev, if (state->capture) { state->capture = false; state->delay_packet = false; - usb_webcam_capture_state_changed(state->capture); + capture_state_changed(state->capture); } } stall = false; @@ -689,7 +677,7 @@ static void usb_webcam_handle_control(USBDevice * const dev, if (notify) { USBWebcamState *state = USB_WEBCAM(dev); - usb_webcam_capture_state_changed(state->capture); + capture_state_changed(state->capture); } } @@ -719,7 +707,7 @@ static void usb_webcam_handle_data(USBDevice *dev, USBPacket *p) if (!p->ep || p->ep->nr != DEVICE_EP_ID) { p->status = USB_RET_STALL; if (state->capture) - usb_webcam_capture_state_changed(false); + capture_state_changed(false); usb_webcam_init_state(state); return; } @@ -727,7 +715,7 @@ static void usb_webcam_handle_data(USBDevice *dev, USBPacket *p) default: p->status = USB_RET_STALL; if (state->capture) - usb_webcam_capture_state_changed(false); + capture_state_changed(false); usb_webcam_init_state(state); return; } diff --git a/repos/libports/src/lib/qemu-usb/webcam-backend.h b/repos/libports/src/lib/qemu-usb/webcam-backend.h index 00e9f3653f..fcdf68ee6e 100644 --- a/repos/libports/src/lib/qemu-usb/webcam-backend.h +++ b/repos/libports/src/lib/qemu-usb/webcam-backend.h @@ -20,6 +20,6 @@ struct webcam_config { extern void webcam_backend_config(struct webcam_config *); extern bool capture_bgr_frame(void * pixel); extern bool capture_yuv_frame(void * pixel); -extern void capture_state_changed(bool on, char const * format); +extern void capture_state_changed(bool on); #endif /* _WEBCAM_BACKEND_H_ */ diff --git a/repos/libports/src/lib/qemu-usb/webcam.cc b/repos/libports/src/lib/qemu-usb/webcam.cc index e174d11fef..27042f845f 100644 --- a/repos/libports/src/lib/qemu-usb/webcam.cc +++ b/repos/libports/src/lib/qemu-usb/webcam.cc @@ -30,28 +30,27 @@ using namespace Genode; struct Capture_webcam { Env &_env; - Capture::Connection _capture { _env, "webcam" }; Gui::Area const _area; bool const _vflip; uint8_t const _fps; bool _force_update { false }; - Attached_dataspace _ds { _env.rm(), _capture.dataspace() }; - Constructible _reporter { }; + Constructible _capture; + Constructible _ds; - Gui::Area setup_area(Gui::Area const area_in, bool const auto_area) + Gui::Area _setup_area(Gui::Area const area_in, bool const auto_area) { Gui::Area area = area_in; if (auto_area) { - area = _capture.screen_size(); + Capture::Connection probe { _env, "webcam" }; + + area = probe.screen_size(); if (!area.valid()) area = area_in; } - /* request setup of dataspace by server */ - _capture.buffer(area); return area; } @@ -62,7 +61,7 @@ struct Capture_webcam return false; bool changed = _force_update; - _capture.capture_at(Capture::Point(0, 0)).for_each_rect([&](auto) { + _capture->capture_at(Capture::Point(0, 0)).for_each_rect([&](auto) { changed = true; }); if (!changed) @@ -71,7 +70,7 @@ struct Capture_webcam int const src_stride_argb = _area.w() * 4; int const dst_stride_yuy2 = _area.w() * 2; - libyuv::ARGBToYUY2(_ds.local_addr(), src_stride_argb, + libyuv::ARGBToYUY2(_ds->local_addr(), src_stride_argb, reinterpret_cast(frame), dst_stride_yuy2, _area.w(), _area.h()); @@ -89,7 +88,7 @@ struct Capture_webcam bool changed = false; uint8_t * const bgr = reinterpret_cast(frame); - Pixel_rgb888 const * const data = _ds.local_addr(); + Pixel_rgb888 const * const data = _ds->local_addr(); auto const &update_fn = ([&](auto &rect) { changed = true; @@ -110,52 +109,47 @@ struct Capture_webcam /* update whole frame */ _force_update = false; Rect const whole(Point(0,0), _area); - _capture.capture_at(Capture::Point(0, 0)); + _capture->capture_at(Capture::Point(0, 0)); update_fn(whole); } else - _capture.capture_at(Capture::Point(0, 0)).for_each_rect(update_fn); + _capture->capture_at(Capture::Point(0, 0)).for_each_rect(update_fn); return changed; } - void capture_state_changed(bool on, char const * format) + void capture_state_changed(bool on) { /* next time update whole frame due to format changes or on/off */ _force_update = true; - if (!_reporter.constructed()) - return; - - Reporter::Xml_generator xml(*_reporter, [&] () { - xml.attribute("enabled", on); - xml.attribute("format", format); - }); + /* construct/destruct capture connection and dataspace */ + if (on) { + _capture.construct(_env, "webcam"); + _capture->buffer(_area); + _ds.construct(_env.rm(), _capture->dataspace()); + } else { + _ds.destruct(); + _capture.destruct(); + } } - Capture_webcam (Env &env, Gui::Area area, bool auto_area, bool flip, - uint8_t fps, bool report) + Capture_webcam(Env &env, Gui::Area area, bool auto_area, bool flip, uint8_t fps) : _env(env), - _area(setup_area(area, auto_area)), + _area(_setup_area(area, auto_area)), _vflip(flip), _fps(fps) { - if (report) { - _reporter.construct(_env, "capture"); - _reporter->enabled(true); - } - log("USB webcam ", _area, " fps=", _fps, " vertical_flip=", - _vflip ? "yes" : "no", - " report=", _reporter.constructed() ? "enabled" : "disabled"); + _vflip ? "yes" : "no"); } }; static Genode::Constructible capture; -extern "C" void capture_state_changed(bool on, char const * format) +extern "C" void capture_state_changed(bool on) { - capture->capture_state_changed(on, format); + capture->capture_state_changed(on); } extern "C" bool capture_bgr_frame(void * pixel) @@ -187,8 +181,7 @@ extern "C" void _type_init_host_webcam_register_types(Env &env, webcam.attribute_value("height", 480u)), webcam.attribute_value("screen_size", false), webcam.attribute_value("vertical_flip", false), - webcam.attribute_value("fps", 15u), - webcam.attribute_value("report", false)); + webcam.attribute_value("fps", 15u)); /* register webcam model, which will call webcam_backend_config() */ _type_init_usb_webcam_register_types(); diff --git a/repos/ports/recipes/pkg/vbox5-nova-capture/runtime b/repos/ports/recipes/pkg/vbox5-nova-capture/runtime index 37f52ff1bd..8f9cfd4825 100644 --- a/repos/ports/recipes/pkg/vbox5-nova-capture/runtime +++ b/repos/ports/recipes/pkg/vbox5-nova-capture/runtime @@ -5,7 +5,6 @@ - @@ -67,7 +66,7 @@ - + @@ -81,7 +80,6 @@ - diff --git a/repos/ports/run/vbox_win.inc b/repos/ports/run/vbox_win.inc index 7e8b2783f9..11e5a35424 100644 --- a/repos/ports/run/vbox_win.inc +++ b/repos/ports/run/vbox_win.inc @@ -280,7 +280,7 @@ for { set i 1} { $i <= $use_vms } { incr i} { } append_if [expr $use_webcam] config_of_app { - } + } append config_of_app {