-audiodev option
Subsystems (5)
v3 cover -audiodev option
This series of patches adds a new -audiodev command line option to specify audio subsytem parameters instead of environment variables. This will later allow us to specify multiple audio backends. The syntax is something like this:
-audiodev driver_name,id=id,property=value,...
like:
-audiodev alsa,id=foo,frequency=8000,channels=1
This series also convert numa and netdev qapi to flat unions, to avoid extra complexity in OptsVisitor. Please refer to the thread at v2 patch.
You are encouraged check whether I break anything during the refactorings (especially at netdev and various audio backends). For easier testing, pull https://github.com/DirtYiCE/qemu.git tag audio-cmdline-v3.
Please review (especially the qapi refactoring I did...)
Changes from v2:
* consistency, style issues in audio qapi
* converted NumaOptions and Netdev and friends to flat union
* OptsVisitor: only full paths accepted
* qemu_opts_print: hopefully produces valid command line in all cases
* other small fixes...
Changes from v1:
* updated to master, removed commits already merged
* now every time-related option takes usecs
* some small fixes
Kővágó, Zoltán (8):
qapi: support implicit structs in OptsVisitor
qapi: convert NumaOptions into a flat union
qapi: change Netdev and NetLegacy into a flat union
qapi: qapi for audio backends
qapi: support nested structs in OptsVisitor
opts: produce valid command line in qemu_opts_print
audio: use qapi AudioFormat instead of audfmt_e
audio: -audiodev command line option
Makefile | 4 +- audio/Makefile.objs | 2 +- audio/alsaaudio.c | 346 +++++--------- audio/audio.c | 792 +++++++++----------------------- audio/audio.h | 34 +- audio/audio_int.h | 7 +- audio/audio_legacy.c | 328 +++++++++++++ audio/audio_template.h | 13 +- audio/audio_win_int.c | 18 +- audio/coreaudio.c | 49 +- audio/dsound_template.h | 6 +- audio/dsoundaudio.c | 60 +-- audio/noaudio.c | 3 +- audio/ossaudio.c | 182 +++----- audio/paaudio.c | 108 ++--- audio/sdlaudio.c | 50 +- audio/spiceaudio.c | 11 +- audio/wavaudio.c | 75 +-- audio/wavcapture.c | 2 +- block.c | 2 +- hw/arm/musicpal.c | 2 +- hw/arm/omap2.c | 2 +- hw/audio/ac97.c | 2 +- hw/audio/adlib.c | 2 +- hw/audio/cs4231a.c | 6 +- hw/audio/es1370.c | 4 +- hw/audio/gus.c | 2 +- hw/audio/hda-codec.c | 18 +- hw/audio/lm4549.c | 6 +- hw/audio/milkymist-ac97.c | 2 +- hw/audio/pcspk.c | 2 +- hw/audio/sb16.c | 14 +- hw/audio/wm8750.c | 4 +- hw/core/qdev-properties-system.c | 2 +- hw/input/tsc210x.c | 2 +- hw/net/allwinner_emac.c | 2 +- hw/net/cadence_gem.c | 2 +- hw/net/dp8393x.c | 2 +- hw/net/e1000.c | 2 +- hw/net/eepro100.c | 2 +- hw/net/etraxfs_eth.c | 2 +- hw/net/fsl_etsec/etsec.c | 2 +- hw/net/lan9118.c | 2 +- hw/net/lance.c | 2 +- hw/net/mcf_fec.c | 2 +- hw/net/milkymist-minimac2.c | 2 +- hw/net/mipsnet.c | 2 +- hw/net/ne2000-isa.c | 2 +- hw/net/ne2000.c | 2 +- hw/net/opencores_eth.c | 2 +- hw/net/pcnet-pci.c | 2 +- hw/net/rocker/rocker_fp.c | 2 +- hw/net/rtl8139.c | 2 +- hw/net/smc91c111.c | 2 +- hw/net/spapr_llan.c | 2 +- hw/net/stellaris_enet.c | 2 +- hw/net/vhost_net.c | 18 +- hw/net/virtio-net.c | 6 +- hw/net/vmxnet3.c | 2 +- hw/net/xen_nic.c | 2 +- hw/net/xgmac.c | 2 +- hw/net/xilinx_axienet.c | 2 +- hw/net/xilinx_ethlite.c | 2 +- hw/usb/dev-audio.c | 2 +- hw/usb/dev-network.c | 2 +- include/net/net.h | 4 +- monitor.c | 14 +- net/clients.h | 20 +- net/dump.c | 9 +- net/hub.c | 24 +- net/l2tpv3.c | 9 +- net/net.c | 110 ++--- net/netmap.c | 6 +- net/slirp.c | 9 +- net/socket.c | 11 +- net/tap-win32.c | 9 +- net/tap.c | 29 +- net/vde.c | 9 +- net/vhost-user.c | 15 +- numa.c | 2 +- qapi-schema.json | 153 ++++-- qapi/audio.json | 250 ++++++++++ qapi/opts-visitor.c | 129 +++++- qemu-options.hx | 230 +++++++++- tests/qapi-schema/qapi-schema-test.json | 9 +- tests/test-opts-visitor.c | 34 ++ ui/vnc.c | 14 +- util/qemu-option.c | 47 +- vl.c | 9 +- 89 files changed, 1876 insertions(+), 1521 deletions(-) create mode 100644 audio/audio_legacy.c create mode 100644 qapi/audio.json
Signature · 1 line
2.4.3
PATCH v3 1/8 qapi: support implicit structs in OptsVisitor
They are required for flat unions (you still have to allocate the structs).
--- qapi/opts-visitor.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
qapi/opts-visitor.c +15 -0
@@ -149,6 +149,12 @@ opts_start_struct(Visitor *v, void **obj, const char *kind, } } +static void +opts_start_implicit_struct (Visitor *v,void **obj,size_t size,Error **errp) +{ +opts_start_struct (v, obj,NULL ,NULL , size, errp); +} +static gboolean ghr_true (gpointer ign_key,gpointer ign_value,gpointer ign_user_data)
@@ -185,6 +191,12 @@ opts_end_struct(Visitor *v, Error **errp) ov->fake_id_opt =NULL ; } +static void +opts_end_implicit_struct (Visitor *v,Error **errp) +{ +opts_end_struct (v, errp); +} +static GQueue *lookup_distinct (const OptsVisitor *ov,const char *name,Error **errp)
@@ -508,6 +520,9 @@ opts_visitor_new(const QemuOpts *opts) ov->visitor.start_struct = &opts_start_struct; ov->visitor.end_struct = &opts_end_struct; + ov->visitor.start_implicit_struct = &opts_start_implicit_struct; + ov->visitor.end_implicit_struct = &opts_end_implicit_struct; + ov->visitor.start_list = &opts_start_list; ov->visitor.next_list = &opts_next_list; ov->visitor.end_list = &opts_end_list;
Signature · 1 line
2.4.3
PATCH v3 2/8 qapi: convert NumaOptions into a flat union
In reply to Kővágó, Zoltán--- numa.c | 2 +- qapi-schema.json | 47 ++++++++++++++++++++++++++++++++++++----------- 2 files changed, 37 insertions(+), 12 deletions(-)
numa.c +1 -1
@@ -141,7 +141,7 @@ static int parse_numa(void *opaque, QemuOpts *opts, Error **errp) }switch (object->kind) { -case NUMA_OPTIONS_KIND_NODE : +case NUMA_DRIVER_NODE :numa_node_parse (object->node, opts, &err);if (err) { goto error;
qapi-schema.json +36 -11
59 lines not on this page · raw message
Signature · 1 line
2.4.3
PATCH v3 3/8 qapi: change Netdev and NetLegacy into a flat union
In reply to Kővágó, Zoltán--- hw/arm/musicpal.c | 2 +- hw/core/qdev-properties-system.c | 2 +- hw/net/allwinner_emac.c | 2 +- hw/net/cadence_gem.c | 2 +- hw/net/dp8393x.c | 2 +- hw/net/e1000.c | 2 +- hw/net/eepro100.c | 2 +- hw/net/etraxfs_eth.c | 2 +- hw/net/fsl_etsec/etsec.c | 2 +- hw/net/lan9118.c | 2 +- hw/net/lance.c | 2 +- hw/net/mcf_fec.c | 2 +- hw/net/milkymist-minimac2.c | 2 +- hw/net/mipsnet.c | 2 +- hw/net/ne2000-isa.c | 2 +- hw/net/ne2000.c | 2 +- hw/net/opencores_eth.c | 2 +- hw/net/pcnet-pci.c | 2 +- hw/net/rocker/rocker_fp.c | 2 +- hw/net/rtl8139.c | 2 +- hw/net/smc91c111.c | 2 +- hw/net/spapr_llan.c | 2 +- hw/net/stellaris_enet.c | 2 +- hw/net/vhost_net.c | 18 +++---- hw/net/virtio-net.c | 6 +-- hw/net/vmxnet3.c | 2 +- hw/net/xen_nic.c | 2 +- hw/net/xgmac.c | 2 +- hw/net/xilinx_axienet.c | 2 +- hw/net/xilinx_ethlite.c | 2 +- hw/usb/dev-network.c | 2 +- include/net/net.h | 4 +- monitor.c | 14 ++--- net/clients.h | 20 +++---- net/dump.c | 9 ++-- net/hub.c | 24 ++++----- net/l2tpv3.c | 9 ++-- net/net.c | 110 +++++++++++++++++++-------------------- net/netmap.c | 6 +-- net/slirp.c | 9 ++-- net/socket.c | 11 ++-- net/tap-win32.c | 9 ++-- net/tap.c | 29 +++++------ net/vde.c | 9 ++-- net/vhost-user.c | 15 +++--- qapi-schema.json | 103 +++++++++++++++++++++++++----------- 46 files changed, 239 insertions(+), 224 deletions(-)
hw/arm/musicpal.c +1 -1
@@ -379,7 +379,7 @@ static void eth_cleanup(NetClientState *nc) }static NetClientInfo net_mv88w8618_info = { - .type =NET_CLIENT_OPTIONS_KIND_NIC , + .type =NET_CLIENT_DRIVER_NIC , .size =sizeof (NICState), .can_receive = eth_can_receive, .receive = eth_receive,
hw/core/qdev-properties-system.c +1 -1
@@ -213,7 +213,7 @@ static void set_netdev(Object *obj, Visitor *v, void *opaque, } queues =qemu_find_net_clients_except (str, peers, -NET_CLIENT_OPTIONS_KIND_NIC , +NET_CLIENT_DRIVER_NIC ,MAX_QUEUE_NUM );if (queues ==0 ) { err = -ENOENT ;
hw/net/allwinner_emac.c +1 -1
@@ -422,7 +422,7 @@ static const MemoryRegionOps aw_emac_mem_ops = { };static NetClientInfo net_aw_emac_info = { - .type =NET_CLIENT_OPTIONS_KIND_NIC , + .type =NET_CLIENT_DRIVER_NIC , .size =sizeof (NICState), .can_receive = aw_emac_can_receive, .receive = aw_emac_receive,
hw/net/cadence_gem.c +1 -1
@@ -1175,7 +1175,7 @@ static void gem_set_link(NetClientState *nc) }static NetClientInfo net_gem_info = { - .type =NET_CLIENT_OPTIONS_KIND_NIC , + .type =NET_CLIENT_DRIVER_NIC , .size =sizeof (NICState), .can_receive = gem_can_receive, .receive = gem_receive,
hw/net/dp8393x.c +1 -1
@@ -807,7 +807,7 @@ static void dp8393x_reset(DeviceState *dev) }static NetClientInfo net_dp83932_info = { - .type =NET_CLIENT_OPTIONS_KIND_NIC , + .type =NET_CLIENT_DRIVER_NIC , .size =sizeof (NICState), .can_receive = dp8393x_can_receive, .receive = dp8393x_receive,
hw/net/e1000.c +1 -1
@@ -1512,7 +1512,7 @@ pci_e1000_uninit(PCIDevice *dev) }static NetClientInfo net_e1000_info = { - .type =NET_CLIENT_OPTIONS_KIND_NIC , + .type =NET_CLIENT_DRIVER_NIC , .size =sizeof (NICState), .can_receive = e1000_can_receive, .receive = e1000_receive,
hw/net/eepro100.c +1 -1
@@ -1842,7 +1842,7 @@ static void pci_nic_uninit(PCIDevice *pci_dev) }static NetClientInfo net_eepro100_info = { - .type =NET_CLIENT_OPTIONS_KIND_NIC , + .type =NET_CLIENT_DRIVER_NIC , .size =sizeof (NICState), .can_receive = nic_can_receive, .receive = nic_receive,
hw/net/etraxfs_eth.c +1 -1
@@ -582,7 +582,7 @@ static const MemoryRegionOps eth_ops = { };static NetClientInfo net_etraxfs_info = { - .type =NET_CLIENT_OPTIONS_KIND_NIC , + .type =NET_CLIENT_DRIVER_NIC , .size =sizeof (NICState), .can_receive = eth_can_receive, .receive = eth_receive,
hw/net/fsl_etsec/etsec.c +1 -1
@@ -368,7 +368,7 @@ static void etsec_set_link_status(NetClientState *nc) }static NetClientInfo net_etsec_info = { - .type =NET_CLIENT_OPTIONS_KIND_NIC , + .type =NET_CLIENT_DRIVER_NIC , .size =sizeof (NICState), .can_receive = etsec_can_receive, .receive = etsec_receive,
hw/net/lan9118.c +1 -1
@@ -1310,7 +1310,7 @@ static const MemoryRegionOps lan9118_16bit_mem_ops = { };static NetClientInfo net_lan9118_info = { - .type =NET_CLIENT_OPTIONS_KIND_NIC , + .type =NET_CLIENT_DRIVER_NIC , .size =sizeof (NICState), .can_receive = lan9118_can_receive, .receive = lan9118_receive,
hw/net/lance.c +1 -1
@@ -92,7 +92,7 @@ static const MemoryRegionOps lance_mem_ops = { };static NetClientInfo net_lance_info = { - .type =NET_CLIENT_OPTIONS_KIND_NIC , + .type =NET_CLIENT_DRIVER_NIC , .size =sizeof (NICState), .can_receive = pcnet_can_receive, .receive = pcnet_receive,
hw/net/mcf_fec.c +1 -1
@@ -440,7 +440,7 @@ static const MemoryRegionOps mcf_fec_ops = { };static NetClientInfo net_mcf_fec_info = { - .type =NET_CLIENT_OPTIONS_KIND_NIC , + .type =NET_CLIENT_DRIVER_NIC , .size =sizeof (NICState), .can_receive = mcf_fec_can_receive, .receive = mcf_fec_receive,
hw/net/milkymist-minimac2.c +1 -1
@@ -443,7 +443,7 @@ static void milkymist_minimac2_reset(DeviceState *d) }static NetClientInfo net_milkymist_minimac2_info = { - .type =NET_CLIENT_OPTIONS_KIND_NIC , + .type =NET_CLIENT_DRIVER_NIC , .size =sizeof (NICState), .can_receive = minimac2_can_rx, .receive = minimac2_rx,
hw/net/mipsnet.c +1 -1
@@ -212,7 +212,7 @@ static const VMStateDescription vmstate_mipsnet = { };static NetClientInfo net_mipsnet_info = { - .type =NET_CLIENT_OPTIONS_KIND_NIC , + .type =NET_CLIENT_DRIVER_NIC , .size =sizeof (NICState), .can_receive = mipsnet_can_receive, .receive = mipsnet_receive,
hw/net/ne2000-isa.c +1 -1
@@ -42,7 +42,7 @@ typedef struct ISANE2000State { } ISANE2000State;static NetClientInfo net_ne2000_isa_info = { - .type =NET_CLIENT_OPTIONS_KIND_NIC , + .type =NET_CLIENT_DRIVER_NIC , .size =sizeof (NICState), .can_receive = ne2000_can_receive, .receive = ne2000_receive,
hw/net/ne2000.c +1 -1
@@ -703,7 +703,7 @@ void ne2000_setup_io(NE2000State *s, DeviceState *dev, unsigned size) }static NetClientInfo net_ne2000_info = { - .type =NET_CLIENT_OPTIONS_KIND_NIC , + .type =NET_CLIENT_DRIVER_NIC , .size =sizeof (NICState), .can_receive = ne2000_can_receive, .receive = ne2000_receive,
hw/net/opencores_eth.c +1 -1
@@ -473,7 +473,7 @@ static ssize_t open_eth_receive(NetClientState *nc, }static NetClientInfo net_open_eth_info = { - .type =NET_CLIENT_OPTIONS_KIND_NIC , + .type =NET_CLIENT_DRIVER_NIC , .size =sizeof (NICState), .can_receive = open_eth_can_receive, .receive = open_eth_receive,
hw/net/pcnet-pci.c +1 -1
@@ -271,7 +271,7 @@ static void pci_pcnet_uninit(PCIDevice *dev) }static NetClientInfo net_pci_pcnet_info = { - .type =NET_CLIENT_OPTIONS_KIND_NIC , + .type =NET_CLIENT_DRIVER_NIC , .size =sizeof (NICState), .can_receive = pcnet_can_receive, .receive = pcnet_receive,
hw/net/rocker/rocker_fp.c +1 -1
@@ -163,7 +163,7 @@ static void fp_port_set_link_status(NetClientState *nc) }static NetClientInfo fp_port_info = { - .type =NET_CLIENT_OPTIONS_KIND_NIC , + .type =NET_CLIENT_DRIVER_NIC , .size =sizeof (NICState), .can_receive = fp_port_can_receive, .receive = fp_port_receive,
hw/net/rtl8139.c +1 -1
@@ -3445,7 +3445,7 @@ static void rtl8139_set_link_status(NetClientState *nc) }static NetClientInfo net_rtl8139_info = { - .type =NET_CLIENT_OPTIONS_KIND_NIC , + .type =NET_CLIENT_DRIVER_NIC , .size =sizeof (NICState), .can_receive = rtl8139_can_receive, .receive = rtl8139_receive,
hw/net/smc91c111.c +1 -1
@@ -737,7 +737,7 @@ static const MemoryRegionOps smc91c111_mem_ops = { };static NetClientInfo net_smc91c111_info = { - .type =NET_CLIENT_OPTIONS_KIND_NIC , + .type =NET_CLIENT_DRIVER_NIC , .size =sizeof (NICState), .can_receive = smc91c111_can_receive, .receive = smc91c111_receive,
hw/net/spapr_llan.c +1 -1
@@ -188,7 +188,7 @@ static ssize_t spapr_vlan_receive(NetClientState *nc, const uint8_t *buf, }static NetClientInfo net_spapr_vlan_info = { - .type =NET_CLIENT_OPTIONS_KIND_NIC , + .type =NET_CLIENT_DRIVER_NIC , .size =sizeof (NICState), .can_receive = spapr_vlan_can_receive, .receive = spapr_vlan_receive,
hw/net/stellaris_enet.c +1 -1
@@ -452,7 +452,7 @@ static void stellaris_enet_reset(stellaris_enet_state *s) }static NetClientInfo net_stellaris_enet_info = { - .type =NET_CLIENT_OPTIONS_KIND_NIC , + .type =NET_CLIENT_DRIVER_NIC , .size =sizeof (NICState), .can_receive = stellaris_enet_can_receive, .receive = stellaris_enet_receive,
hw/net/vhost_net.c +9 -9
@@ -94,10 +94,10 @@ static const int *vhost_net_get_feature_bits(struct vhost_net *net)const int *feature_bits =0 ;switch (net->nc->info->type) { -case NET_CLIENT_OPTIONS_KIND_TAP : +case NET_CLIENT_DRIVER_TAP : feature_bits = kernel_feature_bits;break ; -case NET_CLIENT_OPTIONS_KIND_VHOST_USER : +case NET_CLIENT_DRIVER_VHOST_USER : feature_bits = user_feature_bits;break ;default :
@@ -124,7 +124,7 @@ void vhost_net_ack_features(struct vhost_net *net, uint64_t features)static int vhost_net_get_fd (NetClientState *backend) {switch (backend->info->type) { -case NET_CLIENT_OPTIONS_KIND_TAP : +case NET_CLIENT_DRIVER_TAP :return tap_get_fd (backend);default :fprintf (stderr,"vhost-net requires tap backend\n" );
@@ -220,7 +220,7 @@ static int vhost_net_start_one(struct vhost_net *net, net->nc->info->poll (net->nc, false); } -if (net->nc->info->type ==NET_CLIENT_OPTIONS_KIND_TAP ) { +if (net->nc->info->type ==NET_CLIENT_DRIVER_TAP ) {qemu_set_fd_handler (net->backend,NULL ,NULL ,NULL ); file.fd = net->backend;for (file.index =0 ; file.index < net->dev.nvqs; ++file.index) {
@@ -236,7 +236,7 @@ static int vhost_net_start_one(struct vhost_net *net,return 0 ; fail: file.fd =-1 ; -if (net->nc->info->type ==NET_CLIENT_OPTIONS_KIND_TAP ) { +if (net->nc->info->type ==NET_CLIENT_DRIVER_TAP ) {while (file.index-- >0 ) {const VhostOps *vhost_ops = net->dev.vhost_ops; int r = vhost_ops->vhost_call(&net->dev, VHOST_NET_SET_BACKEND,
@@ -259,14 +259,14 @@ static void vhost_net_stop_one(struct vhost_net *net, {struct vhost_vring_file file = { .fd =-1 }; -if (net->nc->info->type ==NET_CLIENT_OPTIONS_KIND_TAP ) { +if (net->nc->info->type ==NET_CLIENT_DRIVER_TAP ) {for (file.index =0 ; file.index < net->dev.nvqs; ++file.index) {const VhostOps *vhost_ops = net->dev.vhost_ops;int r = vhost_ops->vhost_call (&net->dev,VHOST_NET_SET_BACKEND , &file);assert (r >=0 ); } - }else if (net->nc->info->type ==NET_CLIENT_OPTIONS_KIND_VHOST_USER ) { + }else if (net->nc->info->type ==NET_CLIENT_DRIVER_VHOST_USER ) {for (file.index =0 ; file.index < net->dev.nvqs; ++file.index) {const VhostOps *vhost_ops = net->dev.vhost_ops; int r = vhost_ops->vhost_call(&net->dev, VHOST_RESET_OWNER,
@@ -393,10 +393,10 @@ VHostNetState *get_vhost_net(NetClientState *nc) }switch (nc->info->type) { -case NET_CLIENT_OPTIONS_KIND_TAP : +case NET_CLIENT_DRIVER_TAP : vhost_net =tap_get_vhost_net (nc);break ; -case NET_CLIENT_OPTIONS_KIND_VHOST_USER : +case NET_CLIENT_DRIVER_VHOST_USER : vhost_net =vhost_user_get_vhost_net (nc);break ;default :
hw/net/virtio-net.c +3 -3
@@ -402,7 +402,7 @@ static int peer_attach(VirtIONet *n, int index)return 0 ; } -if (nc->peer->info->type !=NET_CLIENT_OPTIONS_KIND_TAP ) { +if (nc->peer->info->type !=NET_CLIENT_DRIVER_TAP ) {return 0 ; }
@@ -417,7 +417,7 @@ static int peer_detach(VirtIONet *n, int index)return 0 ; } -if (nc->peer->info->type !=NET_CLIENT_OPTIONS_KIND_TAP ) { +if (nc->peer->info->type !=NET_CLIENT_DRIVER_TAP ) {return 0 ; }
@@ -1505,7 +1505,7 @@ static int virtio_net_load_device(VirtIODevice *vdev, QEMUFile *f, }static NetClientInfo net_virtio_info = { - .type =NET_CLIENT_OPTIONS_KIND_NIC , + .type =NET_CLIENT_DRIVER_NIC , .size =sizeof (NICState), .can_receive = virtio_net_can_receive, .receive = virtio_net_receive,
hw/net/vmxnet3.c +1 -1
@@ -1927,7 +1927,7 @@ static void vmxnet3_set_link_status(NetClientState *nc) }static NetClientInfo net_vmxnet3_info = { - .type =NET_CLIENT_OPTIONS_KIND_NIC , + .type =NET_CLIENT_DRIVER_NIC , .size =sizeof (NICState), .can_receive = vmxnet3_can_receive, .receive = vmxnet3_receive,
hw/net/xen_nic.c +1 -1
@@ -302,7 +302,7 @@ static ssize_t net_rx_packet(NetClientState *nc, const uint8_t *buf, size_t size/* ------------------------------------------------------------- */ static NetClientInfo net_xen_info = { - .type =NET_CLIENT_OPTIONS_KIND_NIC , + .type =NET_CLIENT_DRIVER_NIC , .size =sizeof (NICState), .can_receive = net_rx_ok, .receive = net_rx_packet,
hw/net/xgmac.c +1 -1
@@ -369,7 +369,7 @@ out: }static NetClientInfo net_xgmac_enet_info = { - .type =NET_CLIENT_OPTIONS_KIND_NIC , + .type =NET_CLIENT_DRIVER_NIC , .size =sizeof (NICState), .can_receive = eth_can_rx, .receive = eth_rx,
hw/net/xilinx_axienet.c +1 -1
@@ -924,7 +924,7 @@ xilinx_axienet_data_stream_push(StreamSlave *obj, uint8_t *buf, size_t size) }static NetClientInfo net_xilinx_enet_info = { - .type =NET_CLIENT_OPTIONS_KIND_NIC , + .type =NET_CLIENT_DRIVER_NIC , .size =sizeof (NICState), .can_receive = eth_can_rx, .receive = eth_rx,
hw/net/xilinx_ethlite.c +1 -1
@@ -214,7 +214,7 @@ static void xilinx_ethlite_reset(DeviceState *dev) }static NetClientInfo net_xilinx_ethlite_info = { - .type =NET_CLIENT_OPTIONS_KIND_NIC , + .type =NET_CLIENT_DRIVER_NIC , .size =sizeof (NICState), .can_receive = eth_can_rx, .receive = eth_rx,
hw/usb/dev-network.c +1 -1
@@ -1341,7 +1341,7 @@ static void usb_net_handle_destroy(USBDevice *dev) }static NetClientInfo net_usbnet_info = { - .type =NET_CLIENT_OPTIONS_KIND_NIC , + .type =NET_CLIENT_DRIVER_NIC , .size =sizeof (NICState), .can_receive = usbnet_can_receive, .receive = usbnet_receive,
include/net/net.h +2 -2
@@ -57,7 +57,7 @@ typedef void (SetOffload)(NetClientState *, int, int, int, int, int);typedef void (SetVnetHdrLen )(NetClientState *,int ); typedef struct NetClientInfo { - NetClientOptionsKind type; + NetClientDriver type; size_t size; NetReceive *receive; NetReceive *receive_raw;
@@ -100,7 +100,7 @@ typedef struct NICState {char *qemu_mac_strdup_printf (const uint8_t *macaddr);NetClientState *qemu_find_netdev (const char *id);int qemu_find_net_clients_except (const char *id,NetClientState **ncs, -NetClientOptionsKind type,int max); +NetClientDriver type,int max); NetClientState *qemu_new_net_client(NetClientInfo *info, NetClientState *peer, const char *model,
monitor.c +7 -7
@@ -4199,8 +4199,8 @@ void netdev_add_completion(ReadLineState *rs, int nb_args, const char *str) } len =strlen (str);readline_set_completion_index (rs, len); -for (i =0 ; NetClientOptionsKind_lookup[i]; i++) { -add_completion_option (rs, str, NetClientOptionsKind_lookup[i]); +for (i =0 ; NetClientDriver_lookup[i]; i++) { +add_completion_option (rs, str, NetClientDriver_lookup[i]); } }
@@ -4400,7 +4400,7 @@ void set_link_completion(ReadLineState *rs, int nb_args, const char *str)NetClientState *ncs[MAX_QUEUE_NUM ];int count, i; count =qemu_find_net_clients_except (NULL , ncs, -NET_CLIENT_OPTIONS_KIND_NONE , +NET_CLIENT_DRIVER_NONE ,MAX_QUEUE_NUM );for (i =0 ; i <MIN (count,MAX_QUEUE_NUM ); i++) {const char *name = ncs[i]->name;
@@ -4425,7 +4425,7 @@ void netdev_del_completion(ReadLineState *rs, int nb_args, const char *str) len =strlen (str);readline_set_completion_index (rs, len); - count =qemu_find_net_clients_except (NULL , ncs,NET_CLIENT_OPTIONS_KIND_NIC , + count =qemu_find_net_clients_except (NULL , ncs,NET_CLIENT_DRIVER_NIC ,MAX_QUEUE_NUM );for (i =0 ; i <MIN (count,MAX_QUEUE_NUM ); i++) {QemuOpts *opts;
@@ -4517,7 +4517,7 @@ void host_net_remove_completion(ReadLineState *rs, int nb_args, const char *str)readline_set_completion_index (rs, len);if (nb_args ==2 ) { count =qemu_find_net_clients_except (NULL , ncs, -NET_CLIENT_OPTIONS_KIND_NONE , +NET_CLIENT_DRIVER_NONE ,MAX_QUEUE_NUM );for (i =0 ; i <MIN (count,MAX_QUEUE_NUM ); i++) {int id;
@@ -4534,13 +4534,13 @@ void host_net_remove_completion(ReadLineState *rs, int nb_args, const char *str)return ; }else if (nb_args ==3 ) { count =qemu_find_net_clients_except (NULL , ncs, -NET_CLIENT_OPTIONS_KIND_NIC , +NET_CLIENT_DRIVER_NIC ,MAX_QUEUE_NUM );for (i =0 ; i <MIN (count,MAX_QUEUE_NUM ); i++) {int id;const char *name; -if (ncs[i]->info->type ==NET_CLIENT_OPTIONS_KIND_HUBPORT || +if (ncs[i]->info->type ==NET_CLIENT_DRIVER_HUBPORT ||net_hub_id_for_client (ncs[i], &id)) {continue ; }
net/clients.h +10 -10
@@ -27,39 +27,39 @@#include "net/net.h" #include "qapi-types.h" -int net_init_dump (const NetClientOptions *opts,const char *name, +int net_init_dump (const void *opts,const char *name,NetClientState *peer,Error **errp);#ifdef CONFIG_SLIRP -int net_init_slirp (const NetClientOptions *opts,const char *name, +int net_init_slirp (const void *opts,const char *name,NetClientState *peer,Error **errp);#endif -int net_init_hubport (const NetClientOptions *opts,const char *name, +int net_init_hubport (const void *opts,const char *name,NetClientState *peer,Error **errp); -int net_init_socket (const NetClientOptions *opts,const char *name, +int net_init_socket (const void *opts,const char *name,NetClientState *peer,Error **errp); -int net_init_tap (const NetClientOptions *opts,const char *name, +int net_init_tap (const void *opts,const char *name,NetClientState *peer,Error **errp); -int net_init_bridge (const NetClientOptions *opts,const char *name, +int net_init_bridge (const void *opts,const char *name,NetClientState *peer,Error **errp); -int net_init_l2tpv3 (const NetClientOptions *opts,const char *name, +int net_init_l2tpv3 (const void *opts,const char *name,NetClientState *peer,Error **errp);#ifdef CONFIG_VDE -int net_init_vde (const NetClientOptions *opts,const char *name, +int net_init_vde (const void *opts,const char *name,NetClientState *peer,Error **errp);#endif #ifdef CONFIG_NETMAP -int net_init_netmap (const NetClientOptions *opts,const char *name, +int net_init_netmap (const void *opts,const char *name,NetClientState *peer,Error **errp);#endif -int net_init_vhost_user (const NetClientOptions *opts,const char *name, +int net_init_vhost_user (const void *opts,const char *name,NetClientState *peer,Error **errp);#endif /* QEMU_NET_CLIENTS_H */
net/dump.c +3 -6
@@ -94,7 +94,7 @@ static void dump_cleanup(NetClientState *nc) }static NetClientInfo net_dump_info = { - .type =NET_CLIENT_OPTIONS_KIND_DUMP , + .type =NET_CLIENT_DRIVER_DUMP , .size =sizeof (DumpState), .receive = dump_receive, .cleanup = dump_cleanup,
@@ -146,16 +146,13 @@ static int net_dump_init(NetClientState *peer, const char *device,return 0 ; } -int net_init_dump (const NetClientOptions *opts,const char *name, +int net_init_dump (const void *opts,const char *name,NetClientState *peer,Error **errp) {int len;const char *file;char def_file[128 ]; -const NetdevDumpOptions *dump; - -assert (opts->kind ==NET_CLIENT_OPTIONS_KIND_DUMP ); - dump = opts->dump; +const NetdevDumpOptions *dump = opts;assert (peer);
net/hub.c +11 -13
@@ -130,7 +130,7 @@ static void net_hub_port_cleanup(NetClientState *nc) }static NetClientInfo net_hub_port_info = { - .type =NET_CLIENT_OPTIONS_KIND_HUBPORT , + .type =NET_CLIENT_DRIVER_HUBPORT , .size =sizeof (NetHubPort), .can_receive = net_hub_port_can_receive, .receive = net_hub_port_receive,
@@ -265,10 +265,10 @@ int net_hub_id_for_client(NetClientState *nc, int *id) {NetHubPort *port; -if (nc->info->type ==NET_CLIENT_OPTIONS_KIND_HUBPORT ) { +if (nc->info->type ==NET_CLIENT_DRIVER_HUBPORT ) { port =DO_UPCAST (NetHubPort, nc, nc); }else if (nc->peer !=NULL && nc->peer->info->type == -NET_CLIENT_OPTIONS_KIND_HUBPORT ) { +NET_CLIENT_DRIVER_HUBPORT ) { port =DO_UPCAST (NetHubPort, nc, nc->peer); }else {return -ENOENT ;
@@ -280,14 +280,12 @@ int net_hub_id_for_client(NetClientState *nc, int *id)return 0 ; } -int net_init_hubport (const NetClientOptions *opts,const char *name, +int net_init_hubport (const void *opts,const char *name,NetClientState *peer,Error **errp) { -const NetdevHubPortOptions *hubport; +const NetdevHubPortOptions *hubport = opts; -assert (opts->kind ==NET_CLIENT_OPTIONS_KIND_HUBPORT );assert (!peer); - hubport = opts->hubport;net_hub_add_port (hubport->hubid, name);return 0 ;
@@ -314,14 +312,14 @@ void net_hub_check_clients(void) }switch (peer->info->type) { -case NET_CLIENT_OPTIONS_KIND_NIC : +case NET_CLIENT_DRIVER_NIC : has_nic =1 ;break ; -case NET_CLIENT_OPTIONS_KIND_USER : -case NET_CLIENT_OPTIONS_KIND_TAP : -case NET_CLIENT_OPTIONS_KIND_SOCKET : -case NET_CLIENT_OPTIONS_KIND_VDE : -case NET_CLIENT_OPTIONS_KIND_VHOST_USER : +case NET_CLIENT_DRIVER_USER : +case NET_CLIENT_DRIVER_TAP : +case NET_CLIENT_DRIVER_SOCKET : +case NET_CLIENT_DRIVER_VDE : +case NET_CLIENT_DRIVER_VHOST_USER : has_host_dev =1 ;break ;default :
net/l2tpv3.c +3 -6
@@ -517,7 +517,7 @@ static void net_l2tpv3_cleanup(NetClientState *nc) }static NetClientInfo net_l2tpv3_info = { - .type =NET_CLIENT_OPTIONS_KIND_L2TPV3 , + .type =NET_CLIENT_DRIVER_L2TPV3 , .size =sizeof (NetL2TPV3State), .receive = net_l2tpv3_receive_dgram, .receive_iov = net_l2tpv3_receive_dgram_iov,
@@ -525,12 +525,12 @@ static NetClientInfo net_l2tpv3_info = { .cleanup = net_l2tpv3_cleanup, }; -int net_init_l2tpv3 (const NetClientOptions *opts, +int net_init_l2tpv3 (const void *opts,const char *name,NetClientState *peer,Error **errp) {/* FIXME error_setg(errp, ...) on failure */ -const NetdevL2TPv3Options *l2tpv3; +const NetdevL2TPv3Options *l2tpv3 = opts;NetL2TPV3State *s;NetClientState *nc;int fd =-1 , gairet;
@@ -546,9 +546,6 @@ int net_init_l2tpv3(const NetClientOptions *opts, s->queue_tail =0 ; s->header_mismatch = false; -assert (opts->kind ==NET_CLIENT_OPTIONS_KIND_L2TPV3 ); - l2tpv3 = opts->l2tpv3; -if (l2tpv3->has_ipv6 && l2tpv3->ipv6) { s->ipv6 = l2tpv3->ipv6; }else {
net/net.c +55 -55
286 lines not on this page · raw message
net/netmap.c +3 -3
@@ -417,7 +417,7 @@ static void netmap_set_offload(NetClientState *nc, int csum, int tso4, int tso6,/* NetClientInfo methods */ static NetClientInfo net_netmap_info = { - .type =NET_CLIENT_OPTIONS_KIND_NETMAP , + .type =NET_CLIENT_DRIVER_NETMAP , .size =sizeof (NetmapState), .receive = netmap_receive, .receive_iov = netmap_receive_iov,
@@ -435,11 +435,11 @@ static NetClientInfo net_netmap_info = {* * ... -net netmap,ifname="..." */ -int net_init_netmap (const NetClientOptions *opts, +int net_init_netmap (const void *opts,const char *name,NetClientState *peer,Error **errp) {/* FIXME error_setg(errp, ...) on failure */ -const NetdevNetmapOptions *netmap_opts = opts->netmap; +const NetdevNetmapOptions *netmap_opts = opts;NetClientState *nc;NetmapPriv me;NetmapState *s;
net/slirp.c +3 -6
@@ -125,7 +125,7 @@ static void net_slirp_cleanup(NetClientState *nc) }static NetClientInfo net_slirp_info = { - .type =NET_CLIENT_OPTIONS_KIND_USER , + .type =NET_CLIENT_DRIVER_USER , .size =sizeof (SlirpState), .receive = net_slirp_receive, .cleanup = net_slirp_cleanup,
@@ -735,19 +735,16 @@ static const char **slirp_dnssearch(const StringList *dnsname)return ret; } -int net_init_slirp (const NetClientOptions *opts,const char *name, +int net_init_slirp (const void *opts,const char *name,NetClientState *peer,Error **errp) {/* FIXME error_setg(errp, ...) on failure */ struct slirp_config_str *config;char *vnet;int ret; -const NetdevUserOptions *user; +const NetdevUserOptions *user = opts;const char **dnssearch; -assert (opts->kind ==NET_CLIENT_OPTIONS_KIND_USER ); - user = opts->user; - vnet = user->has_net ?g_strdup (user->net) : user->has_ip ?g_strdup_printf ("%s/24" , user->ip) :NULL ;
net/socket.c +4 -7
@@ -346,7 +346,7 @@ static void net_socket_cleanup(NetClientState *nc) }static NetClientInfo net_dgram_socket_info = { - .type =NET_CLIENT_OPTIONS_KIND_SOCKET , + .type =NET_CLIENT_DRIVER_SOCKET , .size =sizeof (NetSocketState), .receive = net_socket_receive_dgram, .cleanup = net_socket_cleanup,
@@ -429,7 +429,7 @@ static void net_socket_connect(void *opaque) }static NetClientInfo net_socket_info = { - .type =NET_CLIENT_OPTIONS_KIND_SOCKET , + .type =NET_CLIENT_DRIVER_SOCKET , .size =sizeof (NetSocketState), .receive = net_socket_receive, .cleanup = net_socket_cleanup,
@@ -699,15 +699,12 @@ static int net_socket_udp_init(NetClientState *peer,return 0 ; } -int net_init_socket (const NetClientOptions *opts,const char *name, +int net_init_socket (const void *opts,const char *name,NetClientState *peer,Error **errp) {/* FIXME error_setg(errp, ...) on failure */ Error *err =NULL ; -const NetdevSocketOptions *sock; - -assert (opts->kind ==NET_CLIENT_OPTIONS_KIND_SOCKET ); - sock = opts->socket; +const NetdevSocketOptions *sock = opts;if (sock->has_fd + sock->has_listen + sock->has_connect + sock->has_mcast + sock->has_udp !=1 ) {
net/tap-win32.c +3 -6
@@ -713,7 +713,7 @@ static void tap_set_vnet_hdr_len(NetClientState *nc, int len) }static NetClientInfo net_tap_win32_info = { - .type =NET_CLIENT_OPTIONS_KIND_TAP , + .type =NET_CLIENT_DRIVER_TAP , .size =sizeof (TAPState), .receive = tap_receive, .cleanup = tap_cleanup,
@@ -751,14 +751,11 @@ static int tap_win32_init(NetClientState *peer, const char *model,return 0 ; } -int net_init_tap (const NetClientOptions *opts,const char *name, +int net_init_tap (const void *opts,const char *name,NetClientState *peer,Error **errp) {/* FIXME error_setg(errp, ...) on failure */ -const NetdevTapOptions *tap; - -assert (opts->kind ==NET_CLIENT_OPTIONS_KIND_TAP ); - tap = opts->tap; +const NetdevTapOptions *tap = opts;if (!tap->has_ifname) {error_report ("tap: no interface name" );
net/tap.c +12 -17
@@ -221,7 +221,7 @@ static bool tap_has_ufo(NetClientState *nc) {TAPState *s =DO_UPCAST (TAPState, nc, nc); -assert (nc->info->type ==NET_CLIENT_OPTIONS_KIND_TAP ); +assert (nc->info->type ==NET_CLIENT_DRIVER_TAP );return s->has_ufo; }
@@ -230,7 +230,7 @@ static bool tap_has_vnet_hdr(NetClientState *nc) {TAPState *s =DO_UPCAST (TAPState, nc, nc); -assert (nc->info->type ==NET_CLIENT_OPTIONS_KIND_TAP ); +assert (nc->info->type ==NET_CLIENT_DRIVER_TAP );return !!s->host_vnet_hdr_len; }
@@ -239,7 +239,7 @@ static bool tap_has_vnet_hdr_len(NetClientState *nc, int len) {TAPState *s =DO_UPCAST (TAPState, nc, nc); -assert (nc->info->type ==NET_CLIENT_OPTIONS_KIND_TAP ); +assert (nc->info->type ==NET_CLIENT_DRIVER_TAP );return !!tap_probe_vnet_hdr_len (s->fd, len); }
@@ -248,7 +248,7 @@ static void tap_set_vnet_hdr_len(NetClientState *nc, int len) {TAPState *s =DO_UPCAST (TAPState, nc, nc); -assert (nc->info->type ==NET_CLIENT_OPTIONS_KIND_TAP ); +assert (nc->info->type ==NET_CLIENT_DRIVER_TAP );assert (len ==sizeof (struct virtio_net_hdr_mrg_rxbuf ) || len ==sizeof (struct virtio_net_hdr ));
@@ -260,7 +260,7 @@ static void tap_using_vnet_hdr(NetClientState *nc, bool using_vnet_hdr) {TAPState *s =DO_UPCAST (TAPState, nc, nc); -assert (nc->info->type ==NET_CLIENT_OPTIONS_KIND_TAP ); +assert (nc->info->type ==NET_CLIENT_DRIVER_TAP );assert (!!s->host_vnet_hdr_len == using_vnet_hdr); s->using_vnet_hdr = using_vnet_hdr;
@@ -312,14 +312,14 @@ static void tap_poll(NetClientState *nc, bool enable)int tap_get_fd (NetClientState *nc) {TAPState *s =DO_UPCAST (TAPState, nc, nc); -assert (nc->info->type ==NET_CLIENT_OPTIONS_KIND_TAP ); +assert (nc->info->type ==NET_CLIENT_DRIVER_TAP );return s->fd; }/* fd support */ static NetClientInfo net_tap_info = { - .type =NET_CLIENT_OPTIONS_KIND_TAP , + .type =NET_CLIENT_DRIVER_TAP , .size =sizeof (TAPState), .receive = tap_receive, .receive_raw = tap_receive_raw,
@@ -541,17 +541,14 @@ static int net_bridge_run_helper(const char *helper, const char *bridge, } } -int net_init_bridge (const NetClientOptions *opts,const char *name, +int net_init_bridge (const void *opts,const char *name,NetClientState *peer,Error **errp) { -const NetdevBridgeOptions *bridge; +const NetdevBridgeOptions *bridge = opts;const char *helper, *br;TAPState *s;int fd, vnet_hdr; -assert (opts->kind ==NET_CLIENT_OPTIONS_KIND_BRIDGE ); - bridge = opts->bridge; - helper = bridge->has_helper ? bridge->helper :DEFAULT_BRIDGE_HELPER ; br = bridge->has_br ? bridge->br :DEFAULT_BRIDGE_INTERFACE ;
@@ -701,10 +698,10 @@ static int get_fds(char *str, char *fds[], int max)return i; } -int net_init_tap (const NetClientOptions *opts,const char *name, +int net_init_tap (const void *opts,const char *name,NetClientState *peer,Error **errp) { -const NetdevTapOptions *tap; +const NetdevTapOptions *tap = opts;int fd, vnet_hdr =0 , i =0 , queues;/* for the no-fd, no-helper case */ const char *script =NULL ;/* suppress wrong "uninit'd use" gcc warning */
@@ -713,8 +710,6 @@ int net_init_tap(const NetClientOptions *opts, const char *name,const char *vhostfdname;char ifname[128 ]; -assert (opts->kind ==NET_CLIENT_OPTIONS_KIND_TAP ); - tap = opts->tap; queues = tap->has_queues ? tap->queues :1 ; vhostfdname = tap->has_vhostfd ? tap->vhostfd :NULL ;
@@ -875,7 +870,7 @@ int net_init_tap(const NetClientOptions *opts, const char *name,VHostNetState *tap_get_vhost_net (NetClientState *nc) {TAPState *s =DO_UPCAST (TAPState, nc, nc); -assert (nc->info->type ==NET_CLIENT_OPTIONS_KIND_TAP ); +assert (nc->info->type ==NET_CLIENT_DRIVER_TAP );return s->vhost_net; }
net/vde.c +3 -6
@@ -68,7 +68,7 @@ static void vde_cleanup(NetClientState *nc) }static NetClientInfo net_vde_info = { - .type =NET_CLIENT_OPTIONS_KIND_VDE , + .type =NET_CLIENT_DRIVER_VDE , .size =sizeof (VDEState), .receive = vde_receive, .cleanup = vde_cleanup,
@@ -109,14 +109,11 @@ static int net_vde_init(NetClientState *peer, const char *model,return 0 ; } -int net_init_vde (const NetClientOptions *opts,const char *name, +int net_init_vde (const void *opts,const char *name,NetClientState *peer,Error **errp) {/* FIXME error_setg(errp, ...) on failure */ -const NetdevVdeOptions *vde; - -assert (opts->kind ==NET_CLIENT_OPTIONS_KIND_VDE ); - vde = opts->vde; +const NetdevVdeOptions *vde = opts;/* missing optional values have been initialized to "all bits zero" */ if (net_vde_init(peer, "vde", name, vde->sock, vde->port, vde->group,
net/vhost-user.c +6 -9
@@ -30,7 +30,7 @@ typedef struct VhostUserChardevProps {VHostNetState *vhost_user_get_vhost_net (NetClientState *nc) {VhostUserState *s =DO_UPCAST (VhostUserState, nc, nc); -assert (nc->info->type ==NET_CLIENT_OPTIONS_KIND_VHOST_USER ); +assert (nc->info->type ==NET_CLIENT_DRIVER_VHOST_USER );return s->vhost_net; }
@@ -76,20 +76,20 @@ static void vhost_user_cleanup(NetClientState *nc)static bool vhost_user_has_vnet_hdr (NetClientState *nc) { -assert (nc->info->type ==NET_CLIENT_OPTIONS_KIND_VHOST_USER ); +assert (nc->info->type ==NET_CLIENT_DRIVER_VHOST_USER );return true; }static bool vhost_user_has_ufo (NetClientState *nc) { -assert (nc->info->type ==NET_CLIENT_OPTIONS_KIND_VHOST_USER ); +assert (nc->info->type ==NET_CLIENT_DRIVER_VHOST_USER );return true; }static NetClientInfo net_vhost_user_info = { - .type =NET_CLIENT_OPTIONS_KIND_VHOST_USER , + .type =NET_CLIENT_DRIVER_VHOST_USER , .size =sizeof (VhostUserState), .cleanup = vhost_user_cleanup, .has_vnet_hdr = vhost_user_has_vnet_hdr,
@@ -228,16 +228,13 @@ static int net_vhost_check_net(void *opaque, QemuOpts *opts, Error **errp)return 0 ; } -int net_init_vhost_user (const NetClientOptions *opts,const char *name, +int net_init_vhost_user (const void *opts,const char *name,NetClientState *peer,Error **errp) {uint32_t queues; -const NetdevVhostUserOptions *vhost_user_opts; +const NetdevVhostUserOptions *vhost_user_opts = opts;CharDriverState *chr; -assert (opts->kind ==NET_CLIENT_OPTIONS_KIND_VHOST_USER ); - vhost_user_opts = opts->vhost_user; - chr =net_vhost_parse_chardev (vhost_user_opts, errp);if (!chr) {return -1 ;
qapi-schema.json +73 -30
137 lines not on this page · raw message
Signature · 1 line
2.4.3
Re: [Qemu-devel] [PATCH v3 3/8] qapi: change Netdev and NetLegacy into a flat union
Quoted 6 lines · Zoltán
net/tap.c +0
-2@@ -713,8 +710,6 @@ int net_init_tap(const NetClientOptions *opts, const char *name,const char *vhostfdname;char ifname[128 ]; -assert (opts->kind ==NET_CLIENT_OPTIONS_KIND_TAP ); - tap = opts->tap;
...
Quoted 17 lines
net/vde.c +2
-5@@ -109,14 +109,11 @@ static int net_vde_init(NetClientState *peer, const char *model,return 0 ; } -int net_init_vde (const NetClientOptions *opts,const char *name, +int net_init_vde (const void *opts,const char *name,NetClientState *peer,Error **errp) {/* FIXME error_setg(errp, ...) on failure */ -const NetdevVdeOptions *vde; - -assert (opts->kind ==NET_CLIENT_OPTIONS_KIND_VDE ); - vde = opts->vde; +const NetdevVdeOptions *vde = opts;/* missing optional values have been initialized to "all bits zero" */ if (net_vde_init(peer, "vde", name, vde->sock, vde->port, vde->group,
...
Quoted 6 lines
net/vhost-user.c +1
-1@@ -228,16 +228,13 @@ static int net_vhost_check_net(void *opaque, QemuOpts *opts, Error **errp)return 0 ; } -int net_init_vhost_user(const NetClientOptions *opts, const char *name, +int net_init_vhost_user(const void *opts, const char *name,
net/vhost-user.c static int net_vhost_check_net(void *opaque, QemuOpts *opts, Error **errp) · line 240
Quoted 10 lines
net/vhost-user.c +1
-4NetClientState *peer, Error **errp) {uint32_t queues; -const NetdevVhostUserOptions *vhost_user_opts; +const NetdevVhostUserOptions *vhost_user_opts = opts;CharDriverState *chr; -assert (opts->kind ==NET_CLIENT_OPTIONS_KIND_VHOST_USER ); - vhost_user_opts = opts->vhost_user; -
Why drop the assertion?
Re: [Qemu-devel] [PATCH v3 3/8] qapi: change Netdev and NetLegacy into a flat union
2015-06-19 16:06 keltezéssel, Stefan Hajnoczi írta:
Quoted 39 lines · Zoltán
Quoted 6 lines
net/tap.c +0
-2@@ -713,8 +710,6 @@ int net_init_tap(const NetClientOptions *opts, const char *name,const char *vhostfdname;char ifname[128 ]; -assert (opts->kind ==NET_CLIENT_OPTIONS_KIND_TAP ); - tap = opts->tap;...
Quoted 17 lines
net/vde.c +2
-5@@ -109,14 +109,11 @@ static int net_vde_init(NetClientState *peer, const char *model,return 0 ; } -int net_init_vde (const NetClientOptions *opts,const char *name, +int net_init_vde (const void *opts,const char *name,NetClientState *peer,Error **errp) {/* FIXME error_setg(errp, ...) on failure */ -const NetdevVdeOptions *vde; - -assert (opts->kind ==NET_CLIENT_OPTIONS_KIND_VDE ); - vde = opts->vde; +const NetdevVdeOptions *vde = opts;/* missing optional values have been initialized to "all bits zero" */ if (net_vde_init(peer, "vde", name, vde->sock, vde->port, vde->group,...
Quoted 13 lines
net/vhost-user.c +2
-2@@ -228,16 +228,13 @@ static int net_vhost_check_net(void *opaque, QemuOpts *opts, Error **errp)return 0 ; } -int net_init_vhost_user (const NetClientOptions *opts,const char *name, +int net_init_vhost_user (const void *opts,const char *name,NetClientState *peer,Error **errp) {uint32_t queues; -const NetdevVhostUserOptions *vhost_user_opts; +const NetdevVhostUserOptions *vhost_user_opts = opts;CharDriverState *chr;
Quoted 6 lines
net/vhost-user.c static int net_vhost_check_net(void *opaque, QemuOpts *opts, Error **errp) · line 240
Quoted 3 lines
net/vhost-user.c +0
-3-assert (opts->kind ==NET_CLIENT_OPTIONS_KIND_VHOST_USER ); - vhost_user_opts = opts->vhost_user; -Why drop the assertion?
Because otherwise you would have to make a version that gets a Netdev and an other that gets Netlegacy, because the common NetClientOptions is gone. Unless, of course, I'm overlooking something.
(I've actually tried to simply pass the corect type as arguments, like net_init_chost_user(const NetdevVhostUserOptions *opts, ...; but then net_client_init_fun in net.c becomes problematic. Maybe replacing it with a giant swicth-case would be better?)
PATCH v3 4/8 qapi: qapi for audio backends
In reply to Kővágó, ZoltánThis patch adds structures into qapi to replace the existing configuration structures used by audio backends currently. This qapi will be the base of the -audiodev command line parameter (that replaces the old environment variables based config).
This is not a 1:1 translation of the old options, I've tried to make them much more consistent (e.g. almost every backend had an option to specify buffer size, but the name was different for every backend, and some backends required usecs, while some other required frames, samples or bytes). Also tried to reduce the number of abbreviations used by the config keys.
Some of the more important changes:
* use in and out instead of ADC and DAC, as the former is more user friendly imho
* moved buffer settings into the global setting area (so it's the same for all backends that support it. Backends that can't change buffer size will simply ignore them). Also using usecs, as it's probably more user friendly than samples or bytes.
* try-poll is now an alsa and oss backend specific option (as all other backends currently ignore it)
---
Changes from v2 patch:
* documentation fixes
* rename mmap -> try-mmap, buffer -> buffer-len
* id is now required
* converted into flat unions
* renamed alsa's and oss's in an out, because it was incompatible with with flat union
Changes from v1 patch:
* every time-related field now take usecs (and removed -usecs, -millis suffixes)
* fixed inconsisten optional marking, language issues
Changes from v2 RFC patch:
* in, out are no longer optional
* try-poll: moved to alsa and oss (as no other backend used them)
* voices: added (env variables had this option)
* dsound: removed primary buffer related fields
Changes from v1 RFC patch:
* fixed style issues
* moved definitions into a separate file
* documented undocumented options (hopefully)
* removed plive option. It was useless even years ago so it can probably safely go away: https://lists.nongnu.org/archive/html/qemu-devel/2012-03/msg02427.html
* removed verbose, debug options. Backends should use trace events instead.
* removed *_retries options from dsound. It's a kludge.
* moved buffer_usecs and buffer_count to the global config options. Some driver might ignore it (as they do not expose API to change them).
* wav backend: removed frequecy, format, channels as AudiodevPerDirectionOptions already have them.
Makefile | 4 +- qapi-schema.json | 3 + qapi/audio.json | 250 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 255 insertions(+), 2 deletions(-) create mode 100644 qapi/audio.json
Makefile +2 -2
@@ -257,8 +257,8 @@ $(SRC_PATH)/qga/qapi-schema.json $(SRC_PATH)/scripts/qapi-commands.py $(qapi-py) " GEN $@") qapi-modules = $(SRC_PATH)/qapi-schema.json $(SRC_PATH)/qapi/common.json \ - $(SRC_PATH)/qapi/block.json $(SRC_PATH)/qapi/block-core.json \ - $(SRC_PATH)/qapi/event.json + $(SRC_PATH)/qapi/audio.json $(SRC_PATH)/qapi/block.json \ + $(SRC_PATH)/qapi/block-core.json $(SRC_PATH)/qapi/event.json qapi-types.c qapi-types.h :\ $(qapi-modules) $(SRC_PATH)/scripts/qapi-types.py $(qapi-py)
qapi-schema.json +3 -0
@@ -5,6 +5,9 @@ # QAPI common definitions { 'include': 'qapi/common.json' } +# QAPI audio definitions +{ 'include': 'qapi/audio.json' } + # QAPI block definitions { 'include': 'qapi/block.json' }
qapi/audio.json new file +250 -0
250 lines not on this page · raw message
Signature · 1 line
2.4.3
PATCH v3 5/8 qapi: support nested structs in OptsVisitor
In reply to Kővágó, ZoltánThe current OptsVisitor flattens the whole structure, if there are same named fields under different paths (like in' and out' in Audiodev'), the current visitor can't cope with them (for example setting frequency=44100' will set the in's frequency to 44100 and leave out's frequency unspecified).
This patch fixes it, by always requiring a complete path in case of nested structs. Fields in the path are separated by dots, similar to C structs (without pointers), like in.frequency' orout.frequency'.
You must provide a full path even in non-ambigous cases. The previous two commits hopefully ensures that this change doesn't create backward compatibility problems.
---
Change from v2:
* only fully qualified paths are allowed
qapi/opts-visitor.c | 114 ++++++++++++++++++++++++++------ tests/qapi-schema/qapi-schema-test.json | 9 ++- tests/test-opts-visitor.c | 34 ++++++++++ 3 files changed, 135 insertions(+), 22 deletions(-)
qapi/opts-visitor.c +93 -21
@@ -71,6 +71,7 @@ struct OptsVisitor* schema, with a single mandatory scalar member. */ ListMode list_mode;GQueue *repeated_opts; +char *repeated_name;/* When parsing a list of repeating options as integers, values of the form * "a-b", representing a closed interval, are allowed. Elements in the
@@ -86,6 +87,9 @@ struct OptsVisitor* not survive or escape the OptsVisitor object. */ QemuOpt *fake_id_opt; + +/* List of field names leading to the current structure. */ +GQueue *nested_names; };
@@ -100,6 +104,7 @@ static void opts_visitor_insert(GHashTable *unprocessed_opts, const QemuOpt *opt) {GQueue *list; +assert (opt); list =g_hash_table_lookup (unprocessed_opts, opt->name);if (list ==NULL ) {
@@ -127,6 +132,9 @@ opts_start_struct(Visitor *v, void **obj, const char *kind,if (obj) { *obj =g_malloc0 (size >0 ? size :1 ); } + +g_queue_push_tail (ov->nested_names, (gpointer ) name); +if (ov->depth++ >0 ) {return ; }
@@ -169,6 +177,8 @@ opts_end_struct(Visitor *v, Error **errp)OptsVisitor *ov =DO_UPCAST (OptsVisitor, visitor, v);GQueue *any; +g_queue_pop_tail (ov->nested_names); +if (--ov->depth >0 ) {return ; }
@@ -198,15 +208,54 @@ opts_end_implicit_struct(Visitor *v, Error **errp) } +static void +sum_strlen (gpointer data,gpointer user_data) +{ +const char *str = data; +size_t *sum_len = user_data; + +if (str) {/* skip NULLs */ + *sum_len +=strlen (str) +1 ; + } +} + +static void +append_str (gpointer data,gpointer user_data) +{ +const char *str = data; +char *concat_str = user_data; + +if (str) { +strcat (concat_str, str); +strcat (concat_str,"." ); + } +} + +/* lookup a name, using a fully qualified version */ static GQueue * -lookup_distinct (const OptsVisitor *ov,const char *name,Error **errp) +lookup_distinct (const OptsVisitor *ov,const char *name,char **out_key, +Error **errp) { -GQueue *list; +GQueue *list =NULL ; +char *key; +size_t sum_len =strlen (name); + +g_queue_foreach (ov->nested_names, sum_strlen, &sum_len); + key =g_malloc (sum_len+1 ); + key[0 ] =0 ; +g_queue_foreach (ov->nested_names, append_str, key); +strcat (key, name); + + list =g_hash_table_lookup (ov->unprocessed_opts, key); +if (list && out_key) { + *out_key =g_strdup (key); + } - list =g_hash_table_lookup (ov->unprocessed_opts, name);if (!list) {error_set (errp,QERR_MISSING_PARAMETER , name); } + +g_free (key);return list; }
@@ -218,7 +267,7 @@ opts_start_list(Visitor *v, const char *name, Error **errp)/* we can't traverse a list in a list */ assert (ov->list_mode ==LM_NONE ); - ov->repeated_opts =lookup_distinct (ov, name, errp); + ov->repeated_opts =lookup_distinct (ov, name, &ov->repeated_name, errp);if (ov->repeated_opts !=NULL ) { ov->list_mode =LM_STARTED ; }
@@ -254,11 +303,9 @@ opts_next_list(Visitor *v, GenericList **list, Error **errp)/* range has been completed, fall through in order to pop option */ case LM_IN_PROGRESS : { -const QemuOpt *opt; - - opt =g_queue_pop_head (ov->repeated_opts); +g_queue_pop_head (ov->repeated_opts);if (g_queue_is_empty (ov->repeated_opts)) { -g_hash_table_remove (ov->unprocessed_opts, opt->name); +g_hash_table_remove (ov->unprocessed_opts, ov->repeated_name);return NULL ; } link = &(*list)->next;
@@ -284,22 +331,28 @@ opts_end_list(Visitor *v, Error **errp) ov->list_mode ==LM_SIGNED_INTERVAL || ov->list_mode == LM_UNSIGNED_INTERVAL); ov->repeated_opts =NULL ; + +g_free (ov->repeated_name); + ov->repeated_name =NULL ; + ov->list_mode =LM_NONE ; }static const QemuOpt * -lookup_scalar (const OptsVisitor *ov,const char *name,Error **errp) +lookup_scalar (const OptsVisitor *ov,const char *name,char ** out_key, +Error **errp) {if (ov->list_mode ==LM_NONE ) {GQueue *list;/* the last occurrence of any QemuOpt takes effect when queried by name */ - list =lookup_distinct (ov, name, errp); + list =lookup_distinct (ov, name, out_key, errp);return list ?g_queue_peek_tail (list) :NULL ; }assert (ov->list_mode ==LM_IN_PROGRESS ); +assert (out_key ==NULL || *out_key ==NULL );return g_queue_peek_head (ov->repeated_opts); }
@@ -321,13 +374,15 @@ opts_type_str(Visitor *v, char **obj, const char *name, Error **errp) {OptsVisitor *ov =DO_UPCAST (OptsVisitor, visitor, v);const QemuOpt *opt; +char *key =NULL ; - opt =lookup_scalar (ov, name, errp); + opt =lookup_scalar (ov, name, &key, errp);if (!opt) {return ; } *obj =g_strdup (opt->str ? opt->str :"" ); -processed (ov, name); +processed (ov, key); +g_free (key); }
@@ -337,8 +392,9 @@ opts_type_bool(Visitor *v, bool *obj, const char *name, Error **errp) {OptsVisitor *ov =DO_UPCAST (OptsVisitor, visitor, v);const QemuOpt *opt; +char *key =NULL ; - opt =lookup_scalar (ov, name, errp); + opt =lookup_scalar (ov, name, &key, errp);if (!opt) {return ; }
@@ -355,13 +411,15 @@ opts_type_bool(Visitor *v, bool *obj, const char *name, Error **errp) }else {error_set (errp,QERR_INVALID_PARAMETER_VALUE , opt->name,"on|yes|y|off|no|n" ); +g_free (key);return ; } }else { *obj = true; } -processed (ov, name); +processed (ov, key); +g_free (key); }
@@ -373,13 +431,14 @@ opts_type_int(Visitor *v, int64_t *obj, const char *name, Error **errp)const char *str;long long val;char *endptr; +char *key =NULL ;if (ov->list_mode ==LM_SIGNED_INTERVAL ) { *obj = ov->range_next.s;return ; } - opt =lookup_scalar (ov, name, errp); + opt =lookup_scalar (ov, name, &key, errp);if (!opt) {return ; }
@@ -393,11 +452,13 @@ opts_type_int(Visitor *v, int64_t *obj, const char *name, Error **errp)if (errno ==0 && endptr > str &&INT64_MIN <= val && val <=INT64_MAX ) {if (*endptr =='\0' ) { *obj = val; -processed (ov, name); +processed (ov, key); +g_free (key);return ; }if (*endptr =='-' && ov->list_mode ==LM_IN_PROGRESS ) {long long val2; +assert (key ==NULL ); str = endptr +1 ; val2 =strtoll (str, &endptr,0 );
@@ -418,6 +479,7 @@ opts_type_int(Visitor *v, int64_t *obj, const char *name, Error **errp)error_set (errp,QERR_INVALID_PARAMETER_VALUE , opt->name, (ov->list_mode ==LM_NONE ) ?"an int64 value" :"an int64 value or range" ); +g_free (key); }
@@ -429,13 +491,14 @@ opts_type_uint64(Visitor *v, uint64_t *obj, const char *name, Error **errp)const char *str;unsigned long long val;char *endptr; +char *key =NULL ;if (ov->list_mode ==LM_UNSIGNED_INTERVAL ) { *obj = ov->range_next.u;return ; } - opt =lookup_scalar (ov, name, errp); + opt =lookup_scalar (ov, name, &key, errp);if (!opt) {return ; }
@@ -447,11 +510,13 @@ opts_type_uint64(Visitor *v, uint64_t *obj, const char *name, Error **errp)if (parse_uint (str, &val, &endptr,0 ) ==0 && val <=UINT64_MAX ) {if (*endptr =='\0' ) { *obj = val; -processed (ov, name); +processed (ov, key); +g_free (key);return ; }if (*endptr =='-' && ov->list_mode ==LM_IN_PROGRESS ) {unsigned long long val2; +assert (key ==NULL ); str = endptr +1 ; if (parse_uint_full(str, &val2, 0) == 0 &&
@@ -470,6 +535,7 @@ opts_type_uint64(Visitor *v, uint64_t *obj, const char *name, Error **errp)error_set (errp,QERR_INVALID_PARAMETER_VALUE , opt->name, (ov->list_mode ==LM_NONE ) ?"a uint64 value" :"a uint64 value or range" ); +g_free (key); }
@@ -480,8 +546,9 @@ opts_type_size(Visitor *v, uint64_t *obj, const char *name, Error **errp)const QemuOpt *opt;int64_t val;char *endptr; +char *key =NULL ; - opt =lookup_scalar (ov, name, errp); + opt =lookup_scalar (ov, name, &key, errp);if (!opt) {return ; }
@@ -491,11 +558,13 @@ opts_type_size(Visitor *v, uint64_t *obj, const char *name, Error **errp)if (val <0 || *endptr) {error_set (errp,QERR_INVALID_PARAMETER_VALUE , opt->name,"a size value representible as a non-negative int64" ); +g_free (key);return ; } *obj = val; -processed (ov, name); +processed (ov, key); +g_free (key); }
@@ -506,7 +575,7 @@ opts_optional(Visitor *v, bool *present, const char *name, Error **errp)/* we only support a single mandatory scalar field in a list node */ assert (ov->list_mode ==LM_NONE ); - *present = (lookup_distinct (ov, name,NULL ) !=NULL ); + *present = (lookup_distinct (ov, name,NULL ,NULL ) !=NULL ); }
@@ -517,6 +586,8 @@ opts_visitor_new(const QemuOpts *opts) ov =g_malloc0 (sizeof *ov); + ov->nested_names =g_queue_new (); + ov->visitor.start_struct = &opts_start_struct; ov->visitor.end_struct = &opts_end_struct;
@@ -560,6 +631,7 @@ opts_visitor_cleanup(OptsVisitor *ov)if (ov->unprocessed_opts !=NULL ) {g_hash_table_destroy (ov->unprocessed_opts); } +g_queue_free (ov->nested_names);g_free (ov->fake_id_opt);g_free (ov); }
tests/qapi-schema/qapi-schema-test.json +8 -1
@@ -81,6 +81,11 @@ { 'command': 'user_def_cmd3', 'data': {'a': 'int', '*b': 'int' }, 'returns': 'int' } +# For testing hierarchy support in opts-visitor +{ 'struct': 'UserDefOptionsSub', + 'data': { + '*nint': 'int' } } + # For testing integer range flattening in opts-visitor. The following schema # corresponds to the option format: #
@@ -94,7 +99,9 @@ '*u64' : [ 'uint64' ], '*u16' : [ 'uint16' ], '*i64x': 'int' , - '*u64x': 'uint64' } } + '*u64x': 'uint64' , + 'sub0': 'UserDefOptionsSub', + 'sub1': 'UserDefOptionsSub' } } # testing event { 'struct': 'EventStructOne',
tests/test-opts-visitor.c +34 -0
@@ -177,6 +177,34 @@ expect_u64_max(OptsVisitorFixture *f, gconstpointer test_data)g_assert (f->userdef->u64->value ==UINT64_MAX ); } +static void +expect_both (OptsVisitorFixture *f,gconstpointer test_data) +{ +expect_ok (f, test_data); +g_assert (f->userdef->sub0->has_nint); +g_assert (f->userdef->sub0->nint ==13 ); +g_assert (f->userdef->sub1->has_nint); +g_assert (f->userdef->sub1->nint ==17 ); +} + +static void +expect_sub0 (OptsVisitorFixture *f,gconstpointer test_data) +{ +expect_ok (f, test_data); +g_assert (f->userdef->sub0->has_nint); +g_assert (f->userdef->sub0->nint ==13 ); +g_assert (!f->userdef->sub1->has_nint); +} + +static void +expect_sub1 (OptsVisitorFixture *f,gconstpointer test_data) +{ +expect_ok (f, test_data); +g_assert (!f->userdef->sub0->has_nint); +g_assert (f->userdef->sub1->has_nint); +g_assert (f->userdef->sub1->nint ==13 ); +} +/* test cases */ int
@@ -270,6 +298,12 @@ main(int argc, char **argv)add_test ("/visitor/opts/i64/range/2big/full" , &expect_fail,"i64=-0x8000000000000000-0x7fffffffffffffff" ); +/* Test nested structs support */ +add_test ("/visitor/opts/nested/unqualified" , &expect_fail,"nint=13" ); +add_test ("/visitor/opts/nested/both" , &expect_both, +"sub0.nint=13,sub1.nint=17" ); +add_test ("/visitor/opts/nested/sub0" , &expect_sub0,"sub0.nint=13" ); +add_test ("/visitor/opts/nested/sub1" , &expect_sub1,"sub1.nint=13" );g_test_run ();return 0 ; }
Signature · 1 line
2.4.3
Re: [Qemu-devel] [PATCH v3 5/8] qapi: support nested structs in OptsVisitor
Quoted 433 lines · Zoltán
The current OptsVisitor flattens the whole structure, if there are same named fields under different paths (like
in' andout' inAudiodev'), the current visitor can't cope with them (for example settingfrequency=44100' will set the in's frequency to 44100 and leave out's frequency unspecified).This patch fixes it, by always requiring a complete path in case of nested structs. Fields in the path are separated by dots, similar to C structs (without pointers), like
in.frequency' orout.frequency'.You must provide a full path even in non-ambigous cases. The previous two commits hopefully ensures that this change doesn't create backward compatibility problems.
Signed-off-by Kővágó, Zoltán <[email protected]>---
Change from v2:
* only fully qualified paths are allowedqapi/opts-visitor.c | 114 ++++++++++++++++++++++++++------ tests/qapi-schema/qapi-schema-test.json | 9 ++- tests/test-opts-visitor.c | 34 ++++++++++ 3 files changed, 135 insertions(+), 22 deletions(-)qapi/opts-visitor.c +93
-21@@ -71,6 +71,7 @@ struct OptsVisitor* schema, with a single mandatory scalar member. */ ListMode list_mode;GQueue *repeated_opts; +char *repeated_name;/* When parsing a list of repeating options as integers, values of the form * "a-b", representing a closed interval, are allowed. Elements in the @@ -86,6 +87,9 @@ struct OptsVisitor* not survive or escape the OptsVisitor object. */ QemuOpt *fake_id_opt; + +/* List of field names leading to the current structure. */ +GQueue *nested_names; };@@ -100,6 +104,7 @@ static void opts_visitor_insert(GHashTable *unprocessed_opts, const QemuOpt *opt) {GQueue *list; +assert (opt); list =g_hash_table_lookup (unprocessed_opts, opt->name);if (list ==NULL ) {@@ -127,6 +132,9 @@ opts_start_struct(Visitor *v, void **obj, const char *kind,if (obj) { *obj =g_malloc0 (size >0 ? size :1 ); } + +g_queue_push_tail (ov->nested_names, (gpointer ) name); +if (ov->depth++ >0 ) {return ; }@@ -169,6 +177,8 @@ opts_end_struct(Visitor *v, Error **errp)OptsVisitor *ov =DO_UPCAST (OptsVisitor, visitor, v);GQueue *any; +g_queue_pop_tail (ov->nested_names); +if (--ov->depth >0 ) {return ; }@@ -198,15 +208,54 @@ opts_end_implicit_struct(Visitor *v, Error **errp) } +static void +sum_strlen (gpointer data,gpointer user_data) +{ +const char *str = data; +size_t *sum_len = user_data; + +if (str) {/* skip NULLs */ + *sum_len +=strlen (str) +1 ; + } +} + +static void +append_str (gpointer data,gpointer user_data) +{ +const char *str = data; +char *concat_str = user_data; + +if (str) { +strcat (concat_str, str); +strcat (concat_str,"." ); + } +} + +/* lookup a name, using a fully qualified version */ static GQueue * -lookup_distinct (const OptsVisitor *ov,const char *name,Error **errp) +lookup_distinct (const OptsVisitor *ov,const char *name,char **out_key, +Error **errp) { -GQueue *list; +GQueue *list =NULL ; +char *key; +size_t sum_len =strlen (name); + +g_queue_foreach (ov->nested_names, sum_strlen, &sum_len); + key =g_malloc (sum_len+1 ); + key[0 ] =0 ; +g_queue_foreach (ov->nested_names, append_str, key); +strcat (key, name); + + list =g_hash_table_lookup (ov->unprocessed_opts, key); +if (list && out_key) { + *out_key =g_strdup (key); + } - list =g_hash_table_lookup (ov->unprocessed_opts, name);if (!list) {error_set (errp,QERR_MISSING_PARAMETER , name); } + +g_free (key);return list; }@@ -218,7 +267,7 @@ opts_start_list(Visitor *v, const char *name, Error **errp)/* we can't traverse a list in a list */ assert (ov->list_mode ==LM_NONE ); - ov->repeated_opts =lookup_distinct (ov, name, errp); + ov->repeated_opts =lookup_distinct (ov, name, &ov->repeated_name, errp);if (ov->repeated_opts !=NULL ) { ov->list_mode =LM_STARTED ; }@@ -254,11 +303,9 @@ opts_next_list(Visitor *v, GenericList **list, Error **errp)/* range has been completed, fall through in order to pop option */ case LM_IN_PROGRESS : { -const QemuOpt *opt; - - opt =g_queue_pop_head (ov->repeated_opts); +g_queue_pop_head (ov->repeated_opts);if (g_queue_is_empty (ov->repeated_opts)) { -g_hash_table_remove (ov->unprocessed_opts, opt->name); +g_hash_table_remove (ov->unprocessed_opts, ov->repeated_name);return NULL ; } link = &(*list)->next;@@ -284,22 +331,28 @@ opts_end_list(Visitor *v, Error **errp) ov->list_mode ==LM_SIGNED_INTERVAL || ov->list_mode == LM_UNSIGNED_INTERVAL); ov->repeated_opts =NULL ; + +g_free (ov->repeated_name); + ov->repeated_name =NULL ; + ov->list_mode =LM_NONE ; }static const QemuOpt * -lookup_scalar (const OptsVisitor *ov,const char *name,Error **errp) +lookup_scalar (const OptsVisitor *ov,const char *name,char ** out_key, +Error **errp) {if (ov->list_mode ==LM_NONE ) {GQueue *list;/* the last occurrence of any QemuOpt takes effect when queried by name */ - list =lookup_distinct (ov, name, errp); + list =lookup_distinct (ov, name, out_key, errp);return list ?g_queue_peek_tail (list) :NULL ; }assert (ov->list_mode ==LM_IN_PROGRESS ); +assert (out_key ==NULL || *out_key ==NULL );return g_queue_peek_head (ov->repeated_opts); }@@ -321,13 +374,15 @@ opts_type_str(Visitor *v, char **obj, const char *name, Error **errp) {OptsVisitor *ov =DO_UPCAST (OptsVisitor, visitor, v);const QemuOpt *opt; +char *key =NULL ; - opt =lookup_scalar (ov, name, errp); + opt =lookup_scalar (ov, name, &key, errp);if (!opt) {return ; } *obj =g_strdup (opt->str ? opt->str :"" ); -processed (ov, name); +processed (ov, key); +g_free (key); }@@ -337,8 +392,9 @@ opts_type_bool(Visitor *v, bool *obj, const char *name, Error **errp) {OptsVisitor *ov =DO_UPCAST (OptsVisitor, visitor, v);const QemuOpt *opt; +char *key =NULL ; - opt =lookup_scalar (ov, name, errp); + opt =lookup_scalar (ov, name, &key, errp);if (!opt) {return ; }@@ -355,13 +411,15 @@ opts_type_bool(Visitor *v, bool *obj, const char *name, Error **errp) }else {error_set (errp,QERR_INVALID_PARAMETER_VALUE , opt->name,"on|yes|y|off|no|n" ); +g_free (key);return ; } }else { *obj = true; } -processed (ov, name); +processed (ov, key); +g_free (key); }@@ -373,13 +431,14 @@ opts_type_int(Visitor *v, int64_t *obj, const char *name, Error **errp)const char *str;long long val;char *endptr; +char *key =NULL ;if (ov->list_mode ==LM_SIGNED_INTERVAL ) { *obj = ov->range_next.s;return ; } - opt =lookup_scalar (ov, name, errp); + opt =lookup_scalar (ov, name, &key, errp);if (!opt) {return ; }@@ -393,11 +452,13 @@ opts_type_int(Visitor *v, int64_t *obj, const char *name, Error **errp)if (errno ==0 && endptr > str &&INT64_MIN <= val && val <=INT64_MAX ) {if (*endptr =='\0' ) { *obj = val; -processed (ov, name); +processed (ov, key); +g_free (key);return ; }if (*endptr =='-' && ov->list_mode ==LM_IN_PROGRESS ) {long long val2; +assert (key ==NULL ); str = endptr +1 ; val2 =strtoll (str, &endptr,0 );@@ -418,6 +479,7 @@ opts_type_int(Visitor *v, int64_t *obj, const char *name, Error **errp)error_set (errp,QERR_INVALID_PARAMETER_VALUE , opt->name, (ov->list_mode ==LM_NONE ) ?"an int64 value" :"an int64 value or range" ); +g_free (key); }@@ -429,13 +491,14 @@ opts_type_uint64(Visitor *v, uint64_t *obj, const char *name, Error **errp)const char *str;unsigned long long val;char *endptr; +char *key =NULL ;if (ov->list_mode ==LM_UNSIGNED_INTERVAL ) { *obj = ov->range_next.u;return ; } - opt =lookup_scalar (ov, name, errp); + opt =lookup_scalar (ov, name, &key, errp);if (!opt) {return ; }@@ -447,11 +510,13 @@ opts_type_uint64(Visitor *v, uint64_t *obj, const char *name, Error **errp)if (parse_uint (str, &val, &endptr,0 ) ==0 && val <=UINT64_MAX ) {if (*endptr =='\0' ) { *obj = val; -processed (ov, name); +processed (ov, key); +g_free (key);return ; }if (*endptr =='-' && ov->list_mode ==LM_IN_PROGRESS ) {unsigned long long val2; +assert (key ==NULL ); str = endptr +1 ; if (parse_uint_full(str, &val2, 0) == 0 &&@@ -470,6 +535,7 @@ opts_type_uint64(Visitor *v, uint64_t *obj, const char *name, Error **errp)error_set (errp,QERR_INVALID_PARAMETER_VALUE , opt->name, (ov->list_mode ==LM_NONE ) ?"a uint64 value" :"a uint64 value or range" ); +g_free (key); }@@ -480,8 +546,9 @@ opts_type_size(Visitor *v, uint64_t *obj, const char *name, Error **errp)const QemuOpt *opt;int64_t val;char *endptr; +char *key =NULL ; - opt =lookup_scalar (ov, name, errp); + opt =lookup_scalar (ov, name, &key, errp);if (!opt) {return ; }@@ -491,11 +558,13 @@ opts_type_size(Visitor *v, uint64_t *obj, const char *name, Error **errp)if (val <0 || *endptr) {error_set (errp,QERR_INVALID_PARAMETER_VALUE , opt->name,"a size value representible as a non-negative int64" ); +g_free (key);return ; } *obj = val; -processed (ov, name); +processed (ov, key); +g_free (key); }@@ -506,7 +575,7 @@ opts_optional(Visitor *v, bool *present, const char *name, Error **errp)/* we only support a single mandatory scalar field in a list node */ assert (ov->list_mode ==LM_NONE ); - *present = (lookup_distinct (ov, name,NULL ) !=NULL ); + *present = (lookup_distinct (ov, name,NULL ,NULL ) !=NULL ); }@@ -517,6 +586,8 @@ opts_visitor_new(const QemuOpts *opts) ov =g_malloc0 (sizeof *ov); + ov->nested_names =g_queue_new (); + ov->visitor.start_struct = &opts_start_struct; ov->visitor.end_struct = &opts_end_struct;@@ -560,6 +631,7 @@ opts_visitor_cleanup(OptsVisitor *ov)if (ov->unprocessed_opts !=NULL ) {g_hash_table_destroy (ov->unprocessed_opts); } +g_queue_free (ov->nested_names);g_free (ov->fake_id_opt);g_free (ov); }tests/qapi-schema/qapi-schema-test.json +8
-1@@ -81,6 +81,11 @@ { 'command': 'user_def_cmd3', 'data': {'a': 'int', '*b': 'int' }, 'returns': 'int' } +# For testing hierarchy support in opts-visitor +{ 'struct': 'UserDefOptionsSub', + 'data': { + '*nint': 'int' } } + # For testing integer range flattening in opts-visitor. The following schema # corresponds to the option format: #@@ -94,7 +99,9 @@ '*u64' : [ 'uint64' ], '*u16' : [ 'uint16' ], '*i64x': 'int' , - '*u64x': 'uint64' } } + '*u64x': 'uint64' , + 'sub0': 'UserDefOptionsSub', + 'sub1': 'UserDefOptionsSub' } } # testing event { 'struct': 'EventStructOne',tests/test-opts-visitor.c +28
-0@@ -177,6 +177,34 @@ expect_u64_max(OptsVisitorFixture *f, gconstpointer test_data)g_assert (f->userdef->u64->value ==UINT64_MAX ); } +static void +expect_both (OptsVisitorFixture *f,gconstpointer test_data) +{ +expect_ok (f, test_data); +g_assert (f->userdef->sub0->has_nint); +g_assert (f->userdef->sub0->nint ==13 ); +g_assert (f->userdef->sub1->has_nint); +g_assert (f->userdef->sub1->nint ==17 ); +} + +static void +expect_sub0 (OptsVisitorFixture *f,gconstpointer test_data) +{ +expect_ok (f, test_data); +g_assert (f->userdef->sub0->has_nint); +g_assert (f->userdef->sub0->nint ==13 ); +g_assert (!f->userdef->sub1->has_nint); +} + +static void +expect_sub1 (OptsVisitorFixture *f,gconstpointer test_data) +{ +expect_ok (f, test_data); +g_assert (!f->userdef->sub0->has_nint); +g_assert (f->userdef->sub1->has_nint); +g_assert (f->userdef->sub1->nint ==13 ); +} +/* test cases */ int @@ -270,6 +298,12 @@ main(int argc, char **argv)add_test ("/visitor/opts/i64/range/2big/full" , &expect_fail,"i64=-0x8000000000000000-0x7fffffffffffffff" );
tests/test-opts-visitor.c main(int argc, char **argv) · line 309
Quoted 10 lines
tests/test-opts-visitor.c +6
-0+/* Test nested structs support */ +add_test ("/visitor/opts/nested/unqualified" , &expect_fail,"nint=13" ); +add_test ("/visitor/opts/nested/both" , &expect_both, +"sub0.nint=13,sub1.nint=17" ); +add_test ("/visitor/opts/nested/sub0" , &expect_sub0,"sub0.nint=13" ); +add_test ("/visitor/opts/nested/sub1" , &expect_sub1,"sub1.nint=13" );g_test_run ();return 0 ; }
Re patch v3 1/8 -- apparently I was not around when the start_implicit_struct() and end_implicit_struct() visitor callbacks were introduced, so I don't know what they are good for, but on the surface, that patch might even be correct. I can't tell.
Re patch v3 5/8, ie. this patch -- if there has been some kind of "master blurb" for this feature, ie. justification for nested structs, I'm unaware of it. (I'm not getting qemu-devel email, just personal Cc's.) Can you please send me a link into the archive where this feature is justifed / discussed?
I have one related, and one independent note here:
(1) The related note -- OptsVisitor was introduced in commit eb7ee2cbeb. You can see in the commit message that "union of flat structures" was a foundational design trait for OptsVisitor, so if you want nested structs, it's not a "bug to fix", but a new feature to add.
(Namely, refer to the allowed members of "struct for discriminator case 1" -- they can only be scalar members, or restricted format lists for repeating optargs. Structure nesting is not allowed on any level.)
The objective was to support then-existent command lines (ie. parse options into QAPI schemas). As far as I (vaguely) recall, Eric has since (independently) flattened a bunch of QAPI structs as well. So I'm unsure if and why nested structs are "again" a "thing".
(In any case this should not be taken as my opposition; I'm just uninformed. That link I mentioned above could inform me.)
(2) The independent note. OptsVisitor is one of the hardest-to-understand things I've implemented. It has always been hard to understand for myself. As far as I recall, I struggled in my mind to cover all corner cases and prove stuff right. Later I was "asked" to add range support to it (ie. turn a range like 3-7 into a list of integers 3, 4, 5, 6, 7) and I was sweating bloody bullets to avoid regressions.
So, this code requires careful tiptoeing. I do not want to discourage changes to it (and I certainly encourage reviewers to look at your patches). I'm just saying I personally can't be your reviewer. I lost this context long ago, I dread looking at this code again, and I don't feel safe saying either yay or nay.
You could *almost* accuse me of having thrown this code over the fence. My only excuse (a good one though) is that I only wrote this code because I was asked to. (If you're familiar with the Bioshock universe, I heard "would you kindly".)
I'm told that this code has proved somewhat useful, which I'm glad about, but I really can't support it. Sorry about that. So, I'm neither acking nor nacking; don't wait for my feedback.
(Apologies for the wall of text, but I guess it's better to say "sorry can't help you" in too many words than not reacting at all.)
Thanks
László (since we're using Hungarian accents in this thread :))
Re: [Qemu-devel] [PATCH v3 5/8] qapi: support nested structs in OptsVisitor
2015-06-18 19:15 keltezéssel, Laszlo Ersek írta:
Quoted 434 lines · Zoltán
Quoted 433 lines
The current OptsVisitor flattens the whole structure, if there are same named fields under different paths (like
in' andout' inAudiodev'), the current visitor can't cope with them (for example settingfrequency=44100' will set the in's frequency to 44100 and leave out's frequency unspecified).This patch fixes it, by always requiring a complete path in case of nested structs. Fields in the path are separated by dots, similar to C structs (without pointers), like
in.frequency' orout.frequency'.You must provide a full path even in non-ambigous cases. The previous two commits hopefully ensures that this change doesn't create backward compatibility problems.
Signed-off-by Kővágó, Zoltán <[email protected]>---
Change from v2:
* only fully qualified paths are allowedqapi/opts-visitor.c | 114 ++++++++++++++++++++++++++------ tests/qapi-schema/qapi-schema-test.json | 9 ++- tests/test-opts-visitor.c | 34 ++++++++++ 3 files changed, 135 insertions(+), 22 deletions(-)qapi/opts-visitor.c +93
-21@@ -71,6 +71,7 @@ struct OptsVisitor* schema, with a single mandatory scalar member. */ ListMode list_mode;GQueue *repeated_opts; +char *repeated_name;/* When parsing a list of repeating options as integers, values of the form * "a-b", representing a closed interval, are allowed. Elements in the @@ -86,6 +87,9 @@ struct OptsVisitor* not survive or escape the OptsVisitor object. */ QemuOpt *fake_id_opt; + +/* List of field names leading to the current structure. */ +GQueue *nested_names; };@@ -100,6 +104,7 @@ static void opts_visitor_insert(GHashTable *unprocessed_opts, const QemuOpt *opt) {GQueue *list; +assert (opt); list =g_hash_table_lookup (unprocessed_opts, opt->name);if (list ==NULL ) {@@ -127,6 +132,9 @@ opts_start_struct(Visitor *v, void **obj, const char *kind,if (obj) { *obj =g_malloc0 (size >0 ? size :1 ); } + +g_queue_push_tail (ov->nested_names, (gpointer ) name); +if (ov->depth++ >0 ) {return ; }@@ -169,6 +177,8 @@ opts_end_struct(Visitor *v, Error **errp)OptsVisitor *ov =DO_UPCAST (OptsVisitor, visitor, v);GQueue *any; +g_queue_pop_tail (ov->nested_names); +if (--ov->depth >0 ) {return ; }@@ -198,15 +208,54 @@ opts_end_implicit_struct(Visitor *v, Error **errp) } +static void +sum_strlen (gpointer data,gpointer user_data) +{ +const char *str = data; +size_t *sum_len = user_data; + +if (str) {/* skip NULLs */ + *sum_len +=strlen (str) +1 ; + } +} + +static void +append_str (gpointer data,gpointer user_data) +{ +const char *str = data; +char *concat_str = user_data; + +if (str) { +strcat (concat_str, str); +strcat (concat_str,"." ); + } +} + +/* lookup a name, using a fully qualified version */ static GQueue * -lookup_distinct (const OptsVisitor *ov,const char *name,Error **errp) +lookup_distinct (const OptsVisitor *ov,const char *name,char **out_key, +Error **errp) { -GQueue *list; +GQueue *list =NULL ; +char *key; +size_t sum_len =strlen (name); + +g_queue_foreach (ov->nested_names, sum_strlen, &sum_len); + key =g_malloc (sum_len+1 ); + key[0 ] =0 ; +g_queue_foreach (ov->nested_names, append_str, key); +strcat (key, name); + + list =g_hash_table_lookup (ov->unprocessed_opts, key); +if (list && out_key) { + *out_key =g_strdup (key); + } - list =g_hash_table_lookup (ov->unprocessed_opts, name);if (!list) {error_set (errp,QERR_MISSING_PARAMETER , name); } + +g_free (key);return list; }@@ -218,7 +267,7 @@ opts_start_list(Visitor *v, const char *name, Error **errp)/* we can't traverse a list in a list */ assert (ov->list_mode ==LM_NONE ); - ov->repeated_opts =lookup_distinct (ov, name, errp); + ov->repeated_opts =lookup_distinct (ov, name, &ov->repeated_name, errp);if (ov->repeated_opts !=NULL ) { ov->list_mode =LM_STARTED ; }@@ -254,11 +303,9 @@ opts_next_list(Visitor *v, GenericList **list, Error **errp)/* range has been completed, fall through in order to pop option */ case LM_IN_PROGRESS : { -const QemuOpt *opt; - - opt =g_queue_pop_head (ov->repeated_opts); +g_queue_pop_head (ov->repeated_opts);if (g_queue_is_empty (ov->repeated_opts)) { -g_hash_table_remove (ov->unprocessed_opts, opt->name); +g_hash_table_remove (ov->unprocessed_opts, ov->repeated_name);return NULL ; } link = &(*list)->next;@@ -284,22 +331,28 @@ opts_end_list(Visitor *v, Error **errp) ov->list_mode ==LM_SIGNED_INTERVAL || ov->list_mode == LM_UNSIGNED_INTERVAL); ov->repeated_opts =NULL ; + +g_free (ov->repeated_name); + ov->repeated_name =NULL ; + ov->list_mode =LM_NONE ; }static const QemuOpt * -lookup_scalar (const OptsVisitor *ov,const char *name,Error **errp) +lookup_scalar (const OptsVisitor *ov,const char *name,char ** out_key, +Error **errp) {if (ov->list_mode ==LM_NONE ) {GQueue *list;/* the last occurrence of any QemuOpt takes effect when queried by name */ - list =lookup_distinct (ov, name, errp); + list =lookup_distinct (ov, name, out_key, errp);return list ?g_queue_peek_tail (list) :NULL ; }assert (ov->list_mode ==LM_IN_PROGRESS ); +assert (out_key ==NULL || *out_key ==NULL );return g_queue_peek_head (ov->repeated_opts); }@@ -321,13 +374,15 @@ opts_type_str(Visitor *v, char **obj, const char *name, Error **errp) {OptsVisitor *ov =DO_UPCAST (OptsVisitor, visitor, v);const QemuOpt *opt; +char *key =NULL ; - opt =lookup_scalar (ov, name, errp); + opt =lookup_scalar (ov, name, &key, errp);if (!opt) {return ; } *obj =g_strdup (opt->str ? opt->str :"" ); -processed (ov, name); +processed (ov, key); +g_free (key); }@@ -337,8 +392,9 @@ opts_type_bool(Visitor *v, bool *obj, const char *name, Error **errp) {OptsVisitor *ov =DO_UPCAST (OptsVisitor, visitor, v);const QemuOpt *opt; +char *key =NULL ; - opt =lookup_scalar (ov, name, errp); + opt =lookup_scalar (ov, name, &key, errp);if (!opt) {return ; }@@ -355,13 +411,15 @@ opts_type_bool(Visitor *v, bool *obj, const char *name, Error **errp) }else {error_set (errp,QERR_INVALID_PARAMETER_VALUE , opt->name,"on|yes|y|off|no|n" ); +g_free (key);return ; } }else { *obj = true; } -processed (ov, name); +processed (ov, key); +g_free (key); }@@ -373,13 +431,14 @@ opts_type_int(Visitor *v, int64_t *obj, const char *name, Error **errp)const char *str;long long val;char *endptr; +char *key =NULL ;if (ov->list_mode ==LM_SIGNED_INTERVAL ) { *obj = ov->range_next.s;return ; } - opt =lookup_scalar (ov, name, errp); + opt =lookup_scalar (ov, name, &key, errp);if (!opt) {return ; }@@ -393,11 +452,13 @@ opts_type_int(Visitor *v, int64_t *obj, const char *name, Error **errp)if (errno ==0 && endptr > str &&INT64_MIN <= val && val <=INT64_MAX ) {if (*endptr =='\0' ) { *obj = val; -processed (ov, name); +processed (ov, key); +g_free (key);return ; }if (*endptr =='-' && ov->list_mode ==LM_IN_PROGRESS ) {long long val2; +assert (key ==NULL ); str = endptr +1 ; val2 =strtoll (str, &endptr,0 );@@ -418,6 +479,7 @@ opts_type_int(Visitor *v, int64_t *obj, const char *name, Error **errp)error_set (errp,QERR_INVALID_PARAMETER_VALUE , opt->name, (ov->list_mode ==LM_NONE ) ?"an int64 value" :"an int64 value or range" ); +g_free (key); }@@ -429,13 +491,14 @@ opts_type_uint64(Visitor *v, uint64_t *obj, const char *name, Error **errp)const char *str;unsigned long long val;char *endptr; +char *key =NULL ;if (ov->list_mode ==LM_UNSIGNED_INTERVAL ) { *obj = ov->range_next.u;return ; } - opt =lookup_scalar (ov, name, errp); + opt =lookup_scalar (ov, name, &key, errp);if (!opt) {return ; }@@ -447,11 +510,13 @@ opts_type_uint64(Visitor *v, uint64_t *obj, const char *name, Error **errp)if (parse_uint (str, &val, &endptr,0 ) ==0 && val <=UINT64_MAX ) {if (*endptr =='\0' ) { *obj = val; -processed (ov, name); +processed (ov, key); +g_free (key);return ; }if (*endptr =='-' && ov->list_mode ==LM_IN_PROGRESS ) {unsigned long long val2; +assert (key ==NULL ); str = endptr +1 ; if (parse_uint_full(str, &val2, 0) == 0 &&@@ -470,6 +535,7 @@ opts_type_uint64(Visitor *v, uint64_t *obj, const char *name, Error **errp)error_set (errp,QERR_INVALID_PARAMETER_VALUE , opt->name, (ov->list_mode ==LM_NONE ) ?"a uint64 value" :"a uint64 value or range" ); +g_free (key); }@@ -480,8 +546,9 @@ opts_type_size(Visitor *v, uint64_t *obj, const char *name, Error **errp)const QemuOpt *opt;int64_t val;char *endptr; +char *key =NULL ; - opt =lookup_scalar (ov, name, errp); + opt =lookup_scalar (ov, name, &key, errp);if (!opt) {return ; }@@ -491,11 +558,13 @@ opts_type_size(Visitor *v, uint64_t *obj, const char *name, Error **errp)if (val <0 || *endptr) {error_set (errp,QERR_INVALID_PARAMETER_VALUE , opt->name,"a size value representible as a non-negative int64" ); +g_free (key);return ; } *obj = val; -processed (ov, name); +processed (ov, key); +g_free (key); }@@ -506,7 +575,7 @@ opts_optional(Visitor *v, bool *present, const char *name, Error **errp)/* we only support a single mandatory scalar field in a list node */ assert (ov->list_mode ==LM_NONE ); - *present = (lookup_distinct (ov, name,NULL ) !=NULL ); + *present = (lookup_distinct (ov, name,NULL ,NULL ) !=NULL ); }@@ -517,6 +586,8 @@ opts_visitor_new(const QemuOpts *opts) ov =g_malloc0 (sizeof *ov); + ov->nested_names =g_queue_new (); + ov->visitor.start_struct = &opts_start_struct; ov->visitor.end_struct = &opts_end_struct;@@ -560,6 +631,7 @@ opts_visitor_cleanup(OptsVisitor *ov)if (ov->unprocessed_opts !=NULL ) {g_hash_table_destroy (ov->unprocessed_opts); } +g_queue_free (ov->nested_names);g_free (ov->fake_id_opt);g_free (ov); }tests/qapi-schema/qapi-schema-test.json +8
-1@@ -81,6 +81,11 @@ { 'command': 'user_def_cmd3', 'data': {'a': 'int', '*b': 'int' }, 'returns': 'int' } +# For testing hierarchy support in opts-visitor +{ 'struct': 'UserDefOptionsSub', + 'data': { + '*nint': 'int' } } + # For testing integer range flattening in opts-visitor. The following schema # corresponds to the option format: #@@ -94,7 +99,9 @@ '*u64' : [ 'uint64' ], '*u16' : [ 'uint16' ], '*i64x': 'int' , - '*u64x': 'uint64' } } + '*u64x': 'uint64' , + 'sub0': 'UserDefOptionsSub', + 'sub1': 'UserDefOptionsSub' } } # testing event { 'struct': 'EventStructOne',tests/test-opts-visitor.c +28
-0@@ -177,6 +177,34 @@ expect_u64_max(OptsVisitorFixture *f, gconstpointer test_data)g_assert (f->userdef->u64->value ==UINT64_MAX ); } +static void +expect_both (OptsVisitorFixture *f,gconstpointer test_data) +{ +expect_ok (f, test_data); +g_assert (f->userdef->sub0->has_nint); +g_assert (f->userdef->sub0->nint ==13 ); +g_assert (f->userdef->sub1->has_nint); +g_assert (f->userdef->sub1->nint ==17 ); +} + +static void +expect_sub0 (OptsVisitorFixture *f,gconstpointer test_data) +{ +expect_ok (f, test_data); +g_assert (f->userdef->sub0->has_nint); +g_assert (f->userdef->sub0->nint ==13 ); +g_assert (!f->userdef->sub1->has_nint); +} + +static void +expect_sub1 (OptsVisitorFixture *f,gconstpointer test_data) +{ +expect_ok (f, test_data); +g_assert (!f->userdef->sub0->has_nint); +g_assert (f->userdef->sub1->has_nint); +g_assert (f->userdef->sub1->nint ==13 ); +} +/* test cases */ int @@ -270,6 +298,12 @@ main(int argc, char **argv)add_test ("/visitor/opts/i64/range/2big/full" , &expect_fail,"i64=-0x8000000000000000-0x7fffffffffffffff" );
Quoted 15 lines
tests/test-opts-visitor.c main(int argc, char **argv) · line 309
Quoted 10 lines
tests/test-opts-visitor.c +6
-0+/* Test nested structs support */ +add_test ("/visitor/opts/nested/unqualified" , &expect_fail,"nint=13" ); +add_test ("/visitor/opts/nested/both" , &expect_both, +"sub0.nint=13,sub1.nint=17" ); +add_test ("/visitor/opts/nested/sub0" , &expect_sub0,"sub0.nint=13" ); +add_test ("/visitor/opts/nested/sub1" , &expect_sub1,"sub1.nint=13" );g_test_run ();return 0 ; }Re patch v3 1/8 -- apparently I was not around when the
start_implicit_struct()andend_implicit_struct()visitor callbacks were introduced, so I don't know what they are good for, but on the surface, that patch might even be correct. I can't tell.
Actually I'm not completely sure that the visitor code generated are correct in case of implicit structs. In case of normal structs, there's an if (*obj) { ... } check, but in case of implicit structs it just visits the fields without checking (which is problematic, since the default visit_start_implicit_struct is just a no-op, causing segfaults...)
Quoted 5 lines
Re patch v3 5/8, ie. this patch -- if there has been some kind of "master blurb" for this feature, ie. justification for nested structs, I'm unaware of it. (I'm not getting qemu-devel email, just personal Cc's.) Can you please send me a link into the archive where this feature is justifed / discussed?
This is needed for my -audiodev option, see v2 patch thread: http://lists.nongnu.org/archive/html/qemu-devel/2015-06/msg04189.html
And probably this as an example where it's useful:
http://lists.nongnu.org/archive/html/qemu-devel/2015-06/msg04186.html
Quoted 11 lines
I have one related, and one independent note here:
(1) The related note -- OptsVisitor was introduced in commit
eb7ee2cbeb. You can see in the commit message that "union of flat structures" was a foundational design trait for OptsVisitor, so if you want nested structs, it's not a "bug to fix", but a new feature to add.(Namely, refer to the allowed members of "struct for discriminator case 1" -- they can only be scalar members, or restricted format lists for repeating optargs. Structure nesting is not allowed on any level.)
Quoted 7 lines
The objective was to support then-existent command lines (ie. parse options into QAPI schemas). As far as I (vaguely) recall, Eric has since (independently) flattened a bunch of QAPI structs as well. So I'm unsure if and why nested structs are "again" a "thing".
(In any case this should not be taken as my opposition; I'm just uninformed. That link I mentioned above could inform me.)
Check my second link, it contains a good example where it's useful (to specify input and output audio settings independently, like in.frequency and out.frequency. Of course we could do like in-frequency and out-frequency and a bunch of copy paste, but this is a much better way imho, even if it requires some changes to how existing things work).
Quoted 18 lines
(2) The independent note. OptsVisitor is one of the hardest-to-understand things I've implemented. It has always been hard to understand for myself. As far as I recall, I struggled in my mind to cover all corner cases and prove stuff right. Later I was "asked" to add range support to it (ie. turn a range like 3-7 into a list of integers 3, 4, 5, 6, 7) and I was sweating bloody bullets to avoid regressions.
So, this code requires careful tiptoeing. I do not want to discourage changes to it (and I certainly encourage reviewers to look at your patches). I'm just saying I personally can't be your reviewer. I lost this context long ago, I dread looking at this code again, and I don't feel safe saying either yay or nay.
You could *almost* accuse me of having thrown this code over the fence. My only excuse (a good one though) is that I only wrote this code because I was asked to. (If you're familiar with the Bioshock universe, I heard "would you kindly".)
Quoted 6 lines
I'm told that this code has proved somewhat useful, which I'm glad about, but I really can't support it. Sorry about that. So, I'm neither acking nor nacking; don't wait for my feedback.
(Apologies for the wall of text, but I guess it's better to say "sorry can't help you" in too many words than not reacting at all.)
All right, no problem.
Quoted 4 lines
Thanks
László (since we're using Hungarian accents in this thread :))
Thanks
Zoltán :)
PATCH v3 6/8 opts: produce valid command line in qemu_opts_print
In reply to Kővágó, ZoltánThis will let us print options in a format that the user would actually write it on the command line (foo=bar,baz=asd,etc=def), without prepending a spurious comma at the beginning of the list, or quoting values unnecessarily. This patch provides the following changes:
* write and id=, if the option has an id
* do not print separator before the first element
* do not quote string arguments which only contains letters or numbers
* properly escape commas (,) for QEMU, apostrophe (') for shell
---
Chages from v2:
* print id=
* proper value escaping (apostrophe and comma)
* renamed d_sep -> separator
block.c | 2 +- util/qemu-option.c | 47 ++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 45 insertions(+), 4 deletions(-)
block.c +1 -1
@@ -3823,7 +3823,7 @@ void bdrv_img_create(const char *filename, const char *fmt, }if (!quiet) { -printf ("Formatting '%s', fmt=%s" , filename, fmt); +printf ("Formatting '%s', fmt=%s " , filename, fmt);qemu_opts_print (opts," " );puts ("" ); }
util/qemu-option.c +44 -3
71 lines not on this page · raw message
Signature · 1 line
2.4.3
PATCH v3 7/8 audio: use qapi AudioFormat instead of audfmt_e
In reply to Kővágó, ZoltánI had to include an enum for audio sampling formats into qapi, but that meant duplicating the audfmt_e enum. This patch replaces audfmt_e and associated values with the qapi generated AudioFormat enum.
This patch is mostly a search-and-replace, except for switches where the qapi generated AUDIO_FORMAT_MAX caused problems.
---
Changes from v2:
* replaced case AUDIO_FORMAT_MAX with default
audio/alsaaudio.c | 53 ++++++++++++++------------ audio/audio.c | 97 ++++++++++++++++++++++++++--------------------- audio/audio.h | 11 +----- audio/audio_win_int.c | 18 ++++----- audio/ossaudio.c | 30 +++++++-------- audio/paaudio.c | 28 +++++++------- audio/sdlaudio.c | 26 ++++++------- audio/spiceaudio.c | 4 +- audio/wavaudio.c | 17 +++++---- audio/wavcapture.c | 2 +- hw/arm/omap2.c | 2 +- hw/audio/ac97.c | 2 +- hw/audio/adlib.c | 2 +- hw/audio/cs4231a.c | 6 +-- hw/audio/es1370.c | 4 +- hw/audio/gus.c | 2 +- hw/audio/hda-codec.c | 18 ++++----- hw/audio/lm4549.c | 6 +-- hw/audio/milkymist-ac97.c | 2 +- hw/audio/pcspk.c | 2 +- hw/audio/sb16.c | 14 +++---- hw/audio/wm8750.c | 4 +- hw/input/tsc210x.c | 2 +- hw/usb/dev-audio.c | 2 +- ui/vnc.c | 14 +++---- 25 files changed, 187 insertions(+), 181 deletions(-)
audio/alsaaudio.c +28 -25
@@ -88,7 +88,7 @@ struct alsa_params_req {struct alsa_params_obt {int freq; -audfmt_e fmt; +AudioFormat fmt;int endianness;int nchannels;snd_pcm_uframes_t samples;
@@ -295,16 +295,16 @@ static int alsa_write (SWVoiceOut *sw, void *buf, int len)return audio_pcm_sw_write (sw, buf, len); } -static snd_pcm_format_t aud_to_alsafmt (audfmt_e fmt,int endianness) +static snd_pcm_format_t aud_to_alsafmt (AudioFormat fmt,int endianness) {switch (fmt) { -case AUD_FMT_S8 : +case AUDIO_FORMAT_S8 :return SND_PCM_FORMAT_S8 ; -case AUD_FMT_U8 : +case AUDIO_FORMAT_U8 :return SND_PCM_FORMAT_U8 ; -case AUD_FMT_S16 : +case AUDIO_FORMAT_S16 :if (endianness) {return SND_PCM_FORMAT_S16_BE ; }
@@ -312,7 +312,7 @@ static snd_pcm_format_t aud_to_alsafmt (audfmt_e fmt, int endianness)return SND_PCM_FORMAT_S16_LE ; } -case AUD_FMT_U16 : +case AUDIO_FORMAT_U16 :if (endianness) {return SND_PCM_FORMAT_U16_BE ; }
@@ -320,7 +320,7 @@ static snd_pcm_format_t aud_to_alsafmt (audfmt_e fmt, int endianness)return SND_PCM_FORMAT_U16_LE ; } -case AUD_FMT_S32 : +case AUDIO_FORMAT_S32 :if (endianness) {return SND_PCM_FORMAT_S32_BE ; }
@@ -328,7 +328,7 @@ static snd_pcm_format_t aud_to_alsafmt (audfmt_e fmt, int endianness)return SND_PCM_FORMAT_S32_LE ; } -case AUD_FMT_U32 : +case AUDIO_FORMAT_U32 :if (endianness) {return SND_PCM_FORMAT_U32_BE ; }
@@ -345,58 +345,58 @@ static snd_pcm_format_t aud_to_alsafmt (audfmt_e fmt, int endianness) } } -static int alsa_to_audfmt (snd_pcm_format_t alsafmt,audfmt_e *fmt, +static int alsa_to_audfmt (snd_pcm_format_t alsafmt,AudioFormat *fmt,int *endianness) {switch (alsafmt) {case SND_PCM_FORMAT_S8 : *endianness =0 ; - *fmt =AUD_FMT_S8 ; + *fmt =AUDIO_FORMAT_S8 ;break ;case SND_PCM_FORMAT_U8 : *endianness =0 ; - *fmt =AUD_FMT_U8 ; + *fmt =AUDIO_FORMAT_U8 ;break ;case SND_PCM_FORMAT_S16_LE : *endianness =0 ; - *fmt =AUD_FMT_S16 ; + *fmt =AUDIO_FORMAT_S16 ;break ;case SND_PCM_FORMAT_U16_LE : *endianness =0 ; - *fmt =AUD_FMT_U16 ; + *fmt =AUDIO_FORMAT_U16 ;break ;case SND_PCM_FORMAT_S16_BE : *endianness =1 ; - *fmt =AUD_FMT_S16 ; + *fmt =AUDIO_FORMAT_S16 ;break ;case SND_PCM_FORMAT_U16_BE : *endianness =1 ; - *fmt =AUD_FMT_U16 ; + *fmt =AUDIO_FORMAT_U16 ;break ;case SND_PCM_FORMAT_S32_LE : *endianness =0 ; - *fmt =AUD_FMT_S32 ; + *fmt =AUDIO_FORMAT_S32 ;break ;case SND_PCM_FORMAT_U32_LE : *endianness =0 ; - *fmt =AUD_FMT_U32 ; + *fmt =AUDIO_FORMAT_U32 ;break ;case SND_PCM_FORMAT_S32_BE : *endianness =1 ; - *fmt =AUD_FMT_S32 ; + *fmt =AUDIO_FORMAT_S32 ;break ;case SND_PCM_FORMAT_U32_BE : *endianness =1 ; - *fmt =AUD_FMT_U32 ; + *fmt =AUDIO_FORMAT_U32 ;break ;default :
@@ -639,19 +639,22 @@ static int alsa_open (int in, struct alsa_params_req *req, bytes_per_sec = freq << (nchannels ==2 );switch (obt->fmt) { -case AUD_FMT_S8 : -case AUD_FMT_U8 : +case AUDIO_FORMAT_S8 : +case AUDIO_FORMAT_U8 :break ; -case AUD_FMT_S16 : -case AUD_FMT_U16 : +case AUDIO_FORMAT_S16 : +case AUDIO_FORMAT_U16 : bytes_per_sec <<=1 ;break ; -case AUD_FMT_S32 : -case AUD_FMT_U32 : +case AUDIO_FORMAT_S32 : +case AUDIO_FORMAT_U32 : bytes_per_sec <<=2 ;break ; + +default : +abort (); } threshold = (conf->threshold * bytes_per_sec) /1000 ;
audio/audio.c +53 -44
230 lines not on this page · raw message
audio/audio.h +1 -10
@@ -29,15 +29,6 @@typedef void (*audio_callback_fn ) (void *opaque,int avail); -typedef enum { -AUD_FMT_U8 , -AUD_FMT_S8 , -AUD_FMT_U16 , -AUD_FMT_S16 , -AUD_FMT_U32 , -AUD_FMT_S32 -}audfmt_e ; -#ifdef HOST_WORDS_BIGENDIAN #define AUDIO_HOST_ENDIANNESS 1#else
@@ -47,7 +38,7 @@ typedef enum {struct audsettings {int freq;int nchannels; -audfmt_e fmt; +AudioFormat fmt;int endianness; };
audio/audio_win_int.c +9 -9
@@ -23,20 +23,20 @@ int waveformat_from_audio_settings (WAVEFORMATEX *wfx, wfx->cbSize =0 ;switch (as->fmt) { -case AUD_FMT_S8 : -case AUD_FMT_U8 : +case AUDIO_FORMAT_S8 : +case AUDIO_FORMAT_U8 : wfx->wBitsPerSample =8 ;break ; -case AUD_FMT_S16 : -case AUD_FMT_U16 : +case AUDIO_FORMAT_S16 : +case AUDIO_FORMAT_U16 : wfx->wBitsPerSample =16 ; wfx->nAvgBytesPerSec <<=1 ; wfx->nBlockAlign <<=1 ;break ; -case AUD_FMT_S32 : -case AUD_FMT_U32 : +case AUDIO_FORMAT_S32 : +case AUDIO_FORMAT_U32 : wfx->wBitsPerSample =32 ; wfx->nAvgBytesPerSec <<=2 ; wfx->nBlockAlign <<=2 ;
@@ -84,15 +84,15 @@ int waveformat_to_audio_settings (WAVEFORMATEX *wfx,switch (wfx->wBitsPerSample) {case 8 : - as->fmt =AUD_FMT_U8 ; + as->fmt =AUDIO_FORMAT_U8 ;break ;case 16 : - as->fmt =AUD_FMT_S16 ; + as->fmt =AUDIO_FORMAT_S16 ;break ;case 32 : - as->fmt =AUD_FMT_S32 ; + as->fmt =AUDIO_FORMAT_S32 ;break ;default :
audio/ossaudio.c +15 -15
@@ -72,7 +72,7 @@ typedef struct OSSVoiceIn {struct oss_params {int freq; -audfmt_e fmt; +AudioFormat fmt;int nchannels;int nfrags;int fragsize;
@@ -150,16 +150,16 @@ static int oss_write (SWVoiceOut *sw, void *buf, int len)return audio_pcm_sw_write (sw, buf, len); } -static int aud_to_ossfmt (audfmt_e fmt,int endianness) +static int aud_to_ossfmt (AudioFormat fmt,int endianness) {switch (fmt) { -case AUD_FMT_S8 : +case AUDIO_FORMAT_S8 :return AFMT_S8 ; -case AUD_FMT_U8 : +case AUDIO_FORMAT_U8 :return AFMT_U8 ; -case AUD_FMT_S16 : +case AUDIO_FORMAT_S16 :if (endianness) {return AFMT_S16_BE ; }
@@ -167,7 +167,7 @@ static int aud_to_ossfmt (audfmt_e fmt, int endianness)return AFMT_S16_LE ; } -case AUD_FMT_U16 : +case AUDIO_FORMAT_U16 :if (endianness) {return AFMT_U16_BE ; }
@@ -184,37 +184,37 @@ static int aud_to_ossfmt (audfmt_e fmt, int endianness) } } -static int oss_to_audfmt (int ossfmt,audfmt_e *fmt,int *endianness) +static int oss_to_audfmt (int ossfmt,AudioFormat *fmt,int *endianness) {switch (ossfmt) {case AFMT_S8 : *endianness =0 ; - *fmt =AUD_FMT_S8 ; + *fmt =AUDIO_FORMAT_S8 ;break ;case AFMT_U8 : *endianness =0 ; - *fmt =AUD_FMT_U8 ; + *fmt =AUDIO_FORMAT_U8 ;break ;case AFMT_S16_LE : *endianness =0 ; - *fmt =AUD_FMT_S16 ; + *fmt =AUDIO_FORMAT_S16 ;break ;case AFMT_U16_LE : *endianness =0 ; - *fmt =AUD_FMT_U16 ; + *fmt =AUDIO_FORMAT_U16 ;break ;case AFMT_S16_BE : *endianness =1 ; - *fmt =AUD_FMT_S16 ; + *fmt =AUDIO_FORMAT_S16 ;break ;case AFMT_U16_BE : *endianness =1 ; - *fmt =AUD_FMT_U16 ; + *fmt =AUDIO_FORMAT_U16 ;break ;default :
@@ -502,7 +502,7 @@ static int oss_init_out(HWVoiceOut *hw, struct audsettings *as,int endianness;int err;int fd; -audfmt_e effective_fmt; +AudioFormat effective_fmt;struct audsettings obt_as;OSSConf *conf = drv_opaque;
@@ -671,7 +671,7 @@ static int oss_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque)int endianness;int err;int fd; -audfmt_e effective_fmt; +AudioFormat effective_fmt;struct audsettings obt_as;OSSConf *conf = drv_opaque;
audio/paaudio.c +14 -14
@@ -384,21 +384,21 @@ static int qpa_read (SWVoiceIn *sw, void *buf, int len)return audio_pcm_sw_read (sw, buf, len); } -static pa_sample_format_t audfmt_to_pa (audfmt_e afmt,int endianness) +static pa_sample_format_t audfmt_to_pa (AudioFormat afmt,int endianness) {int format;switch (afmt) { -case AUD_FMT_S8 : -case AUD_FMT_U8 : +case AUDIO_FORMAT_S8 : +case AUDIO_FORMAT_U8 : format =PA_SAMPLE_U8 ;break ; -case AUD_FMT_S16 : -case AUD_FMT_U16 : +case AUDIO_FORMAT_S16 : +case AUDIO_FORMAT_U16 : format = endianness ?PA_SAMPLE_S16BE :PA_SAMPLE_S16LE ;break ; -case AUD_FMT_S32 : -case AUD_FMT_U32 : +case AUDIO_FORMAT_S32 : +case AUDIO_FORMAT_U32 : format = endianness ?PA_SAMPLE_S32BE :PA_SAMPLE_S32LE ;break ;default :
@@ -409,26 +409,26 @@ static pa_sample_format_t audfmt_to_pa (audfmt_e afmt, int endianness)return format; } -static audfmt_e pa_to_audfmt (pa_sample_format_t fmt,int *endianness) +static AudioFormat pa_to_audfmt (pa_sample_format_t fmt,int *endianness) {switch (fmt) {case PA_SAMPLE_U8 : -return AUD_FMT_U8 ; +return AUDIO_FORMAT_U8 ;case PA_SAMPLE_S16BE : *endianness =1 ; -return AUD_FMT_S16 ; +return AUDIO_FORMAT_S16 ;case PA_SAMPLE_S16LE : *endianness =0 ; -return AUD_FMT_S16 ; +return AUDIO_FORMAT_S16 ;case PA_SAMPLE_S32BE : *endianness =1 ; -return AUD_FMT_S32 ; +return AUDIO_FORMAT_S32 ;case PA_SAMPLE_S32LE : *endianness =0 ; -return AUD_FMT_S32 ; +return AUDIO_FORMAT_S32 ;default :dolog ("Internal logic error: Bad pa_sample_format %d\n" , fmt); -return AUD_FMT_U8 ; +return AUDIO_FORMAT_U8 ; } }
audio/sdlaudio.c +13 -13
@@ -115,19 +115,19 @@ static int sdl_unlock_and_post (SDLAudioState *s, const char *forfn)return sdl_post (s, forfn); } -static int aud_to_sdlfmt (audfmt_e fmt) +static int aud_to_sdlfmt (AudioFormat fmt) {switch (fmt) { -case AUD_FMT_S8 : +case AUDIO_FORMAT_S8 :return AUDIO_S8 ; -case AUD_FMT_U8 : +case AUDIO_FORMAT_U8 :return AUDIO_U8 ; -case AUD_FMT_S16 : +case AUDIO_FORMAT_S16 :return AUDIO_S16LSB ; -case AUD_FMT_U16 : +case AUDIO_FORMAT_U16 :return AUDIO_U16LSB ;default :
@@ -139,37 +139,37 @@ static int aud_to_sdlfmt (audfmt_e fmt) } } -static int sdl_to_audfmt (int sdlfmt,audfmt_e *fmt,int *endianness) +static int sdl_to_audfmt (int sdlfmt,AudioFormat *fmt,int *endianness) {switch (sdlfmt) {case AUDIO_S8 : *endianness =0 ; - *fmt =AUD_FMT_S8 ; + *fmt =AUDIO_FORMAT_S8 ;break ;case AUDIO_U8 : *endianness =0 ; - *fmt =AUD_FMT_U8 ; + *fmt =AUDIO_FORMAT_U8 ;break ;case AUDIO_S16LSB : *endianness =0 ; - *fmt =AUD_FMT_S16 ; + *fmt =AUDIO_FORMAT_S16 ;break ;case AUDIO_U16LSB : *endianness =0 ; - *fmt =AUD_FMT_U16 ; + *fmt =AUDIO_FORMAT_U16 ;break ;case AUDIO_S16MSB : *endianness =1 ; - *fmt =AUD_FMT_S16 ; + *fmt =AUDIO_FORMAT_S16 ;break ;case AUDIO_U16MSB : *endianness =1 ; - *fmt =AUD_FMT_U16 ; + *fmt =AUDIO_FORMAT_U16 ;break ;default :
@@ -341,7 +341,7 @@ static int sdl_init_out(HWVoiceOut *hw, struct audsettings *as,SDL_AudioSpec req, obt;int endianness;int err; -audfmt_e effective_fmt; +AudioFormat effective_fmt;struct audsettings obt_as; req.freq = as->freq;
audio/spiceaudio.c +2 -2
@@ -127,7 +127,7 @@ static int line_out_init(HWVoiceOut *hw, struct audsettings *as, settings.freq =SPICE_INTERFACE_PLAYBACK_FREQ ;#endif settings.nchannels =SPICE_INTERFACE_PLAYBACK_CHAN ; - settings.fmt =AUD_FMT_S16 ; + settings.fmt =AUDIO_FORMAT_S16 ; settings.endianness =AUDIO_HOST_ENDIANNESS ;audio_pcm_init_info (&hw->info, &settings);
@@ -255,7 +255,7 @@ static int line_in_init(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque) settings.freq =SPICE_INTERFACE_RECORD_FREQ ;#endif settings.nchannels =SPICE_INTERFACE_RECORD_CHAN ; - settings.fmt =AUD_FMT_S16 ; + settings.fmt =AUDIO_FORMAT_S16 ; settings.endianness =AUDIO_HOST_ENDIANNESS ;audio_pcm_init_info (&hw->info, &settings);
audio/wavaudio.c +10 -7
@@ -116,20 +116,23 @@ static int wav_init_out(HWVoiceOut *hw, struct audsettings *as, stereo = wav_as.nchannels ==2 ;switch (wav_as.fmt) { -case AUD_FMT_S8 : -case AUD_FMT_U8 : +case AUDIO_FORMAT_S8 : +case AUDIO_FORMAT_U8 : bits16 =0 ;break ; -case AUD_FMT_S16 : -case AUD_FMT_U16 : +case AUDIO_FORMAT_S16 : +case AUDIO_FORMAT_U16 : bits16 =1 ;break ; -case AUD_FMT_S32 : -case AUD_FMT_U32 : +case AUDIO_FORMAT_S32 : +case AUDIO_FORMAT_U32 :dolog ("WAVE files can not handle 32bit formats\n" );return -1 ; + +default : +abort (); } hdr[34 ] = bits16 ?0x10 :0x08 ;
@@ -224,7 +227,7 @@ static int wav_ctl_out (HWVoiceOut *hw, int cmd, ...)static WAVConf glob_conf = { .settings.freq =44100 , .settings.nchannels =2 , - .settings.fmt =AUD_FMT_S16 , + .settings.fmt =AUDIO_FORMAT_S16 , .wav_path ="qemu.wav" };
audio/wavcapture.c +1 -1
@@ -135,7 +135,7 @@ int wav_start_capture (CaptureState *s, const char *path, int freq, as.freq = freq; as.nchannels =1 << stereo; - as.fmt = bits16 ?AUD_FMT_S16 :AUD_FMT_U8 ; + as.fmt = bits16 ?AUDIO_FORMAT_S16 :AUDIO_FORMAT_U8 ; as.endianness =0 ; ops.notify = wav_notify;
hw/arm/omap2.c +1 -1
@@ -269,7 +269,7 @@ static void omap_eac_format_update(struct omap_eac_s *s)* does I2S specify it? */ /* All register writes are 16 bits so we we store 16-bit samples * in the buffers regardless of AGCFR[B8_16] value. */ - fmt.fmt =AUD_FMT_U16 ; + fmt.fmt =AUDIO_FORMAT_U16 ; s->codec.in_voice =AUD_open_in (&s->codec.card, s->codec.in_voice,"eac.codec.in" , s, omap_eac_in_cb, &fmt);
hw/audio/ac97.c +1 -1
@@ -360,7 +360,7 @@ static void open_voice (AC97LinkState *s, int index, int freq) as.freq = freq; as.nchannels =2 ; - as.fmt =AUD_FMT_S16 ; + as.fmt =AUDIO_FORMAT_S16 ; as.endianness =0 ;if (freq >0 ) {
hw/audio/adlib.c +1 -1
@@ -323,7 +323,7 @@ static void adlib_realizefn (DeviceState *dev, Error **errp) as.freq = s->freq; as.nchannels =SHIFT ; - as.fmt =AUD_FMT_S16 ; + as.fmt =AUDIO_FORMAT_S16 ; as.endianness =AUDIO_HOST_ENDIANNESS ;AUD_register_card ("adlib" , &s->card);
hw/audio/cs4231a.c +3 -3
@@ -284,7 +284,7 @@ static void cs_reset_voices (CSState *s, uint32_t val)switch ((val >>5 ) & ((s->dregs[MODE_And_ID] &MODE2 ) ?7 :3 )) {case 0 : - as.fmt =AUD_FMT_U8 ; + as.fmt =AUDIO_FORMAT_U8 ; s->shift = as.nchannels ==2 ;break ;
@@ -294,7 +294,7 @@ static void cs_reset_voices (CSState *s, uint32_t val)case 3 : s->tab = ALawDecompressTable; x_law: - as.fmt =AUD_FMT_S16 ; + as.fmt =AUDIO_FORMAT_S16 ; as.endianness =AUDIO_HOST_ENDIANNESS ; s->shift = as.nchannels ==2 ;break ;
@@ -302,7 +302,7 @@ static void cs_reset_voices (CSState *s, uint32_t val)case 6 : as.endianness =1 ;case 2 : - as.fmt =AUD_FMT_S16 ; + as.fmt =AUDIO_FORMAT_S16 ; s->shift = as.nchannels;break ;
hw/audio/es1370.c +2 -2
@@ -414,14 +414,14 @@ static void es1370_update_voices (ES1370State *s, uint32_t ctl, uint32_t sctl) i, new_freq,1 << (new_fmt &1 ), - (new_fmt &2 ) ?AUD_FMT_S16 :AUD_FMT_U8 , + (new_fmt &2 ) ?AUDIO_FORMAT_S16 :AUDIO_FORMAT_U8 , d->shift);if (new_freq) {struct audsettings as; as.freq = new_freq; as.nchannels =1 << (new_fmt &1 ); - as.fmt = (new_fmt &2 ) ?AUD_FMT_S16 :AUD_FMT_U8 ; + as.fmt = (new_fmt &2 ) ?AUDIO_FORMAT_S16 :AUDIO_FORMAT_U8 ; as.endianness =0 ;if (i ==ADC_CHANNEL ) {
hw/audio/gus.c +1 -1
@@ -242,7 +242,7 @@ static void gus_realizefn (DeviceState *dev, Error **errp) as.freq = s->freq; as.nchannels =2 ; - as.fmt =AUD_FMT_S16 ; + as.fmt =AUDIO_FORMAT_S16 ; as.endianness =GUS_ENDIANNESS ; s->voice = AUD_open_out (
hw/audio/hda-codec.c +9 -9
@@ -97,9 +97,9 @@ static void hda_codec_parse_fmt(uint32_t format, struct audsettings *as) }switch (format &AC_FMT_BITS_MASK ) { -case AC_FMT_BITS_8 : as->fmt =AUD_FMT_S8 ;break ; -case AC_FMT_BITS_16 : as->fmt =AUD_FMT_S16 ;break ; -case AC_FMT_BITS_32 : as->fmt =AUD_FMT_S32 ;break ; +case AC_FMT_BITS_8 : as->fmt =AUDIO_FORMAT_S8 ;break ; +case AC_FMT_BITS_16 : as->fmt =AUDIO_FORMAT_S16 ;break ; +case AC_FMT_BITS_32 : as->fmt =AUDIO_FORMAT_S32 ;break ; } as->nchannels = ((format &AC_FMT_CHAN_MASK ) >>AC_FMT_CHAN_SHIFT ) +1 ;
@@ -128,12 +128,12 @@ static void hda_codec_parse_fmt(uint32_t format, struct audsettings *as)/* -------------------------------------------------------------------------- */ static const char *fmt2name[] = { - [AUD_FMT_U8 ] ="PCM-U8" , - [AUD_FMT_S8 ] ="PCM-S8" , - [AUD_FMT_U16 ] ="PCM-U16" , - [AUD_FMT_S16 ] ="PCM-S16" , - [AUD_FMT_U32 ] ="PCM-U32" , - [AUD_FMT_S32 ] ="PCM-S32" , + [AUDIO_FORMAT_U8 ] ="PCM-U8" , + [AUDIO_FORMAT_S8 ] ="PCM-S8" , + [AUDIO_FORMAT_U16 ] ="PCM-U16" , + [AUDIO_FORMAT_S16 ] ="PCM-S16" , + [AUDIO_FORMAT_U32 ] ="PCM-U32" , + [AUDIO_FORMAT_S32 ] ="PCM-S32" , };typedef struct HDAAudioState HDAAudioState ;
hw/audio/lm4549.c +3 -3
@@ -185,7 +185,7 @@ void lm4549_write(lm4549_state *s,struct audsettings as; as.freq = value; as.nchannels =2 ; - as.fmt =AUD_FMT_S16 ; + as.fmt =AUDIO_FORMAT_S16 ; as.endianness =0 ; s->voice = AUD_open_out(
@@ -255,7 +255,7 @@ static int lm4549_post_load(void *opaque, int version_id)struct audsettings as; as.freq = freq; as.nchannels =2 ; - as.fmt =AUD_FMT_S16 ; + as.fmt =AUDIO_FORMAT_S16 ; as.endianness =0 ; s->voice = AUD_open_out(
@@ -292,7 +292,7 @@ void lm4549_init(lm4549_state *s, lm4549_callback data_req_cb, void* opaque)/* Open a default voice */ as.freq =48000 ; as.nchannels =2 ; - as.fmt =AUD_FMT_S16 ; + as.fmt =AUDIO_FORMAT_S16 ; as.endianness =0 ; s->voice = AUD_open_out(
hw/audio/milkymist-ac97.c +1 -1
@@ -297,7 +297,7 @@ static int milkymist_ac97_init(SysBusDevice *dev) as.freq =48000 ; as.nchannels =2 ; - as.fmt =AUD_FMT_S16 ; + as.fmt =AUDIO_FORMAT_S16 ; as.endianness =1 ; s->voice_in = AUD_open_in(&s->card, s->voice_in,
hw/audio/pcspk.c +1 -1
@@ -112,7 +112,7 @@ static void pcspk_callback(void *opaque, int free)static int pcspk_audio_init (ISABus *bus) {PCSpkState *s = pcspk_state; -struct audsettings as = {PCSPK_SAMPLE_RATE ,1 ,AUD_FMT_U8 ,0 }; +struct audsettings as = {PCSPK_SAMPLE_RATE ,1 ,AUDIO_FORMAT_U8 ,0 };AUD_register_card (s_spk, &s->card);
hw/audio/sb16.c +7 -7
@@ -66,7 +66,7 @@ typedef struct SB16State {int fmt_stereo;int fmt_signed;int fmt_bits; -audfmt_e fmt; +AudioFormat fmt;int dma_auto;int block_size;int fifo;
@@ -221,7 +221,7 @@ static void continue_dma8 (SB16State *s)static void dma_cmd8 (SB16State *s,int mask,int dma_len) { - s->fmt =AUD_FMT_U8 ; + s->fmt =AUDIO_FORMAT_U8 ; s->use_hdma =0 ; s->fmt_bits =8 ; s->fmt_signed =0 ;
@@ -316,18 +316,18 @@ static void dma_cmd (SB16State *s, uint8_t cmd, uint8_t d0, int dma_len)if (16 == s->fmt_bits) {if (s->fmt_signed) { - s->fmt =AUD_FMT_S16 ; + s->fmt =AUDIO_FORMAT_S16 ; }else { - s->fmt =AUD_FMT_U16 ; + s->fmt =AUDIO_FORMAT_U16 ; } }else {if (s->fmt_signed) { - s->fmt =AUD_FMT_S8 ; + s->fmt =AUDIO_FORMAT_S8 ; }else { - s->fmt =AUD_FMT_U8 ; + s->fmt =AUDIO_FORMAT_U8 ; } }
@@ -839,7 +839,7 @@ static void legacy_reset (SB16State *s) as.freq = s->freq; as.nchannels =1 ; - as.fmt =AUD_FMT_U8 ; + as.fmt =AUDIO_FORMAT_U8 ; as.endianness =0 ; s->voice = AUD_open_out (
hw/audio/wm8750.c +2 -2
@@ -201,7 +201,7 @@ static void wm8750_set_format(WM8750State *s) in_fmt.endianness =0 ; in_fmt.nchannels =2 ; in_fmt.freq = s->adc_hz; - in_fmt.fmt =AUD_FMT_S16 ; + in_fmt.fmt =AUDIO_FORMAT_S16 ; s->adc_voice[0 ] =AUD_open_in (&s->card, s->adc_voice[0 ],CODEC ".input1" , s, wm8750_audio_in_cb, &in_fmt);
@@ -214,7 +214,7 @@ static void wm8750_set_format(WM8750State *s) out_fmt.endianness =0 ; out_fmt.nchannels =2 ; out_fmt.freq = s->dac_hz; - out_fmt.fmt =AUD_FMT_S16 ; + out_fmt.fmt =AUDIO_FORMAT_S16 ; s->dac_voice[0 ] =AUD_open_out (&s->card, s->dac_voice[0 ],CODEC ".speaker" , s, wm8750_audio_out_cb, &out_fmt);
hw/input/tsc210x.c +1 -1
@@ -315,7 +315,7 @@ static void tsc2102_audio_output_update(TSC210xState *s) fmt.endianness =0 ; fmt.nchannels =2 ; fmt.freq = s->codec.tx_rate; - fmt.fmt =AUD_FMT_S16 ; + fmt.fmt =AUDIO_FORMAT_S16 ; s->dac_voice[0 ] =AUD_open_out (&s->card, s->dac_voice[0 ],"tsc2102.sink" , s, (void *) tsc210x_audio_out_cb, &fmt);
hw/usb/dev-audio.c +1 -1
@@ -646,7 +646,7 @@ static void usb_audio_realize(USBDevice *dev, Error **errp) s->out.vol[1 ] =240 ;/* 0 dB */ s->out.as.freq =USBAUDIO_SAMPLE_RATE ; s->out.as.nchannels =2 ; - s->out.as.fmt =AUD_FMT_S16 ; + s->out.as.fmt =AUDIO_FORMAT_S16 ; s->out.as.endianness =0 ;streambuf_init (&s->out.buf, s->buffer);
ui/vnc.c +7 -7
@@ -2379,12 +2379,12 @@ static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)if (len ==4 )return 10 ;switch (read_u8 (data,4 )) { -case 0 : vs->as.fmt =AUD_FMT_U8 ;break ; -case 1 : vs->as.fmt =AUD_FMT_S8 ;break ; -case 2 : vs->as.fmt =AUD_FMT_U16 ;break ; -case 3 : vs->as.fmt =AUD_FMT_S16 ;break ; -case 4 : vs->as.fmt =AUD_FMT_U32 ;break ; -case 5 : vs->as.fmt =AUD_FMT_S32 ;break ; +case 0 : vs->as.fmt =AUDIO_FORMAT_U8 ;break ; +case 1 : vs->as.fmt =AUDIO_FORMAT_S8 ;break ; +case 2 : vs->as.fmt =AUDIO_FORMAT_U16 ;break ; +case 3 : vs->as.fmt =AUDIO_FORMAT_S16 ;break ; +case 4 : vs->as.fmt =AUDIO_FORMAT_U32 ;break ; +case 5 : vs->as.fmt =AUDIO_FORMAT_S32 ;break ;default :VNC_DEBUG ("Invalid audio format %d\n" ,read_u8 (data,4 ));vnc_client_error (vs);
@@ -3065,7 +3065,7 @@ void vnc_init_state(VncState *vs) vs->as.freq =44100 ; vs->as.nchannels =2 ; - vs->as.fmt =AUD_FMT_S16 ; + vs->as.fmt =AUDIO_FORMAT_S16 ; vs->as.endianness =0 ;qemu_mutex_init (&vs->output_mutex);
Signature · 1 line
2.4.3
PATCH v3 8/8 audio: -audiodev command line option
In reply to Kővágó, ZoltánThis patch adds an -audiodev command line option, and deprecates the QEMU_* environment variables for audio backend configuration. It's syntax is similar to existing options (-netdev, -device, etc): -audiodev driver_name,property=value,...
Audio drivers now get an Audiodev * as config paramters, instead of the global audio_option structs. There is some code in audio/audio_legacy.c that converts the old environment variables to audiodev options (this way backends do not have to worry about legacy options). It also contains a replacement of -audio-help, which prints out the equivalent -audiodev based config of the currently specified environment variables.
Although now it's possible to specify multiple -audiodev options on command line, multiple audio backends are not supported yet.
---
Changes from v2:
* fixed alsa threshold
* updated to audio qapi changes
Changes from v1:
* updated to everything usecs without suffix
* better rounding when converting between usecs and frames/samples/bytes
* bugfixes in audio_legacy.c
* fixed code broken by qemu_opts changes by Markus
audio/Makefile.objs | 2 +- audio/alsaaudio.c | 311 ++++++-------------- audio/audio.c | 741 +++++++++++++----------------------------------- audio/audio.h | 23 +- audio/audio_int.h | 7 +- audio/audio_legacy.c | 328 +++++++++++++++++++++ audio/audio_template.h | 13 +- audio/coreaudio.c | 49 +--- audio/dsound_template.h | 6 +- audio/dsoundaudio.c | 60 ++-- audio/noaudio.c | 3 +- audio/ossaudio.c | 154 +++------- audio/paaudio.c | 80 ++---- audio/sdlaudio.c | 24 +- audio/spiceaudio.c | 7 +- audio/wavaudio.c | 60 +--- qemu-options.hx | 230 ++++++++++++++- vl.c | 9 +- 18 files changed, 997 insertions(+), 1110 deletions(-) create mode 100644 audio/audio_legacy.c
audio/Makefile.objs +1 -1
@@ -1,4 +1,4 @@ -common-obj-y = audio.o noaudio.o wavaudio.o mixeng.o +common-obj-y = audio.o audio_legacy.o noaudio.o wavaudio.o mixeng.o common-obj-$(CONFIG_SDL) += sdlaudio.o common-obj-$(CONFIG_OSS) += ossaudio.o common-obj-$(CONFIG_SPICE) += spiceaudio.o
audio/alsaaudio.c +84 -227
480 lines not on this page · raw message
audio/audio.c +198 -543
890 lines not on this page · raw message
audio/audio.h +20 -3
@@ -24,7 +24,10 @@#ifndef QEMU_AUDIO_H #define QEMU_AUDIO_H +#include <stdarg.h> #include "config-host.h" +#include "qapi-types.h" +#include "qemu/option.h" #include "qemu/queue.h" typedef void (*audio_callback_fn ) (void *opaque,int avail);
@@ -35,12 +38,21 @@ typedef void (*audio_callback_fn) (void *opaque, int avail);#define AUDIO_HOST_ENDIANNESS 0#endif -struct audsettings { +typedef struct audsettings {int freq;int nchannels;AudioFormat fmt;int endianness; -}; +}audsettings ; + +audsettings audiodev_to_audsettings (AudiodevPerDirectionOptions *pdo); +int audioformat_bytes_per_sample (AudioFormat fmt); +int audio_buffer_frames (AudiodevPerDirectionOptions *pdo, +audsettings *as,int def_usecs); +int audio_buffer_samples (AudiodevPerDirectionOptions *pdo, +audsettings *as,int def_usecs); +int audio_buffer_bytes (AudiodevPerDirectionOptions *pdo, +audsettings *as,int def_usecs); typedef enum { AUD_CNOTIFY_ENABLE,
@@ -77,10 +89,11 @@ typedef struct QEMUAudioTimeStamp {uint64_t old_ts; } QEMUAudioTimeStamp; +extern QemuOptsList qemu_audiodev_opts; + void AUD_vlog (const char *cap, const char *fmt, va_list ap) GCC_FMT_ATTR(2, 0); void AUD_log (const char *cap, const char *fmt, ...) GCC_FMT_ATTR(2, 3); -void AUD_help (void );void AUD_register_card (const char *name,QEMUSoundCard *card);void AUD_remove_card (QEMUSoundCard *card); CaptureVoiceOut *AUD_add_capture (
@@ -154,4 +167,8 @@ static inline void *advance (void *p, int incr)int wav_start_capture (CaptureState *s,const char *path,int freq,int bits,int nchannels); +void audio_set_options (void ); +void audio_handle_legacy_opts (void ); +void audio_legacy_help (void ); +#endif /* audio.h */
audio/audio_int.h +5 -2
@@ -143,8 +143,7 @@ struct SWVoiceIn {struct audio_driver {const char *name;const char *descr; -struct audio_option *options; -void *(*init) (void ); +void *(*init) (Audiodev *);void (*fini) (void *);struct audio_pcm_ops *pcm_ops;int can_be_default;
@@ -190,6 +189,7 @@ struct SWVoiceCap {struct AudioState {struct audio_driver *drv; +Audiodev *dev;void *drv_opaque;QEMUTimer *ts;
@@ -200,6 +200,7 @@ struct AudioState {int nb_hw_voices_out;int nb_hw_voices_in;int vm_running; +int64_t period_ticks; };extern struct audio_driver no_audio_driver;
@@ -213,6 +214,8 @@ extern struct audio_driver pa_audio_driver;extern struct audio_driver spice_audio_driver;extern const struct mixeng_volume nominal_volume; +extern struct audio_driver *drvtab[]; +void audio_pcm_init_info (struct audio_pcm_info *info,struct audsettings *as);void audio_pcm_info_clear_buf (struct audio_pcm_info *info,void *buf,int len);
audio/audio_legacy.c new file +328 -0
328 lines not on this page · raw message
audio/audio_template.h +9 -4
@@ -302,8 +302,10 @@ static HW *glue (audio_pcm_hw_add_new_, TYPE) (struct audsettings *as)static HW *glue (audio_pcm_hw_add_ ,TYPE ) (struct audsettings *as) {HW *hw; +AudioState *s = &glob_audio_state; +AudiodevPerDirectionOptions *pdo = s->dev->TYPE; -if (glue (conf.fixed_,TYPE ).enabled &&glue (conf.fixed_,TYPE ).greedy) { +if (pdo->fixed_settings) { hw =glue (audio_pcm_hw_add_new_,TYPE ) (as);if (hw) {return hw;
@@ -331,9 +333,11 @@ static SW *glue (audio_pcm_create_voice_pair_, TYPE) (SW *sw;HW *hw;struct audsettings hw_as; +AudioState *s = &glob_audio_state; +AudiodevPerDirectionOptions *pdo = s->dev->TYPE; -if (glue (conf.fixed_,TYPE ).enabled) { - hw_as =glue (conf.fixed_,TYPE ).settings; +if (pdo->fixed_settings) { + hw_as =audiodev_to_audsettings (pdo); }else { hw_as = *as;
@@ -398,6 +402,7 @@ SW *glue (AUD_open_, TYPE) ( ) {AudioState *s = &glob_audio_state; +AudiodevPerDirectionOptions *pdo = s->dev->TYPE;if (audio_bug (AUDIO_FUNC , !card || !name || !callback_fn || !as)) { dolog ("card=%p name=%p callback_fn=%p as=%p\n",
@@ -422,7 +427,7 @@ SW *glue (AUD_open_, TYPE) (return sw; } -if (!glue (conf.fixed_,TYPE ).enabled && sw) { +if (!pdo->fixed_settings && sw) {glue (AUD_close_,TYPE ) (card, sw); sw =NULL ; }
audio/coreaudio.c +11 -38
100 lines not on this page · raw message
audio/dsound_template.h +3 -3
@@ -167,17 +167,18 @@ static int dsound_init_out(HWVoiceOut *hw, struct audsettings *as,dsound *s = drv_opaque;WAVEFORMATEX wfx;struct audsettings obt_as; -DSoundConf *conf = &s->conf;#ifdef DSBTYPE_IN const char *typ ="ADC" ;DSoundVoiceIn *ds = (DSoundVoiceIn *) hw;DSCBUFFERDESC bd;DSCBCAPS bc; +AudiodevPerDirectionOptions *pdo = s->dev->in;#else const char *typ ="DAC" ;DSoundVoiceOut *ds = (DSoundVoiceOut *) hw;DSBUFFERDESC bd;DSBCAPS bc; +AudiodevPerDirectionOptions *pdo = s->dev->out;#endif if (!s->FIELD2) {
@@ -193,8 +194,8 @@ static int dsound_init_out(HWVoiceOut *hw, struct audsettings *as,memset (&bd,0 ,sizeof (bd)); bd.dwSize =sizeof (bd); bd.lpwfxFormat = &wfx; + bd.dwBufferBytes =audio_buffer_bytes (pdo, as,92880 );#ifdef DSBTYPE_IN - bd.dwBufferBytes = conf->bufsize_in; hr = IDirectSoundCapture_CreateCaptureBuffer ( s->dsound_capture, &bd,
@@ -203,7 +204,6 @@ static int dsound_init_out(HWVoiceOut *hw, struct audsettings *as, );#else bd.dwFlags =DSBCAPS_STICKYFOCUS |DSBCAPS_GETCURRENTPOSITION2 ; - bd.dwBufferBytes = conf->bufsize_out; hr = IDirectSound_CreateSoundBuffer ( s->dsound, &bd,
audio/dsoundaudio.c +17 -43
123 lines not on this page · raw message
audio/noaudio.c +1 -2
@@ -134,7 +134,7 @@ static int no_ctl_in (HWVoiceIn *hw, int cmd, ...)return 0 ; } -static void *no_audio_init (void ) +static void *no_audio_init (Audiodev *dev) {return &no_audio_init; }
@@ -161,7 +161,6 @@ static struct audio_pcm_ops no_pcm_ops = {struct audio_driver no_audio_driver = { .name ="none" , .descr ="Timer based audio emulation" , - .options =NULL , .init = no_audio_init, .fini = no_audio_fini, .pcm_ops = &no_pcm_ops,
audio/ossaudio.c +43 -111
301 lines not on this page · raw message
audio/paaudio.c +28 -52
183 lines not on this page · raw message
audio/sdlaudio.c +5 -19
@@ -44,18 +44,13 @@ typedef struct SDLVoiceOut {int decr; } SDLVoiceOut; -static struct { -int nb_samples; -} conf = { - .nb_samples =1024 -}; -static struct SDLAudioState {int exit;SDL_mutex *mutex;SDL_sem *sem;int initialized;bool driver_created; +Audiodev *dev; } glob_sdl;typedef struct SDLAudioState SDLAudioState ;
@@ -347,7 +342,7 @@ static int sdl_init_out(HWVoiceOut *hw, struct audsettings *as, req.freq = as->freq; req.format =aud_to_sdlfmt (as->fmt); req.channels = as->nchannels; - req.samples = conf.nb_samples; + req.samples =audio_buffer_samples (s->dev->out, as,11610 ); req.callback = sdl_callback; req.userdata = sdl;
@@ -391,7 +386,7 @@ static int sdl_ctl_out (HWVoiceOut *hw, int cmd, ...)return 0 ; } -static void *sdl_audio_init (void ) +static void *sdl_audio_init (Audiodev *dev) {SDLAudioState *s = &glob_sdl;if (s->driver_created) {
@@ -420,6 +415,7 @@ static void *sdl_audio_init (void) } s->driver_created = true; + s->dev = dev;return s; }
@@ -431,18 +427,9 @@ static void sdl_audio_fini (void *opaque)SDL_DestroyMutex (s->mutex);SDL_QuitSubSystem (SDL_INIT_AUDIO ); s->driver_created = false; + s->dev =NULL ; } -static struct audio_option sdl_options[] = { - { - .name ="SAMPLES" , - .tag =AUD_OPT_INT , - .valp = &conf.nb_samples, - .descr ="Size of SDL buffer in samples" - }, - {/* End of list */ } -}; -static struct audio_pcm_ops sdl_pcm_ops = { .init_out = sdl_init_out, .fini_out = sdl_fini_out,
@@ -454,7 +441,6 @@ static struct audio_pcm_ops sdl_pcm_ops = {struct audio_driver sdl_audio_driver = { .name ="sdl" , .descr ="SDL http://www.libsdl.org" , - .options = sdl_options, .init = sdl_audio_init, .fini = sdl_audio_fini, .pcm_ops = &sdl_pcm_ops,
audio/spiceaudio.c +1 -6
@@ -74,7 +74,7 @@ static const SpiceRecordInterface record_sif = { .base.minor_version = SPICE_INTERFACE_RECORD_MINOR, }; -static void *spice_audio_init (void ) +static void *spice_audio_init (Audiodev *dev) {if (!using_spice) {return NULL ;
@@ -370,10 +370,6 @@ static int line_in_ctl (HWVoiceIn *hw, int cmd, ...)return 0 ; } -static struct audio_option audio_options[] = { - {/* end of list */ }, -}; -static struct audio_pcm_ops audio_callbacks = { .init_out = line_out_init, .fini_out = line_out_fini,
@@ -391,7 +387,6 @@ static struct audio_pcm_ops audio_callbacks = {struct audio_driver spice_audio_driver = { .name ="spice" , .descr ="spice audio driver" , - .options = audio_options, .init = spice_audio_init, .fini = spice_audio_fini, .pcm_ops = &audio_callbacks,
audio/wavaudio.c +10 -50
106 lines not on this page · raw message
qemu-options.hx +225 -5
218 lines not on this page · raw message
The rest of this diff is not shown. View the raw message.
Signature · 1 line
2.4.3
Part of the diff is not shown here. View the raw message.