mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-20 17:52:52 +00:00
Qt-based media player
This patch implements a simple Qt-based media player which is actually a graphical user interface for the SDL-based 'avplay' media player from 'libav'. It starts 'avplay' as a child and shows its graphical output in a 'QNitpickerViewWidget'. The widgets for controlling the player state send the according keyboard and mouse input events to 'avplay'. The 'qt_avplay' player supports the following configuration options: <mediafile name="..."/> -> name of the media file to play <framebuffer_filter name="..." ram_quota="..."/> (may appear multiple times) -> name of a framebuffer filter service to filter the video output Fixes #222.
This commit is contained in:
parent
8f4b3dd4f1
commit
06fdc7b897
@ -14,6 +14,7 @@
|
||||
#ifndef _EVENT_QUEUE_H_
|
||||
#define _EVENT_QUEUE_H_
|
||||
|
||||
#include <base/printf.h>
|
||||
#include <input/event.h>
|
||||
#include <os/ring_buffer.h>
|
||||
|
@ -15,13 +15,13 @@
|
||||
#define _PS2_KEYBOARD_H_
|
||||
|
||||
#include <base/printf.h>
|
||||
#include <input/event_queue.h>
|
||||
#include <input/keycodes.h>
|
||||
|
||||
#include "input_driver.h"
|
||||
#include "serial_interface.h"
|
||||
#include "scan_code_set_1.h"
|
||||
#include "scan_code_set_2.h"
|
||||
#include "event_queue.h"
|
||||
|
||||
class Ps2_keyboard : public Input_driver
|
||||
{
|
||||
|
@ -15,9 +15,9 @@
|
||||
#define _PS2_MOUSE_H_
|
||||
|
||||
#include <base/printf.h>
|
||||
#include <input/event_queue.h>
|
||||
#include <input/keycodes.h>
|
||||
|
||||
#include "event_queue.h"
|
||||
#include "input_driver.h"
|
||||
|
||||
class Ps2_mouse : public Input_driver
|
||||
|
160
qt4/run/qt_avplay.run
Normal file
160
qt4/run/qt_avplay.run
Normal file
@ -0,0 +1,160 @@
|
||||
#
|
||||
# Build
|
||||
#
|
||||
|
||||
build {
|
||||
core
|
||||
init
|
||||
drivers/input/ps2
|
||||
drivers/pci
|
||||
drivers/framebuffer
|
||||
drivers/timer
|
||||
drivers/audio_out
|
||||
server/nitpicker
|
||||
app/avplay
|
||||
app/qt_avplay
|
||||
}
|
||||
|
||||
#
|
||||
# Download media file
|
||||
#
|
||||
|
||||
set media_url "ftp://ftp.untergrund.net/users/ae/dhstv/escape-chotro.mp4"
|
||||
if {![file exists bin/mediafile]} {
|
||||
puts "downloading media file from $media_url"
|
||||
catch { exec wget -O bin/mediafile $media_url }
|
||||
}
|
||||
|
||||
create_boot_directory
|
||||
|
||||
#
|
||||
# Generate config
|
||||
#
|
||||
|
||||
set config {
|
||||
<config>
|
||||
<parent-provides>
|
||||
<service name="ROM"/>
|
||||
<service name="RAM"/>
|
||||
<service name="IRQ"/>
|
||||
<service name="IO_MEM"/>
|
||||
<service name="IO_PORT"/>
|
||||
<service name="CAP"/>
|
||||
<service name="PD"/>
|
||||
<service name="RM"/>
|
||||
<service name="CPU"/>
|
||||
<service name="LOG"/>
|
||||
<service name="SIGNAL"/>
|
||||
</parent-provides>
|
||||
<default-route>
|
||||
<any-service> <parent/> <any-child/> </any-service>
|
||||
</default-route> }
|
||||
|
||||
append_if [have_spec sdl] config {
|
||||
<start name="fb_sdl">
|
||||
<resource name="RAM" quantum="4M"/>
|
||||
<provides>
|
||||
<service name="Input"/>
|
||||
<service name="Framebuffer"/>
|
||||
</provides>
|
||||
</start>}
|
||||
|
||||
append_if [have_spec pci] config {
|
||||
<start name="pci_drv">
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
<provides><service name="PCI"/></provides>
|
||||
</start>}
|
||||
|
||||
append_if [have_spec vesa] config {
|
||||
<start name="vesa_drv">
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
<provides><service name="Framebuffer"/></provides>
|
||||
</start>}
|
||||
|
||||
append_if [have_spec pl11x] config {
|
||||
<start name="pl11x_drv">
|
||||
<resource name="RAM" quantum="2M"/>
|
||||
<provides><service name="Framebuffer"/></provides>
|
||||
</start>}
|
||||
|
||||
append_if [have_spec ps2] config {
|
||||
<start name="ps2_drv">
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
<provides><service name="Input"/></provides>
|
||||
</start> }
|
||||
|
||||
append config {
|
||||
<start name="timer">
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
<provides><service name="Timer"/></provides>
|
||||
</start>
|
||||
<start name="audio_out_drv">
|
||||
<resource name="RAM" quantum="2M"/>
|
||||
<provides><service name="Audio_out"/></provides>
|
||||
</start>
|
||||
<start name="nitpicker">
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
<provides><service name="Nitpicker"/></provides>
|
||||
</start>
|
||||
<start name="qt_avplay">
|
||||
<resource name="RAM" quantum="2G"/>
|
||||
<config>
|
||||
<mediafile name="mediafile"/>
|
||||
</config>
|
||||
</start>
|
||||
</config>
|
||||
}
|
||||
|
||||
install_config $config
|
||||
|
||||
#
|
||||
# Boot modules
|
||||
#
|
||||
|
||||
# generic modules
|
||||
set boot_modules {
|
||||
core
|
||||
init
|
||||
timer
|
||||
audio_out_drv
|
||||
nitpicker
|
||||
qt_avplay
|
||||
dejavusans.lib.so
|
||||
freetype.lib.so
|
||||
ld.lib.so
|
||||
libc.lib.so
|
||||
libc_lock_pipe.lib.so
|
||||
libm.lib.so
|
||||
libpng.lib.so
|
||||
jpeg.lib.so
|
||||
qnitpickerviewwidget.lib.so
|
||||
qt_core.lib.so
|
||||
qt_gui.lib.so
|
||||
qt_xml.lib.so
|
||||
zlib.lib.so
|
||||
avcodec.lib.so
|
||||
avformat.lib.so
|
||||
avutil.lib.so
|
||||
avfilter.lib.so
|
||||
swscale.lib.so
|
||||
sdl.lib.so
|
||||
pthread.lib.so
|
||||
libc_log.lib.so
|
||||
libc_rom.lib.so
|
||||
avplay
|
||||
mediafile
|
||||
}
|
||||
|
||||
# platform-specific modules
|
||||
lappend_if [have_spec linux] boot_modules fb_sdl
|
||||
lappend_if [have_spec pci] boot_modules pci_drv
|
||||
lappend_if [have_spec vesa] boot_modules vesa_drv
|
||||
lappend_if [have_spec ps2] boot_modules ps2_drv
|
||||
lappend_if [have_spec pl11x] boot_modules pl11x_drv
|
||||
|
||||
build_boot_image $boot_modules
|
||||
|
||||
append qemu_args " -m 512 -soundhw all"
|
||||
|
||||
run_genode_until forever
|
||||
|
18
qt4/src/app/qt_avplay/README
Normal file
18
qt4/src/app/qt_avplay/README
Normal file
@ -0,0 +1,18 @@
|
||||
This directory contains a simple Qt-based media player which is actually a
|
||||
graphical user interface for the SDL-based 'avplay' media player from 'libav'.
|
||||
It starts 'avplay' as a child and shows its graphical output in a
|
||||
'QNitpickerViewWidget'. The widgets for controlling the player state send the
|
||||
according keyboard and mouse input events to 'avplay'.
|
||||
|
||||
The 'qt_avplay' player supports the following configuration options:
|
||||
|
||||
:'<mediafile name="..."/>:'
|
||||
name of the media file to play
|
||||
|
||||
:'<framebuffer_filter name="..." ram_quota="..."/>':
|
||||
|
||||
This node contains the name of a framebuffer filter service to filter the
|
||||
video output. It may appear multiple times. If specified more than once, it
|
||||
is possible to build a post-processing pipeline for the video display where
|
||||
each processing stage is executed by a separate program.
|
||||
|
115
qt4/src/app/qt_avplay/avplay_policy.h
Normal file
115
qt4/src/app/qt_avplay/avplay_policy.h
Normal file
@ -0,0 +1,115 @@
|
||||
/*
|
||||
* \brief Avplay policy
|
||||
* \author Christian Prochaska
|
||||
* \date 2012-04-05
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _AVPLAY_POLICY_H_
|
||||
#define _AVPLAY_POLICY_H_
|
||||
|
||||
/* Qt4 includes */
|
||||
#include <QDebug>
|
||||
#include <QObject>
|
||||
#include <QDomDocument>
|
||||
#include <QDomElement>
|
||||
#include <QDomText>
|
||||
|
||||
/* Genode includes */
|
||||
#include <os/slave.h>
|
||||
|
||||
|
||||
class Avplay_policy : public QObject, public Genode::Slave_policy
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
|
||||
Genode::Service_registry &_input_in;
|
||||
Genode::Service_registry &_framebuffer_in;
|
||||
|
||||
const char *_mediafile;
|
||||
int _sdl_audio_volume;
|
||||
QByteArray _config_byte_array;
|
||||
|
||||
|
||||
const char *_config()
|
||||
{
|
||||
QDomDocument config_doc;
|
||||
|
||||
QDomElement config_node = config_doc.createElement("config");
|
||||
config_doc.appendChild(config_node);
|
||||
|
||||
QDomElement arg0_node = config_doc.createElement("arg");
|
||||
arg0_node.setAttribute("value", "avplay");
|
||||
config_node.appendChild(arg0_node);
|
||||
|
||||
QDomElement arg1_node = config_doc.createElement("arg");
|
||||
arg1_node.setAttribute("value", _mediafile);
|
||||
config_node.appendChild(arg1_node);
|
||||
|
||||
QDomElement sdl_audio_volume_node = config_doc.createElement("sdl_audio_volume");
|
||||
sdl_audio_volume_node.setAttribute("value", QString::number(_sdl_audio_volume));
|
||||
config_node.appendChild(sdl_audio_volume_node);
|
||||
|
||||
_config_byte_array = config_doc.toByteArray(4);
|
||||
|
||||
return _config_byte_array.constData();
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
const char **_permitted_services() const
|
||||
{
|
||||
static const char *permitted_services[] = {
|
||||
"CAP", "LOG", "RM", "ROM", "SIGNAL",
|
||||
"Timer", "Audio_out", 0 };
|
||||
|
||||
return permitted_services;
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
Avplay_policy(Genode::Rpc_entrypoint &entrypoint,
|
||||
Genode::Service_registry &input_in,
|
||||
Genode::Service_registry &framebuffer_in,
|
||||
const char *mediafile)
|
||||
: Genode::Slave_policy("avplay", entrypoint, Genode::env()->ram_session()),
|
||||
_input_in(input_in),
|
||||
_framebuffer_in(framebuffer_in),
|
||||
_mediafile(mediafile),
|
||||
_sdl_audio_volume(100)
|
||||
{
|
||||
configure(_config());
|
||||
}
|
||||
|
||||
Genode::Service *resolve_session_request(const char *service_name,
|
||||
const char *args)
|
||||
{
|
||||
if (strcmp(service_name, "Input") == 0)
|
||||
return _input_in.find(service_name);
|
||||
|
||||
if (strcmp(service_name, "Framebuffer") == 0) {
|
||||
Genode::Client client;
|
||||
return _framebuffer_in.wait_for_service(service_name, &client, name());
|
||||
}
|
||||
|
||||
return Slave_policy::resolve_session_request(service_name, args);
|
||||
}
|
||||
|
||||
public Q_SLOTS:
|
||||
|
||||
void volume_changed(int value)
|
||||
{
|
||||
_sdl_audio_volume = value;
|
||||
configure(_config());
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _AVPLAY_POLICY_H_ */
|
73
qt4/src/app/qt_avplay/control_bar.cpp
Normal file
73
qt4/src/app/qt_avplay/control_bar.cpp
Normal file
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* \brief Control bar
|
||||
* \author Christian Prochaska
|
||||
* \date 2012-03-30
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <input/keycodes.h>
|
||||
|
||||
/* Qoost includes */
|
||||
#include <qoost/style.h>
|
||||
|
||||
#include "input_service.h"
|
||||
#include "main_window.h"
|
||||
|
||||
|
||||
void Control_bar::_rewind()
|
||||
{
|
||||
/* mouse click at horizontal position 0 */
|
||||
ev_queue.add(Input::Event(Input::Event::PRESS, Input::BTN_LEFT, 0, 0, 0, 0));
|
||||
ev_queue.add(Input::Event(Input::Event::RELEASE, Input::BTN_LEFT, 0, 0, 0, 0));
|
||||
}
|
||||
|
||||
|
||||
void Control_bar::_pause_resume()
|
||||
{
|
||||
ev_queue.add(Input::Event(Input::Event::PRESS, Input::KEY_SPACE, 0, 0, 0, 0));
|
||||
ev_queue.add(Input::Event(Input::Event::RELEASE, Input::KEY_SPACE, 0, 0, 0, 0));
|
||||
|
||||
_playing = !_playing;
|
||||
if (_playing)
|
||||
update_style_id(_play_pause_button, "play");
|
||||
else
|
||||
update_style_id(_play_pause_button, "pause");
|
||||
}
|
||||
|
||||
|
||||
void Control_bar::_stop()
|
||||
{
|
||||
if (_playing)
|
||||
_pause_resume();
|
||||
|
||||
_rewind();
|
||||
}
|
||||
|
||||
|
||||
Control_bar::Control_bar()
|
||||
: _playing(true)
|
||||
{
|
||||
update_style_id(_play_pause_button, "play");
|
||||
|
||||
_volume_slider->setOrientation(Qt::Horizontal);
|
||||
_volume_slider->setRange(0, 100);
|
||||
_volume_slider->setTickInterval(10);
|
||||
_volume_slider->setValue(100);
|
||||
|
||||
_layout->addWidget(_play_pause_button);
|
||||
_layout->addWidget(_stop_button);
|
||||
_layout->addStretch();
|
||||
_layout->addWidget(_volume_label);
|
||||
_layout->addWidget(_volume_slider);
|
||||
|
||||
connect(_play_pause_button, SIGNAL(clicked()), this, SLOT(_pause_resume()));
|
||||
connect(_stop_button, SIGNAL(clicked()), this, SLOT(_stop()));
|
||||
connect(_volume_slider, SIGNAL(valueChanged(int)), this, SIGNAL(volume_changed(int)));
|
||||
}
|
58
qt4/src/app/qt_avplay/control_bar.h
Normal file
58
qt4/src/app/qt_avplay/control_bar.h
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* \brief Control bar
|
||||
* \author Christian Prochaska
|
||||
* \date 2012-03-30
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _CONTROL_BAR_H_
|
||||
#define _CONTROL_BAR_H_
|
||||
|
||||
/* Qt includes */
|
||||
#include <QtGui>
|
||||
|
||||
/* Qoost includes */
|
||||
#include <qoost/compound_widget.h>
|
||||
#include <qoost/qmember.h>
|
||||
|
||||
struct Play_pause_button : QPushButton { Q_OBJECT };
|
||||
struct Stop_button : QPushButton { Q_OBJECT };
|
||||
struct Volume_label : QLabel { Q_OBJECT };
|
||||
struct Volume_slider : QSlider { Q_OBJECT };
|
||||
|
||||
class Control_bar : public Compound_widget<QWidget, QHBoxLayout>
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
|
||||
QMember<Play_pause_button> _play_pause_button;
|
||||
QMember<Stop_button> _stop_button;
|
||||
QMember<Volume_label> _volume_label;
|
||||
QMember<Volume_slider> _volume_slider;
|
||||
|
||||
bool _playing;
|
||||
|
||||
void _rewind();
|
||||
|
||||
private Q_SLOTS:
|
||||
|
||||
void _pause_resume();
|
||||
void _stop();
|
||||
|
||||
public:
|
||||
|
||||
Control_bar();
|
||||
|
||||
Q_SIGNALS:
|
||||
|
||||
void volume_changed(int value);
|
||||
};
|
||||
|
||||
#endif /* _CONTROL_BAR_H_ */
|
77
qt4/src/app/qt_avplay/filter_framebuffer_policy.h
Normal file
77
qt4/src/app/qt_avplay/filter_framebuffer_policy.h
Normal file
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* \brief Filter framebuffer policy
|
||||
* \author Christian Prochaska
|
||||
* \date 2012-04-11
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _FILTER_FRAMEBUFFER_POLICY_H_
|
||||
#define _FILTER_FRAMEBUFFER_POLICY_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/service.h>
|
||||
#include <os/slave.h>
|
||||
|
||||
|
||||
class Filter_framebuffer_policy : public Genode::Slave_policy
|
||||
{
|
||||
private:
|
||||
|
||||
Genode::Service_registry &_framebuffer_in;
|
||||
Genode::Service_registry &_framebuffer_out;
|
||||
|
||||
protected:
|
||||
|
||||
const char **_permitted_services() const
|
||||
{
|
||||
static const char *permitted_services[] = {
|
||||
"CAP", "LOG", "RM", "ROM", "SIGNAL",
|
||||
"Timer", 0 };
|
||||
|
||||
return permitted_services;
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
Filter_framebuffer_policy(const char *name,
|
||||
Genode::Rpc_entrypoint &entrypoint,
|
||||
Genode::Service_registry &framebuffer_in,
|
||||
Genode::Service_registry &framebuffer_out)
|
||||
: Genode::Slave_policy(name, entrypoint, Genode::env()->ram_session()),
|
||||
_framebuffer_in(framebuffer_in),
|
||||
_framebuffer_out(framebuffer_out) { }
|
||||
|
||||
Genode::Service *resolve_session_request(const char *service_name,
|
||||
const char *args)
|
||||
{
|
||||
if (strcmp(service_name, "Framebuffer") == 0) {
|
||||
Genode::Client client;
|
||||
return _framebuffer_in.wait_for_service(service_name, &client, name());
|
||||
}
|
||||
|
||||
return Slave_policy::resolve_session_request(service_name, args);
|
||||
}
|
||||
|
||||
bool announce_service(const char *name,
|
||||
Genode::Root_capability root,
|
||||
Genode::Allocator *alloc,
|
||||
Genode::Server *server)
|
||||
{
|
||||
if (strcmp(name, "Framebuffer") == 0) {
|
||||
_framebuffer_out.insert(new (alloc) Genode::Child_service(name, root, server));
|
||||
return true;
|
||||
}
|
||||
|
||||
return Slave_policy::announce_service(name, root, alloc, server);
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif /* _FILTER_FRAMEBUFFER_POLICY_H_ */
|
64
qt4/src/app/qt_avplay/framebuffer_root.h
Normal file
64
qt4/src/app/qt_avplay/framebuffer_root.h
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* \brief Framebuffer root
|
||||
* \author Christian Prochaska
|
||||
* \date 2012-04-02
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _FRAMEBUFFER_ROOT_H_
|
||||
#define _FRAMEBUFFER_ROOT_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <root/component.h>
|
||||
|
||||
#include "framebuffer_session_component.h"
|
||||
|
||||
namespace Framebuffer {
|
||||
|
||||
/**
|
||||
* Shortcut for single-client root component
|
||||
*/
|
||||
typedef Genode::Root_component<Session_component, Genode::Single_client> Root_component;
|
||||
|
||||
|
||||
class Root : public Root_component
|
||||
{
|
||||
private:
|
||||
|
||||
QNitpickerViewWidget &_nitpicker_view_widget;
|
||||
int _max_width;
|
||||
int _max_height;
|
||||
|
||||
protected:
|
||||
|
||||
Session_component *_create_session(const char *args)
|
||||
{
|
||||
return new (md_alloc())
|
||||
Session_component(args, _nitpicker_view_widget,
|
||||
_max_width, _max_height);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Root(Genode::Rpc_entrypoint *session_ep,
|
||||
Genode::Allocator *md_alloc,
|
||||
QNitpickerViewWidget &nitpicker_view_widget,
|
||||
int max_width = 0,
|
||||
int max_height = 0)
|
||||
: Root_component(session_ep, md_alloc),
|
||||
_nitpicker_view_widget(nitpicker_view_widget),
|
||||
_max_width(max_width),
|
||||
_max_height(max_height) { }
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* _FRAMEBUFFER_ROOT_H_ */
|
86
qt4/src/app/qt_avplay/framebuffer_session_component.cc
Normal file
86
qt4/src/app/qt_avplay/framebuffer_session_component.cc
Normal file
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* \brief Framebuffer session component
|
||||
* \author Christian Prochaska
|
||||
* \date 2012-04-02
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/env.h>
|
||||
#include <nitpicker_view/client.h>
|
||||
#include <util/arg_string.h>
|
||||
#include <util/misc_math.h>
|
||||
|
||||
#include "framebuffer_session_component.h"
|
||||
|
||||
namespace Framebuffer {
|
||||
|
||||
|
||||
int Session_component::_limited_size(int requested_size, int max_size)
|
||||
{
|
||||
if (requested_size == 0)
|
||||
return max_size;
|
||||
else
|
||||
return (max_size > 0) ? Genode::min(requested_size, max_size) : requested_size;
|
||||
}
|
||||
|
||||
|
||||
static inline long session_arg(const char *arg, const char *key)
|
||||
{
|
||||
return Genode::Arg_string::find_arg(arg, key).long_value(0);
|
||||
}
|
||||
|
||||
|
||||
Session_component::Session_component(const char *args,
|
||||
QNitpickerViewWidget &nitpicker_view_widget,
|
||||
int max_width,
|
||||
int max_height)
|
||||
: _nitpicker(Nitpicker::Connection(
|
||||
_limited_size(session_arg(args, "fb_width"), max_width),
|
||||
_limited_size(session_arg(args, "fb_height"), max_height))),
|
||||
_framebuffer(_nitpicker.framebuffer_session())
|
||||
{
|
||||
Nitpicker::View_capability nitpicker_view_cap = _nitpicker.create_view();
|
||||
Mode _mode = _framebuffer.mode();
|
||||
nitpicker_view_widget.setNitpickerView(nitpicker_view_cap,
|
||||
0, 0,
|
||||
_mode.width(),
|
||||
_mode.height());
|
||||
}
|
||||
|
||||
|
||||
Genode::Dataspace_capability Session_component::dataspace()
|
||||
{
|
||||
return _framebuffer.dataspace();
|
||||
}
|
||||
|
||||
|
||||
void Session_component::release()
|
||||
{
|
||||
_framebuffer.release();
|
||||
}
|
||||
|
||||
|
||||
Mode Session_component::mode() const
|
||||
{
|
||||
return _framebuffer.mode();
|
||||
}
|
||||
|
||||
|
||||
void Session_component::mode_sigh(Genode::Signal_context_capability sigh_cap)
|
||||
{
|
||||
_framebuffer.mode_sigh(sigh_cap);
|
||||
}
|
||||
|
||||
|
||||
void Session_component::refresh(int x, int y, int w, int h)
|
||||
{
|
||||
_framebuffer.refresh(x, y, w, h);
|
||||
}
|
||||
}
|
57
qt4/src/app/qt_avplay/framebuffer_session_component.h
Normal file
57
qt4/src/app/qt_avplay/framebuffer_session_component.h
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* \brief Framebuffer session component
|
||||
* \author Christian Prochaska
|
||||
* \date 2012-04-02
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _FRAMEBUFFER_SESSION_COMPONENT_H_
|
||||
#define _FRAMEBUFFER_SESSION_COMPONENT_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/rpc_server.h>
|
||||
#include <framebuffer_session/client.h>
|
||||
#include <nitpicker_session/connection.h>
|
||||
|
||||
/* Qt4 includes */
|
||||
#include <qnitpickerviewwidget/qnitpickerviewwidget.h>
|
||||
|
||||
|
||||
namespace Framebuffer {
|
||||
|
||||
class Session_component : public Genode::Rpc_object<Session>
|
||||
{
|
||||
private:
|
||||
|
||||
Nitpicker::Connection _nitpicker;
|
||||
Session_client _framebuffer;
|
||||
|
||||
int _limited_size(int requested_size, int max_size);
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Session_component(const char *args,
|
||||
QNitpickerViewWidget &nitpicker_view_widget,
|
||||
int max_width = 0,
|
||||
int max_height = 0);
|
||||
|
||||
Genode::Dataspace_capability dataspace();
|
||||
void release();
|
||||
Mode mode() const;
|
||||
void mode_sigh(Genode::Signal_context_capability sigh_cap);
|
||||
void refresh(int x, int y, int w, int h);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* _FRAMEBUFFER_SESSION_COMPONENT_H_ */
|
40
qt4/src/app/qt_avplay/input_service.cpp
Normal file
40
qt4/src/app/qt_avplay/input_service.cpp
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* \brief Input service
|
||||
* \author Christian Prochaska
|
||||
* \date 2012-03-29
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <input/component.h>
|
||||
|
||||
#include "input_service.h"
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
Event_queue ev_queue;
|
||||
|
||||
|
||||
namespace Input {
|
||||
|
||||
/*
|
||||
* Event handling is disabled on queue creation and will be enabled later if a
|
||||
* session is created.
|
||||
*/
|
||||
void event_handling(bool enable)
|
||||
{
|
||||
if (enable)
|
||||
ev_queue.enable();
|
||||
else
|
||||
ev_queue.disable();
|
||||
}
|
||||
|
||||
bool event_pending() { return !ev_queue.empty(); }
|
||||
Event get_event() { return ev_queue.get(); }
|
||||
}
|
24
qt4/src/app/qt_avplay/input_service.h
Normal file
24
qt4/src/app/qt_avplay/input_service.h
Normal file
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* \brief Input service
|
||||
* \author Christian Prochaska
|
||||
* \date 2012-03-29
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _INPUT_SERVICE_H_
|
||||
#define _INPUT_SERVICE_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <input/event_queue.h>
|
||||
|
||||
extern Event_queue ev_queue;
|
||||
|
||||
extern void create_input_service();
|
||||
|
||||
#endif /* _INPUT_SERVICE_H_ */
|
45
qt4/src/app/qt_avplay/main.cpp
Normal file
45
qt4/src/app/qt_avplay/main.cpp
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* \brief Simple Qt interface for 'avplay' media player
|
||||
* \author Christian Prochaska
|
||||
* \date 2012-03-21
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Qt includes */
|
||||
#include <QApplication>
|
||||
|
||||
/* qt_avplay includes */
|
||||
#include "main_window.h"
|
||||
|
||||
|
||||
static inline void load_stylesheet()
|
||||
{
|
||||
QFile file(":style.qss");
|
||||
if (!file.open(QFile::ReadOnly)) {
|
||||
qWarning() << "Warning:" << file.errorString()
|
||||
<< "opening file" << file.fileName();
|
||||
return;
|
||||
}
|
||||
|
||||
qApp->setStyleSheet(QLatin1String(file.readAll()));
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
|
||||
load_stylesheet();
|
||||
|
||||
QMember<Main_window> main_window;
|
||||
|
||||
main_window->show();
|
||||
|
||||
return app.exec();
|
||||
}
|
129
qt4/src/app/qt_avplay/main_window.cpp
Normal file
129
qt4/src/app/qt_avplay/main_window.cpp
Normal file
@ -0,0 +1,129 @@
|
||||
/*
|
||||
* \brief Main window of the media player
|
||||
* \author Christian Prochaska
|
||||
* \date 2012-03-29
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <cap_session/connection.h>
|
||||
#include <input/component.h>
|
||||
#include <os/config.h>
|
||||
#include <rom_session/connection.h>
|
||||
|
||||
/* qt_avplay includes */
|
||||
#include "avplay_policy.h"
|
||||
#include "filter_framebuffer_policy.h"
|
||||
#include "framebuffer_root.h"
|
||||
#include "input_service.h"
|
||||
#include "main_window.h"
|
||||
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
struct Framebuffer_filter
|
||||
{
|
||||
enum { MAX_FILTER_NAME_SIZE = 32 };
|
||||
char name[MAX_FILTER_NAME_SIZE];
|
||||
Genode::Number_of_bytes ram_quota;
|
||||
|
||||
Service_registry *framebuffer_out_registry;
|
||||
Rpc_entrypoint *ep;
|
||||
Filter_framebuffer_policy *policy;
|
||||
Slave *slave;
|
||||
};
|
||||
|
||||
|
||||
Main_window::Main_window()
|
||||
{
|
||||
/* look for dynamic linker */
|
||||
|
||||
try {
|
||||
static Rom_connection ldso_rom("ld.lib.so");
|
||||
Process::dynamic_linker(ldso_rom.dataspace());
|
||||
} catch (...) {
|
||||
PERR("ld.lib.so not found");
|
||||
}
|
||||
|
||||
/* get the name of the media file from the config file */
|
||||
enum { MAX_LEN_MEDIAFILE_NAME = 256 };
|
||||
static char mediafile[MAX_LEN_MEDIAFILE_NAME] = "mediafile";
|
||||
try {
|
||||
config()->xml_node().sub_node("mediafile").attribute("name").value(mediafile, sizeof(mediafile));
|
||||
} catch(...) {
|
||||
PWRN("no <mediafile> config node found, using \"mediafile\"");
|
||||
}
|
||||
|
||||
/* create local services */
|
||||
|
||||
enum { STACK_SIZE = 2*sizeof(addr_t)*1024 };
|
||||
static Cap_connection cap;
|
||||
static Rpc_entrypoint avplay_ep(&cap, STACK_SIZE, "avplay_ep");
|
||||
static Service_registry input_registry;
|
||||
static Service_registry nitpicker_framebuffer_registry;
|
||||
|
||||
static Input::Root input_root(&avplay_ep, env()->heap());
|
||||
static Local_service input_service(Input::Session::service_name(), &input_root);
|
||||
input_registry.insert(&input_service);
|
||||
avplay_ep.manage(&input_root);
|
||||
|
||||
/* find out which filtering framebuffer services to start and sort them in reverse order */
|
||||
|
||||
static QList<Framebuffer_filter*> framebuffer_filters;
|
||||
try {
|
||||
Xml_node node = config()->xml_node().sub_node("framebuffer_filter");
|
||||
for (; ; node = node.next("framebuffer_filter")) {
|
||||
Framebuffer_filter *framebuffer_filter = new Framebuffer_filter;
|
||||
node.attribute("name").value(framebuffer_filter->name, sizeof(framebuffer_filter->name));
|
||||
node.attribute("ram_quota").value(&framebuffer_filter->ram_quota);
|
||||
qDebug() << "filter:" << framebuffer_filter->name << "," << framebuffer_filter->ram_quota;
|
||||
framebuffer_filters.prepend(framebuffer_filter);
|
||||
}
|
||||
} catch (Config::Invalid) {
|
||||
} catch (Xml_node::Nonexistent_sub_node) {
|
||||
}
|
||||
|
||||
/* start the filtering framebuffer services */
|
||||
|
||||
Service_registry *framebuffer_in_registry = &nitpicker_framebuffer_registry;
|
||||
|
||||
Q_FOREACH(Framebuffer_filter *framebuffer_filter, framebuffer_filters) {
|
||||
framebuffer_filter->framebuffer_out_registry = new Service_registry;
|
||||
framebuffer_filter->ep = new Rpc_entrypoint(&cap, STACK_SIZE, "filter_fb_ep");
|
||||
framebuffer_filter->policy = new Filter_framebuffer_policy(framebuffer_filter->name,
|
||||
*framebuffer_filter->ep,
|
||||
*framebuffer_in_registry,
|
||||
*framebuffer_filter->framebuffer_out_registry);
|
||||
framebuffer_filter->slave = new Slave(*framebuffer_filter->ep,
|
||||
*framebuffer_filter->policy,
|
||||
framebuffer_filter->ram_quota);
|
||||
framebuffer_in_registry = framebuffer_filter->framebuffer_out_registry;
|
||||
}
|
||||
|
||||
Rpc_entrypoint *local_framebuffer_ep = framebuffer_filters.isEmpty() ?
|
||||
&avplay_ep :
|
||||
framebuffer_filters.at(0)->ep;
|
||||
|
||||
static Framebuffer::Root framebuffer_root(local_framebuffer_ep, env()->heap(), *_avplay_widget, 640, 480);
|
||||
static Local_service framebuffer_service(Framebuffer::Session::service_name(), &framebuffer_root);
|
||||
nitpicker_framebuffer_registry.insert(&framebuffer_service);
|
||||
|
||||
/* start avplay */
|
||||
|
||||
static Avplay_policy avplay_policy(avplay_ep, input_registry, *framebuffer_in_registry, mediafile);
|
||||
static Genode::Slave avplay_slave(avplay_ep, avplay_policy, 32*1024*1024);
|
||||
|
||||
/* add widgets to layout */
|
||||
|
||||
_layout->addWidget(_avplay_widget);
|
||||
_layout->addWidget(_control_bar);
|
||||
|
||||
connect(_control_bar, SIGNAL(volume_changed(int)), &avplay_policy, SLOT(volume_changed(int)));
|
||||
}
|
43
qt4/src/app/qt_avplay/main_window.h
Normal file
43
qt4/src/app/qt_avplay/main_window.h
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* \brief Main window of the media player
|
||||
* \author Christian Prochaska
|
||||
* \date 2012-03-29
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _MAIN_WINDOW_H_
|
||||
#define _MAIN_WINDOW_H_
|
||||
|
||||
/* Qt includes */
|
||||
#include <QVBoxLayout>
|
||||
#include <QWidget>
|
||||
#include <qnitpickerviewwidget/qnitpickerviewwidget.h>
|
||||
|
||||
/* Qoost includes */
|
||||
#include <qoost/compound_widget.h>
|
||||
#include <qoost/qmember.h>
|
||||
|
||||
#include "control_bar.h"
|
||||
|
||||
|
||||
class Main_window : public Compound_widget<QWidget, QVBoxLayout>
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
|
||||
QMember<QNitpickerViewWidget> _avplay_widget;
|
||||
QMember<Control_bar> _control_bar;
|
||||
|
||||
public:
|
||||
|
||||
Main_window();
|
||||
};
|
||||
|
||||
#endif /* _MAIN_WINDOW_H_ */
|
12
qt4/src/app/qt_avplay/qt_avplay.pro
Normal file
12
qt4/src/app/qt_avplay/qt_avplay.pro
Normal file
@ -0,0 +1,12 @@
|
||||
TEMPLATE = app
|
||||
TARGET = qt_avplay
|
||||
QT = core gui xml
|
||||
HEADERS = avplay_policy.h \
|
||||
control_bar.h \
|
||||
main_window.h
|
||||
SOURCES = control_bar.cpp \
|
||||
framebuffer_session_component.cc \
|
||||
input_service.cpp \
|
||||
main.cpp \
|
||||
main_window.cpp
|
||||
RESOURCES = style.qrc
|
10
qt4/src/app/qt_avplay/style.qrc
Normal file
10
qt4/src/app/qt_avplay/style.qrc
Normal file
@ -0,0 +1,10 @@
|
||||
<!DOCTYPE RCC>
|
||||
<RCC version="1.0">
|
||||
<qresource prefix="/">
|
||||
<file>style.qss</file>
|
||||
<file alias="player_play.png">../../../contrib/qt-everywhere-opensource-src-4.7.4/examples/network/torrent/icons/player_play.png</file>
|
||||
<file alias="player_pause.png">../../../contrib/qt-everywhere-opensource-src-4.7.4/examples/network/torrent/icons/player_pause.png</file>
|
||||
<file alias="player_stop.png">../../../contrib/qt-everywhere-opensource-src-4.7.4/examples/network/torrent/icons/player_stop.png</file>
|
||||
<file alias="volume.png">../../../contrib/qt-everywhere-opensource-src-4.7.4/demos/mobile/guitartuner/src/mycomponents/images/volume.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
32
qt4/src/app/qt_avplay/style.qss
Normal file
32
qt4/src/app/qt_avplay/style.qss
Normal file
@ -0,0 +1,32 @@
|
||||
Main_window {
|
||||
max-width: 640px;
|
||||
max-height: 512px;
|
||||
}
|
||||
|
||||
Play_pause_button, Stop_button {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
Play_pause_button#play {
|
||||
border-image: url(:player_pause.png);
|
||||
}
|
||||
|
||||
|
||||
Play_pause_button#pause {
|
||||
border-image: url(:player_play.png);
|
||||
}
|
||||
|
||||
|
||||
Stop_button {
|
||||
border-image: url(:player_stop.png);
|
||||
}
|
||||
|
||||
Volume_label {
|
||||
background-image: url(:volume.png);
|
||||
min-width: 16px;
|
||||
max-width: 32px;
|
||||
min-height: 16px;
|
||||
max-height: 32px;
|
||||
margin-right: 5px;
|
||||
}
|
9
qt4/src/app/qt_avplay/target.mk
Normal file
9
qt4/src/app/qt_avplay/target.mk
Normal file
@ -0,0 +1,9 @@
|
||||
# identify the qt4 repository by searching for a file that is unique for qt4
|
||||
QT4_REP_DIR := $(call select_from_repositories,lib/import/import-qt4.inc)
|
||||
QT4_REP_DIR := $(realpath $(dir $(QT4_REP_DIR))../..)
|
||||
|
||||
include $(QT4_REP_DIR)/src/app/tmpl/target_defaults.inc
|
||||
|
||||
include $(QT4_REP_DIR)/src/app/tmpl/target_final.inc
|
||||
|
||||
LIBS += qnitpickerviewwidget
|
Loading…
x
Reference in New Issue
Block a user