audio: -audiodev option, multiple options
Subsystems (5)
v2 cover audio: -audiodev option, multiple options
This patch series adds support to multiple audio backends. Afterwards I add support to multiple backends. Audio fronteds gain a new audiodev option to specify the id of the audiodev to use. The audiodev= option is required, unless you use the old environment variable based configuration, in that case it must not used (and you can't use multiple backends).
Finally I also make mixeng usage optional, it can save us some useless format converting when not needed. Also makes easier to support formats currently not supported by qemu (as only the backend has to support it, not the mixeng).
For easier testing pull https://github.com/DirtYiCE/qemu.git tag audio-multi-v2.
Please review.
---
Changes from v1:
* added qemu_opts_print patch as it's still not merged
* splitted the big -audiodev and remove mixeng from backend commits
* tons of bugfixes and typo fixing
Kővágó, Zoltán (49):
opts: produce valid command line in qemu_opts_print
qapi: support implicit structs in OptsVisitor
qapi: convert NumaOptions into a flat union
net: remove NetLegacy struct
net: use Netdev instead of NetClientOptions in client init
qapi: change Netdev into a flat union
qapi: reorder NetdevBase and Netdev
qapi: qapi for audio backends
qapi: support nested structs in OptsVisitor
audio: use qapi AudioFormat instead of audfmt_e
audio: -audiodev command line option: documentation
audio: -audiodev command line option basic implementation
alsaaudio: port to -audiodev config
coreaudio: port to -audiodev config
dsoundaudio: port to -audiodev config
noaudio: port to -audiodev config
ossaudio: port to -audiodev config
paaudio: port to -audiodev config
sdlaudio: port to -audiodev config
spiceaudio: port to -audiodev config
wavaudio: port to -audiodev config
audio: -audiodev command line option: cleanup
audio: reduce glob_audio_state usage
audio: basic support for multi backend audio
audio: add audiodev properties to frontends
audio: audiodev= parameters no longer optional when -audiodev present
paaudio: do not create multiple connections to the same server
paaudio: do not move stream when sink/source name is specified
paaudio: properly disconnect streams in fini_*
audio: remove audio_MIN, audio_MAX
audio: do not run each backend in audio_run
paaudio: fix playback glitches
audio: remove read and write pcm_ops
audio: use size_t where makes sense
audio: api for mixeng code free backends
alsaaudio: port to the new audio backend api
coreaudio: port to the new audio backend api
dsoundaudio: port to the new audio backend api
noaudio: port to the new audio backend api
ossaudio: port to the new audio backend api
paaudio: port to the new audio backend api
sdlaudio: port to the new audio backend api
spiceaudio: port to the new audio backend api
wavaudio: port to the new audio backend api
audio: remove remains of the old backend api
audio: unify input and output mixeng buffer management
audio: remove hw->samples, buffer_size_in/out pcm_ops
audio: common rate control code for timer based outputs
audio: split ctl_* functions into enable_* and volume_*
Makefile | 4 +- audio/Makefile.objs | 3 +- audio/alsaaudio.c | 740 +++++----------- audio/audio.c | 1390 +++++++++++++++---------------- audio/audio.h | 66 +- audio/audio_int.h | 121 +-- audio/audio_legacy.c | 333 ++++++++ audio/audio_pt_int.c | 173 ---- audio/audio_pt_int.h | 22 - audio/audio_template.h | 89 +- audio/audio_win_int.c | 18 +- audio/coreaudio.c | 198 ++--- audio/dsound_template.h | 59 +- audio/dsoundaudio.c | 445 +++------- audio/mixeng.h | 11 +- audio/noaudio.c | 98 +-- audio/ossaudio.c | 588 +++++-------- audio/paaudio.c | 828 +++++++----------- audio/rate_template.h | 2 +- audio/sdlaudio.c | 183 ++-- audio/spiceaudio.c | 283 +++---- audio/wavaudio.c | 156 +--- audio/wavcapture.c | 8 +- block.c | 2 +- configure | 5 - hmp-commands.hx | 11 +- hw/arm/musicpal.c | 2 +- hw/arm/omap2.c | 2 +- hw/audio/ac97.c | 13 +- hw/audio/adlib.c | 7 +- hw/audio/cs4231a.c | 11 +- hw/audio/es1370.c | 17 +- hw/audio/gus.c | 9 +- hw/audio/hda-codec.c | 19 +- hw/audio/lm4549.c | 6 +- hw/audio/milkymist-ac97.c | 16 +- hw/audio/pcspk.c | 5 +- hw/audio/pl041.c | 1 + hw/audio/sb16.c | 17 +- hw/audio/wm8750.c | 14 +- hw/core/qdev-properties-system.c | 59 +- 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 | 3 +- hw/usb/dev-network.c | 2 +- include/hw/qdev-properties.h | 3 + include/net/net.h | 4 +- monitor.c | 26 +- net/clients.h | 20 +- net/dump.c | 8 +- net/hub.c | 24 +- net/l2tpv3.c | 8 +- net/net.c | 129 ++- net/netmap.c | 6 +- net/slirp.c | 8 +- net/socket.c | 10 +- net/tap-win32.c | 8 +- net/tap.c | 28 +- net/vde.c | 8 +- net/vhost-user.c | 14 +- numa.c | 2 +- qapi-schema.json | 132 +-- qapi/audio.json | 263 ++++++ qapi/opts-visitor.c | 131 ++- qemu-options.hx | 227 ++++- tests/qapi-schema/qapi-schema-test.json | 9 +- tests/qapi-schema/qapi-schema-test.out | 6 +- tests/qemu-iotests/017.out | 2 +- tests/qemu-iotests/018.out | 2 +- tests/qemu-iotests/019.out | 2 +- tests/qemu-iotests/020.out | 2 +- tests/qemu-iotests/024.out | 2 +- tests/qemu-iotests/028.out | 4 +- tests/qemu-iotests/034.out | 2 +- tests/qemu-iotests/037.out | 2 +- tests/qemu-iotests/038.out | 2 +- tests/qemu-iotests/039.out | 2 +- tests/qemu-iotests/043.out | 12 +- tests/qemu-iotests/046.out | 2 +- tests/qemu-iotests/049.out | 22 +- tests/qemu-iotests/050.out | 2 +- tests/qemu-iotests/051.out | 2 +- tests/qemu-iotests/061.out | 10 +- tests/qemu-iotests/069.out | 2 +- tests/qemu-iotests/073.out | 2 +- tests/qemu-iotests/079.out | 18 +- tests/qemu-iotests/082.out | 4 +- tests/qemu-iotests/085.out | 38 +- tests/qemu-iotests/095.out | 4 +- tests/qemu-iotests/097.out | 16 +- tests/qemu-iotests/098.out | 8 +- tests/qemu-iotests/110.out | 4 +- tests/qemu-iotests/112.out | 4 +- tests/qemu-iotests/114.out | 2 +- tests/qemu-iotests/115.out | 2 +- tests/qemu-iotests/121.out | 4 +- tests/qemu-iotests/122.out | 6 +- tests/qemu-iotests/130.out | 4 +- tests/qemu-iotests/common.filter | 2 +- tests/test-opts-visitor.c | 34 + ui/vnc.c | 29 +- ui/vnc.h | 2 + util/qemu-option.c | 29 +- vl.c | 11 +- 131 files changed, 3578 insertions(+), 3910 deletions(-) create mode 100644 audio/audio_legacy.c delete mode 100644 audio/audio_pt_int.c delete mode 100644 audio/audio_pt_int.h create mode 100644 qapi/audio.json
Signature · 1 line
2.5.0
PATCH v2 1/49 opts: produce valid command line in qemu_opts_print
This 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 id=, if the option has an id
* do not print separator before the first element
* do not quote string arguments
* properly escape commas (,) for QEMU
--- block.c | 2 +- tests/qemu-iotests/017.out | 2 +- tests/qemu-iotests/018.out | 2 +- tests/qemu-iotests/019.out | 2 +- tests/qemu-iotests/020.out | 2 +- tests/qemu-iotests/024.out | 2 +- tests/qemu-iotests/028.out | 4 ++-- tests/qemu-iotests/034.out | 2 +- tests/qemu-iotests/037.out | 2 +- tests/qemu-iotests/038.out | 2 +- tests/qemu-iotests/039.out | 2 +- tests/qemu-iotests/043.out | 12 ++++++------ tests/qemu-iotests/046.out | 2 +- tests/qemu-iotests/049.out | 22 +++++++++++----------- tests/qemu-iotests/050.out | 2 +- tests/qemu-iotests/051.out | 2 +- tests/qemu-iotests/061.out | 10 +++++----- tests/qemu-iotests/069.out | 2 +- tests/qemu-iotests/073.out | 2 +- tests/qemu-iotests/079.out | 18 +++++++++--------- tests/qemu-iotests/082.out | 4 ++-- tests/qemu-iotests/085.out | 38 +++++++++++++++++++------------------- tests/qemu-iotests/095.out | 4 ++-- tests/qemu-iotests/097.out | 16 ++++++++-------- tests/qemu-iotests/098.out | 8 ++++---- tests/qemu-iotests/110.out | 4 ++-- tests/qemu-iotests/112.out | 4 ++-- tests/qemu-iotests/114.out | 2 +- tests/qemu-iotests/115.out | 2 +- tests/qemu-iotests/121.out | 4 ++-- tests/qemu-iotests/122.out | 6 +++--- tests/qemu-iotests/130.out | 4 ++-- tests/qemu-iotests/common.filter | 2 +- util/qemu-option.c | 29 ++++++++++++++++++++++++++--- 34 files changed, 123 insertions(+), 100 deletions(-)
block.c +1 -1
@@ -3869,7 +3869,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 ("" ); }
tests/qemu-iotests/017.out +1 -1
@@ -269,7 +269,7 @@ wrote 65536/65536 bytes at offset 4295032832 No errors were found on the image. Creating test image with backing file -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=6442450944 backing_file='TEST_DIR/t.IMGFMT.base' +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=6442450944 backing_file=TEST_DIR/t.IMGFMT.base Filling test image === IO: pattern 1
tests/qemu-iotests/018.out +1 -1
@@ -269,7 +269,7 @@ wrote 65536/65536 bytes at offset 4295032832 No errors were found on the image. Creating test image with backing file -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=6442450944 backing_file='TEST_DIR/t.IMGFMT.base' +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=6442450944 backing_file=TEST_DIR/t.IMGFMT.base Filling test image === IO: pattern 1
tests/qemu-iotests/019.out +1 -1
@@ -269,7 +269,7 @@ wrote 65536/65536 bytes at offset 4296015872 No errors were found on the image. Creating test image with backing file -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=6442450944 backing_file='TEST_DIR/t.IMGFMT.base' +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=6442450944 backing_file=TEST_DIR/t.IMGFMT.base Filling test image === IO: pattern 43
tests/qemu-iotests/020.out +1 -1
@@ -269,7 +269,7 @@ wrote 65536/65536 bytes at offset 4295032832 No errors were found on the image. Creating test image with backing file -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=6442450944 backing_file='TEST_DIR/t.IMGFMT.base' +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=6442450944 backing_file=TEST_DIR/t.IMGFMT.base Filling test image === IO: pattern 1
tests/qemu-iotests/024.out +1 -1
@@ -33,7 +33,7 @@ wrote 131072/131072 bytes at offset 786432 128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) Creating COW image -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 backing_file='TEST_DIR/t.IMGFMT.base_old' +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 backing_file=TEST_DIR/t.IMGFMT.base_old === IO: pattern 0x33 wrote 262144/262144 bytes at offset 0 256 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
tests/qemu-iotests/028.out +2 -2
@@ -70,7 +70,7 @@ wrote 512/512 bytes at offset 3221225984 No errors were found on the image. Creating test image with backing file -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=4294968832 backing_file='TEST_DIR/t.IMGFMT.base' +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=4294968832 backing_file=TEST_DIR/t.IMGFMT.base Filling test image === IO: pattern 196
@@ -468,7 +468,7 @@ No errors were found on the image. block-backup -Formatting 'TEST_DIR/t.IMGFMT.copy', fmt=IMGFMT size=4294968832 backing_file='TEST_DIR/t.IMGFMT.base' backing_fmt='IMGFMT' +Formatting 'TEST_DIR/t.IMGFMT.copy', fmt=IMGFMT size=4294968832 backing_file=TEST_DIR/t.IMGFMT.base backing_fmt=IMGFMT (qemu) (qemu) i[K[Din[K[D[Dinf[K[D[D[Dinfo[K[D[D[D[Dinfo [K[D[D[D[D[Dinfo b[K[D[D[D[D[D[Dinfo bl[K[D[D[D[D[D[D[Dinfo blo[K[D[D[D[D[D[D[D[Dinfo bloc[K[D[D[D[D[D[D[D[D[Dinfo block[K[D[D[D[D[D[D[D[D[D[Dinfo block-[K[D[D[D[D[D[D[D[D[D[D[Dinfo block-j[K[D[D[D[D[D[D[D[D[D[D[D[Dinfo block-jo[K[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block-job[K[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block-jobs[K Type backup, device disk: Completed 0 of 4294968832 bytes, speed limit 0 bytes/s
tests/qemu-iotests/034.out +1 -1
@@ -4,7 +4,7 @@ QA output created by 034 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 wrote 1048576/1048576 bytes at offset 0 1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=6442450944 backing_file='TEST_DIR/t.IMGFMT.base' +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=6442450944 backing_file=TEST_DIR/t.IMGFMT.base == zero write with backing file == wrote 196608/196608 bytes at offset 65536
tests/qemu-iotests/037.out +1 -1
@@ -514,7 +514,7 @@ wrote 512/512 bytes at offset 130048 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) wrote 512/512 bytes at offset 130560 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=6442450944 backing_file='TEST_DIR/t.IMGFMT.base' +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=6442450944 backing_file=TEST_DIR/t.IMGFMT.base == COW in a single cluster == wrote 2048/2048 bytes at offset 0
tests/qemu-iotests/038.out +1 -1
@@ -514,7 +514,7 @@ wrote 65536/65536 bytes at offset 16646144 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) wrote 65536/65536 bytes at offset 16711680 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=6442450944 backing_file='TEST_DIR/t.IMGFMT.base' +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=6442450944 backing_file=TEST_DIR/t.IMGFMT.base == Some concurrent requests touching the same cluster == wrote 65536/65536 bytes at offset XXX
tests/qemu-iotests/039.out +1 -1
@@ -66,7 +66,7 @@ No errors were found on the image. == Committing to a backing file with lazy_refcounts=on == Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=134217728 -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file='TEST_DIR/t.IMGFMT.base' +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file=TEST_DIR/t.IMGFMT.base wrote 512/512 bytes at offset 0 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) Image committed.
tests/qemu-iotests/043.out +6 -6
@@ -4,20 +4,20 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 == backing file references self == qemu-img: Backing file 'TEST_DIR/t.IMGFMT' creates an infinite loop. Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file='TEST_DIR/t.IMGFMT.base' +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file=TEST_DIR/t.IMGFMT.base == parent references self == qemu-img: Backing file 'TEST_DIR/t.IMGFMT' creates an infinite loop. Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file='TEST_DIR/t.IMGFMT.1.base' -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file='TEST_DIR/t.IMGFMT.2.base' -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file='TEST_DIR/t.IMGFMT.3.base' +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file=TEST_DIR/t.IMGFMT.1.base +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file=TEST_DIR/t.IMGFMT.2.base +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file=TEST_DIR/t.IMGFMT.3.base == ancestor references another ancestor == qemu-img: Backing file 'TEST_DIR/t.IMGFMT.2.base' creates an infinite loop. Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file='TEST_DIR/t.IMGFMT.1.base' -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file='TEST_DIR/t.IMGFMT.2.base' +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file=TEST_DIR/t.IMGFMT.1.base +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file=TEST_DIR/t.IMGFMT.2.base == finite chain of length 3 (human) == image: TEST_DIR/t.IMGFMT
tests/qemu-iotests/046.out +1 -1
@@ -66,7 +66,7 @@ wrote 65536/65536 bytes at offset 1966080 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) wrote 65536/65536 bytes at offset 2031616 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=6442450944 backing_file='TEST_DIR/t.IMGFMT.base' +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=6442450944 backing_file=TEST_DIR/t.IMGFMT.base == Some concurrent requests touching the same cluster == blkdebug: Suspended request 'A'
tests/qemu-iotests/049.out +11 -11
@@ -157,30 +157,30 @@ Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off cluster_si == Check compat level option == qemu-img create -f qcow2 -o compat=0.10 TEST_DIR/t.qcow2 64M -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat='0.10' encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=0.10 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 qemu-img create -f qcow2 -o compat=1.1 TEST_DIR/t.qcow2 64M -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat='1.1' encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=1.1 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 qemu-img create -f qcow2 -o compat=0.42 TEST_DIR/t.qcow2 64M qemu-img: TEST_DIR/t.qcow2: Invalid compatibility level: '0.42' -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat='0.42' encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=0.42 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 qemu-img create -f qcow2 -o compat=foobar TEST_DIR/t.qcow2 64M qemu-img: TEST_DIR/t.qcow2: Invalid compatibility level: 'foobar' -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat='foobar' encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=foobar encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 == Check preallocation option == qemu-img create -f qcow2 -o preallocation=off TEST_DIR/t.qcow2 64M -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off cluster_size=65536 preallocation='off' lazy_refcounts=off refcount_bits=16 +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off cluster_size=65536 preallocation=off lazy_refcounts=off refcount_bits=16 qemu-img create -f qcow2 -o preallocation=metadata TEST_DIR/t.qcow2 64M -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off cluster_size=65536 preallocation='metadata' lazy_refcounts=off refcount_bits=16 +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off cluster_size=65536 preallocation=metadata lazy_refcounts=off refcount_bits=16 qemu-img create -f qcow2 -o preallocation=1234 TEST_DIR/t.qcow2 64M qemu-img: TEST_DIR/t.qcow2: invalid parameter value: 1234 -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off cluster_size=65536 preallocation='1234' lazy_refcounts=off refcount_bits=16 +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off cluster_size=65536 preallocation=1234 lazy_refcounts=off refcount_bits=16 == Check encryption option ==
@@ -199,16 +199,16 @@ Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=on cluster_siz == Check lazy_refcounts option (only with v3) == qemu-img create -f qcow2 -o compat=1.1,lazy_refcounts=off TEST_DIR/t.qcow2 64M -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat='1.1' encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=1.1 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 qemu-img create -f qcow2 -o compat=1.1,lazy_refcounts=on TEST_DIR/t.qcow2 64M -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat='1.1' encryption=off cluster_size=65536 lazy_refcounts=on refcount_bits=16 +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=1.1 encryption=off cluster_size=65536 lazy_refcounts=on refcount_bits=16 qemu-img create -f qcow2 -o compat=0.10,lazy_refcounts=off TEST_DIR/t.qcow2 64M -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat='0.10' encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=0.10 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 qemu-img create -f qcow2 -o compat=0.10,lazy_refcounts=on TEST_DIR/t.qcow2 64M qemu-img: TEST_DIR/t.qcow2: Lazy refcounts only supported with compatibility level 1.1 and above (use compat=1.1 or greater) -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat='0.10' encryption=off cluster_size=65536 lazy_refcounts=on refcount_bits=16 +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=0.10 encryption=off cluster_size=65536 lazy_refcounts=on refcount_bits=16 *** done
tests/qemu-iotests/050.out +1 -1
@@ -7,7 +7,7 @@ wrote 1048576/1048576 bytes at offset 0 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=10485760 wrote 1048576/1048576 bytes at offset 0 1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=10485760 backing_file='TEST_DIR/t.IMGFMT.old' +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=10485760 backing_file=TEST_DIR/t.IMGFMT.old wrote 1048576/1048576 bytes at offset 0 1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
tests/qemu-iotests/051.out +1 -1
@@ -1,6 +1,6 @@ QA output created by 051 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file='TEST_DIR/t.IMGFMT.base' +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file=TEST_DIR/t.IMGFMT.base === Unknown option ===
tests/qemu-iotests/061.out +5 -5
@@ -334,7 +334,7 @@ read 131072/131072 bytes at offset 0 Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864 wrote 131072/131072 bytes at offset 0 128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file='TEST_DIR/t.IMGFMT.base' +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.base read 131072/131072 bytes at offset 0 128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) wrote 65536/65536 bytes at offset 0
@@ -350,7 +350,7 @@ read 65536/65536 bytes at offset 65536 Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864 wrote 131072/131072 bytes at offset 0 128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file='TEST_DIR/t.IMGFMT.base' +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.base wrote 65536/65536 bytes at offset 0 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) wrote 131072/131072 bytes at offset 0
@@ -369,7 +369,7 @@ read 65536/65536 bytes at offset 65536 Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864 wrote 131072/131072 bytes at offset 0 128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file='TEST_DIR/t.IMGFMT.base' +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.base wrote 131072/131072 bytes at offset 0 128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) No errors were found on the image.
@@ -393,7 +393,7 @@ read 67108864/67108864 bytes at offset 0 === Testing progress report without snapshot === Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=4294967296 -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=4294967296 backing_file='TEST_DIR/t.IMGFMT.base' +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=4294967296 backing_file=TEST_DIR/t.IMGFMT.base wrote 65536/65536 bytes at offset 0 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) wrote 65536/65536 bytes at offset 1073741824
@@ -408,7 +408,7 @@ No errors were found on the image. === Testing progress report with snapshot === Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=4294967296 -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=4294967296 backing_file='TEST_DIR/t.IMGFMT.base' +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=4294967296 backing_file=TEST_DIR/t.IMGFMT.base wrote 65536/65536 bytes at offset 0 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) wrote 65536/65536 bytes at offset 1073741824
tests/qemu-iotests/069.out +1 -1
@@ -3,6 +3,6 @@ QA output created by 069 === Creating an image with a backing file and deleting that file === Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=131072 -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=131072 backing_file='TEST_DIR/t.IMGFMT.base' +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=131072 backing_file=TEST_DIR/t.IMGFMT.base qemu-io: can't open device TEST_DIR/t.IMGFMT: Could not open backing file: Could not open 'TEST_DIR/t.IMGFMT.base': No such file or directory *** done
tests/qemu-iotests/073.out +1 -1
@@ -2,7 +2,7 @@ QA output created by 073 == creating backing file == Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=134217728 -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file='TEST_DIR/t.IMGFMT.base' +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file=TEST_DIR/t.IMGFMT.base wrote 134217728/134217728 bytes at offset 0 128 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
tests/qemu-iotests/079.out +9 -9
@@ -1,14 +1,14 @@ QA output created by 079 === Check option preallocation and cluster_size === -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=4294967296 preallocation='metadata' -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=4294967296 preallocation='metadata' -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=4294967296 preallocation='metadata' -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=4294967296 preallocation='metadata' -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=4294967296 preallocation='metadata' -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=4294967296 preallocation='metadata' -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=4294967296 preallocation='metadata' -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=4294967296 preallocation='metadata' +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=4294967296 preallocation=metadata +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=4294967296 preallocation=metadata +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=4294967296 preallocation=metadata +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=4294967296 preallocation=metadata +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=4294967296 preallocation=metadata +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=4294967296 preallocation=metadata +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=4294967296 preallocation=metadata +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=4294967296 preallocation=metadata qemu-img: TEST_DIR/t.IMGFMT: Cluster size must be a power of two between 512 and 2048k -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=4294967296 preallocation='metadata' +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=4294967296 preallocation=metadata *** done
tests/qemu-iotests/082.out +2 -2
@@ -147,10 +147,10 @@ refcount_bits Width of a reference count entry in bits nocow Turn off copy-on-write (valid only on btrfs) Testing: create -f qcow2 -o backing_file=TEST_DIR/t.qcow2,,help TEST_DIR/t.qcow2 128M -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 backing_file='TEST_DIR/t.qcow2,help' encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/t.qcow2,,help encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 Testing: create -f qcow2 -o backing_file=TEST_DIR/t.qcow2,,? TEST_DIR/t.qcow2 128M -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 backing_file='TEST_DIR/t.qcow2,?' encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/t.qcow2,,? encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 Testing: create -f qcow2 -o backing_file=TEST_DIR/t.qcow2, -o help TEST_DIR/t.qcow2 128M qemu-img: Invalid option list: backing_file=TEST_DIR/t.qcow2,
tests/qemu-iotests/085.out +19 -19
@@ -11,7 +11,7 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 === Create a single snapshot on virtio0 === -Formatting 'TEST_DIR/1-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file='TEST_DIR/t.qcow2.orig' backing_fmt='qcow2' encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 +Formatting 'TEST_DIR/1-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/t.qcow2.orig backing_fmt=qcow2 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 {"return": {}} === Invalid command - missing device and nodename ===
@@ -25,31 +25,31 @@ Formatting 'TEST_DIR/1-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file === Create several transactional group snapshots === -Formatting 'TEST_DIR/2-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file='TEST_DIR/1-snapshot-v0.qcow2' backing_fmt='qcow2' encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 -Formatting 'TEST_DIR/2-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file='TEST_DIR/t.qcow2' backing_fmt='qcow2' encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 +Formatting 'TEST_DIR/2-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/1-snapshot-v0.qcow2 backing_fmt=qcow2 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 +Formatting 'TEST_DIR/2-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/t.qcow2 backing_fmt=qcow2 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 {"return": {}} -Formatting 'TEST_DIR/3-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file='TEST_DIR/2-snapshot-v0.qcow2' backing_fmt='qcow2' encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 -Formatting 'TEST_DIR/3-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file='TEST_DIR/2-snapshot-v1.qcow2' backing_fmt='qcow2' encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 +Formatting 'TEST_DIR/3-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/2-snapshot-v0.qcow2 backing_fmt=qcow2 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 +Formatting 'TEST_DIR/3-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/2-snapshot-v1.qcow2 backing_fmt=qcow2 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 {"return": {}} -Formatting 'TEST_DIR/4-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file='TEST_DIR/3-snapshot-v0.qcow2' backing_fmt='qcow2' encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 -Formatting 'TEST_DIR/4-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file='TEST_DIR/3-snapshot-v1.qcow2' backing_fmt='qcow2' encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 +Formatting 'TEST_DIR/4-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/3-snapshot-v0.qcow2 backing_fmt=qcow2 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 +Formatting 'TEST_DIR/4-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/3-snapshot-v1.qcow2 backing_fmt=qcow2 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 {"return": {}} -Formatting 'TEST_DIR/5-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file='TEST_DIR/4-snapshot-v0.qcow2' backing_fmt='qcow2' encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 -Formatting 'TEST_DIR/5-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file='TEST_DIR/4-snapshot-v1.qcow2' backing_fmt='qcow2' encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 +Formatting 'TEST_DIR/5-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/4-snapshot-v0.qcow2 backing_fmt=qcow2 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 +Formatting 'TEST_DIR/5-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/4-snapshot-v1.qcow2 backing_fmt=qcow2 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 {"return": {}} -Formatting 'TEST_DIR/6-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file='TEST_DIR/5-snapshot-v0.qcow2' backing_fmt='qcow2' encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 -Formatting 'TEST_DIR/6-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file='TEST_DIR/5-snapshot-v1.qcow2' backing_fmt='qcow2' encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 +Formatting 'TEST_DIR/6-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/5-snapshot-v0.qcow2 backing_fmt=qcow2 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 +Formatting 'TEST_DIR/6-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/5-snapshot-v1.qcow2 backing_fmt=qcow2 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 {"return": {}} -Formatting 'TEST_DIR/7-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file='TEST_DIR/6-snapshot-v0.qcow2' backing_fmt='qcow2' encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 -Formatting 'TEST_DIR/7-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file='TEST_DIR/6-snapshot-v1.qcow2' backing_fmt='qcow2' encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 +Formatting 'TEST_DIR/7-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/6-snapshot-v0.qcow2 backing_fmt=qcow2 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 +Formatting 'TEST_DIR/7-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/6-snapshot-v1.qcow2 backing_fmt=qcow2 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 {"return": {}} -Formatting 'TEST_DIR/8-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file='TEST_DIR/7-snapshot-v0.qcow2' backing_fmt='qcow2' encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 -Formatting 'TEST_DIR/8-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file='TEST_DIR/7-snapshot-v1.qcow2' backing_fmt='qcow2' encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 +Formatting 'TEST_DIR/8-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/7-snapshot-v0.qcow2 backing_fmt=qcow2 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 +Formatting 'TEST_DIR/8-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/7-snapshot-v1.qcow2 backing_fmt=qcow2 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 {"return": {}} -Formatting 'TEST_DIR/9-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file='TEST_DIR/8-snapshot-v0.qcow2' backing_fmt='qcow2' encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 -Formatting 'TEST_DIR/9-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file='TEST_DIR/8-snapshot-v1.qcow2' backing_fmt='qcow2' encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 +Formatting 'TEST_DIR/9-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/8-snapshot-v0.qcow2 backing_fmt=qcow2 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 +Formatting 'TEST_DIR/9-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/8-snapshot-v1.qcow2 backing_fmt=qcow2 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 {"return": {}} -Formatting 'TEST_DIR/10-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file='TEST_DIR/9-snapshot-v0.qcow2' backing_fmt='qcow2' encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 -Formatting 'TEST_DIR/10-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file='TEST_DIR/9-snapshot-v1.qcow2' backing_fmt='qcow2' encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 +Formatting 'TEST_DIR/10-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/9-snapshot-v0.qcow2 backing_fmt=qcow2 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 +Formatting 'TEST_DIR/10-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/9-snapshot-v1.qcow2 backing_fmt=qcow2 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 {"return": {}} *** done
tests/qemu-iotests/095.out +2 -2
@@ -1,7 +1,7 @@ QA output created by 095 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=5242880 -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=104857600 backing_file='TEST_DIR/t.IMGFMT.base' -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=104857600 backing_file='TEST_DIR/t.IMGFMT.snp1' +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=104857600 backing_file=TEST_DIR/t.IMGFMT.base +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=104857600 backing_file=TEST_DIR/t.IMGFMT.snp1 === Base image info before commit and resize === image: TEST_DIR/t.IMGFMT.base
tests/qemu-iotests/097.out +8 -8
@@ -3,8 +3,8 @@ QA output created by 097 === Test pass 0 === Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864 -Formatting 'TEST_DIR/t.IMGFMT.itmd', fmt=IMGFMT size=67108864 backing_file='TEST_DIR/t.IMGFMT.base' -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file='TEST_DIR/t.IMGFMT.itmd' +Formatting 'TEST_DIR/t.IMGFMT.itmd', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.base +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.itmd wrote 196608/196608 bytes at offset 0 192 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) wrote 131072/131072 bytes at offset 65536
@@ -32,8 +32,8 @@ Offset Length File === Test pass 1 === Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864 -Formatting 'TEST_DIR/t.IMGFMT.itmd', fmt=IMGFMT size=67108864 backing_file='TEST_DIR/t.IMGFMT.base' -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file='TEST_DIR/t.IMGFMT.itmd' +Formatting 'TEST_DIR/t.IMGFMT.itmd', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.base +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.itmd wrote 196608/196608 bytes at offset 0 192 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) wrote 131072/131072 bytes at offset 65536
@@ -62,8 +62,8 @@ Offset Length File === Test pass 2 === Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864 -Formatting 'TEST_DIR/t.IMGFMT.itmd', fmt=IMGFMT size=67108864 backing_file='TEST_DIR/t.IMGFMT.base' -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file='TEST_DIR/t.IMGFMT.itmd' +Formatting 'TEST_DIR/t.IMGFMT.itmd', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.base +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.itmd wrote 196608/196608 bytes at offset 0 192 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) wrote 131072/131072 bytes at offset 65536
@@ -92,8 +92,8 @@ Offset Length File === Test pass 3 === Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864 -Formatting 'TEST_DIR/t.IMGFMT.itmd', fmt=IMGFMT size=67108864 backing_file='TEST_DIR/t.IMGFMT.base' -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file='TEST_DIR/t.IMGFMT.itmd' +Formatting 'TEST_DIR/t.IMGFMT.itmd', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.base +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.itmd wrote 196608/196608 bytes at offset 0 192 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) wrote 131072/131072 bytes at offset 65536
tests/qemu-iotests/098.out +4 -4
@@ -3,7 +3,7 @@ QA output created by 098 === l1_update === Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864 -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file='TEST_DIR/t.IMGFMT.base' +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.base wrote 65536/65536 bytes at offset 0 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) qemu-img: Could not empty blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.IMGFMT: Input/output error
@@ -12,7 +12,7 @@ No errors were found on the image. === empty_image_prepare === Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864 -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file='TEST_DIR/t.IMGFMT.base' +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.base wrote 65536/65536 bytes at offset 0 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) qemu-img: Could not empty blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.IMGFMT: Input/output error
@@ -25,7 +25,7 @@ No errors were found on the image. === reftable_update === Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864 -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file='TEST_DIR/t.IMGFMT.base' +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.base wrote 65536/65536 bytes at offset 0 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) qemu-img: Could not empty blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.IMGFMT: Input/output error
@@ -39,7 +39,7 @@ No errors were found on the image. === refblock_alloc === Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864 -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file='TEST_DIR/t.IMGFMT.base' +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.base wrote 65536/65536 bytes at offset 0 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) qemu-img: Could not empty blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.IMGFMT: Input/output error
tests/qemu-iotests/110.out +2 -2
@@ -3,7 +3,7 @@ QA output created by 110 === Reconstructable filename === Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864 -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file='t.IMGFMT.base' +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file=t.IMGFMT.base image: TEST_DIR/t.IMGFMT file format: IMGFMT virtual size: 64M (67108864 bytes)
@@ -15,5 +15,5 @@ qemu-img: Cannot use relative backing file names for 'json:{"driver": "IMGFMT", === Backing name is always relative to the backed image === -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file='t.IMGFMT.base' +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file=t.IMGFMT.base *** done
tests/qemu-iotests/112.out +2 -2
@@ -21,9 +21,9 @@ refcount bits: 16 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 refcount bits: 16 -qemu-img: TEST_DIR/t.IMGFMT: Different refcount widths than 16 bits require compatibility level 1.1 or above (use compat=1.1 or greater) +qemu-img: TEST_DIR/t.IMGFMT: Different refcount widths than 16 bits require compatibility level 1.1 or above (use or greater) Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 -qemu-img: TEST_DIR/t.IMGFMT: Different refcount widths than 16 bits require compatibility level 1.1 or above (use compat=1.1 or greater) +qemu-img: TEST_DIR/t.IMGFMT: Different refcount widths than 16 bits require compatibility level 1.1 or above (use or greater) Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 === Snapshot limit on refcount_bits=1 ===
tests/qemu-iotests/114.out +1 -1
@@ -1,6 +1,6 @@ QA output created by 114 Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864 -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file='TEST_DIR/t.IMGFMT.base' +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.base image: TEST_DIR/t.IMGFMT file format: IMGFMT virtual size: 64M (67108864 bytes)
tests/qemu-iotests/115.out +1 -1
@@ -2,7 +2,7 @@ QA output created by 115 === Testing large refcount and L1 table === -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=268435456 preallocation='metadata' +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=268435456 preallocation=metadata No errors were found on the image. 100.00% allocated clusters *** done
tests/qemu-iotests/121.out +2 -2
@@ -4,7 +4,7 @@ QA output created by 121 --- Test 1 --- -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=66060288 preallocation='metadata' +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=66060288 preallocation=metadata Image resized. wrote 1049600/1049600 bytes at offset 65011712 1.001 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
@@ -14,7 +14,7 @@ No errors were found on the image. --- Test 2 --- -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=66061312 preallocation='metadata' +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=66061312 preallocation=metadata Image resized. wrote 133120/133120 bytes at offset 66060288 130 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
tests/qemu-iotests/122.out +3 -3
@@ -5,7 +5,7 @@ wrote 67108864/67108864 bytes at offset 0 === Check allocation status regression with -B === -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file='TEST_DIR/t.IMGFMT.base' +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.base wrote 3145728/3145728 bytes at offset 0 3 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) Offset Length File
@@ -14,7 +14,7 @@ Offset Length File === Check that zero clusters are kept in overlay === -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file='TEST_DIR/t.IMGFMT.base' +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.base wrote 3145728/3145728 bytes at offset 0 3 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) read 3145728/3145728 bytes at offset 0
@@ -125,7 +125,7 @@ read 63963136/63963136 bytes at offset 3145728 Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864 wrote 33554432/33554432 bytes at offset 0 32 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file='TEST_DIR/t.IMGFMT.base' +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.base wrote 3145728/3145728 bytes at offset 0 3 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
tests/qemu-iotests/130.out +2 -2
@@ -14,7 +14,7 @@ QEMU X.Y.Z monitor - type 'help' for more information image: TEST_DIR/t.IMGFMT file format: IMGFMT virtual size: 64M (67108864 bytes) -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file='TEST_DIR/t.IMGFMT.orig' backing_fmt='raw' +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.orig backing_fmt=raw QEMU X.Y.Z monitor - type 'help' for more information (qemu) c[K[Dco[K[D[Dcom[K[D[D[Dcomm[K[D[D[D[Dcommi[K[D[D[D[D[Dcommit[K[D[D[D[D[D[Dcommit [K[D[D[D[D[D[D[Dcommit i[K[D[D[D[D[D[D[D[Dcommit id[K[D[D[D[D[D[D[D[D[Dcommit ide[K[D[D[D[D[D[D[D[D[D[Dcommit ide0[K[D[D[D[D[D[D[D[D[D[D[Dcommit ide0-[K[D[D[D[D[D[D[D[D[D[D[D[Dcommit ide0-h[K[D[D[D[D[D[D[D[D[D[D[D[D[Dcommit ide0-hd[K[D[D[D[D[D[D[D[D[D[D[D[D[D[Dcommit ide0-hd0[K (qemu)
@@ -32,7 +32,7 @@ wrote 4096/4096 bytes at offset 0 image: TEST_DIR/t.IMGFMT file format: IMGFMT virtual size: 64M (67108864 bytes) -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file='TEST_DIR/t.IMGFMT.orig' backing_fmt='raw' +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.orig backing_fmt=raw wrote 4096/4096 bytes at offset 0 4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) image: TEST_DIR/t.IMGFMT
tests/qemu-iotests/common.filter +1 -1
@@ -182,7 +182,7 @@ _filter_img_create() -e "s# encryption=off##g" \ -e "s# cluster_size=[0-9]\\+##g" \ -e "s# table_size=[0-9]\\+##g" \ - -e "s# compat='[^']*'##g" \ + -e "s# compat=[^ ]*##g" \ -e "s# compat6=\\(on\\|off\\)##g" \ -e "s# static=\\(on\\|off\\)##g" \ -e "s# zeroed_grain=\\(on\\|off\\)##g" \
util/qemu-option.c +26 -3
@@ -730,14 +730,35 @@ void qemu_opts_del(QemuOpts *opts)g_free (opts); } -void qemu_opts_print (QemuOpts *opts,const char *sep) +/* print value, escaping any commas in value */ +static void escaped_print (const char *value) +{ +const char *ptr; + +for (ptr = value; *ptr; ++ptr) { +if (*ptr ==',' ) { +putchar (',' ); + } +putchar (*ptr); + } +} + +void qemu_opts_print (QemuOpts *opts,const char *separator) {QemuOpt *opt;QemuOptDesc *desc = opts->list->desc; +const char *sep ="" ; + +if (opts->id) { +printf ("id=%s" , opts->id);/* passed id_wellformed -> no commas */ + sep = separator; + }if (desc[0 ].name ==NULL ) { QTAILQ_FOREACH(opt, &opts->head, next) { -printf ("%s%s=\"%s\"" , sep, opt->name, opt->str); +printf ("%s%s=" , sep, opt->name); +escaped_print (opt->str); + sep = separator; }return ; }
@@ -750,13 +771,15 @@ void qemu_opts_print(QemuOpts *opts, const char *sep)continue ; }if (desc->type ==QEMU_OPT_STRING ) { -printf ("%s%s='%s'" , sep, desc->name, value); +printf ("%s%s=" , sep, desc->name); +escaped_print (value); }else if ((desc->type ==QEMU_OPT_SIZE || desc->type ==QEMU_OPT_NUMBER ) && opt) {printf ("%s%s=%" PRId64, sep, desc->name, opt->value.uint); }else {printf ("%s%s=%s" , sep, desc->name, value); } + sep = separator; } }
Signature · 1 line
2.5.0
Re: [Qemu-devel] [PATCH v2 01/49] opts: produce valid command line in qemu_opts_print
Quoted 22 lines · Zoltán
This 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 id=, if the option has an id
* do not print separator before the first element
* do not quote string arguments
* properly escape commas (,) for QEMUReviewed-by Markus Armbruster <[email protected]>Reviewed-by Stefan Hajnoczi <[email protected]>Reviewed-by Marc-André Lureau <[email protected]>Signed-off-by Kővágó, Zoltán <[email protected]>---
+++
b/util/qemu-option.cutil/qemu-option.c +1
-1@@ -730,14 +730,35 @@ void qemu_opts_del(QemuOpts *opts)g_free (opts); } -void qemu_opts_print (QemuOpts *opts,const char *sep) +/* print value, escaping any commas in value */
util/qemu-option.c void qemu_opts_del(QemuOpts *opts) · line 743
Quoted 10 lines
util/qemu-option.c +10
-0+static void escaped_print (const char *value) +{ +const char *ptr; + +for (ptr = value; *ptr; ++ptr) { +if (*ptr ==',' ) { +putchar (',' ); + } +putchar (*ptr); + }
I guess this not in a hot path. (If it were, I might suggest using strchr() to skip to the next command, and fwrite() to output blocks of data between commas, rather than putchar() at a time; but unless it shows up in a benchmark that might be premature optimization)
Signature · 2 lines
Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org
PATCH v2 2/49 qapi: support implicit structs in OptsVisitor
In reply to Kővágó, ZoltánThey 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.5.0
Re: [Qemu-devel] [PATCH v2 02/49] qapi: support implicit structs in OptsVisitor
Quoted 8 lines · Zoltán
They are required for flat unions (you still have to allocate the structs).
Signed-off-by Kővágó, Zoltán <[email protected]>--- qapi/opts-visitor.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
However, note that I may be touching the signature of these functions in one of my pending patches (last RFC was here[1], although I'm currently rebasing on top of Markus v4/v5 of introspection, and may yet tweak how things work before my next post)
[1] https://lists.gnu.org/archive/html/qemu-devel/2015-08/msg02097.html
Whoever gets in first doesn't have to do a merge conflict resolution :)
Signature · 2 lines
Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org
PATCH v2 3/49 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
@@ -227,7 +227,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.5.0
Re: [Qemu-devel] [PATCH v2 03/49] qapi: convert NumaOptions into a flat union
Quoted 1 line · Zoltán
Signed-off-by Kővágó, Zoltán <[email protected]>
I don't understand QAPI enough to understand why exactly this is needed (so I would like to get feedback from somebody who actually understands QAPI unions), but I have one comment below.
[...]
qapi-schema.json line 3572
Quoted 9 lines
##
qapi-schema.json +8
-0+# @NumaDriver +# +# List of possible numa drivers. +# +# Since: 2.5 +## +{ 'enum': 'NumaDriver', + 'data': [ 'node' ] }
Why is the name "NumaDriver"? Below, the field is called "type", so why not something like "NumaOptionType"?
Quoted 34 lines
qapi-schema.json +28
-0+ +## +# @NumaCommonOptions +# +# Common set of numa options. +# +# @type: the numa driver to use +# +# Since: 2.5 +## +{ 'struct': 'NumaCommonOptions', + 'data': { + 'type': 'NumaDriver' } } + +## +# @NumaOptions +# +# A discriminated record of NUMA options. (for OptsVisitor) +# +# Since 2.1 +## +{ 'union': 'NumaOptions', + 'base': 'NumaCommonOptions', + 'discriminator': 'type', + 'data': { + 'node': 'NumaNodeOptions' }} + +## # @HostMemPolicy # # Host memory policy typesSignature · 1 line
2.5.0
Signature · 1 line
Eduardo
Re: [Qemu-devel] [PATCH v2 03/49] qapi: convert NumaOptions into a flat union
2015-08-22 01:13 keltezéssel, Eduardo Habkost írta:
Quoted 6 lines · Zoltán
Quoted 1 line
Signed-off-by Kővágó, Zoltán <[email protected]>I don't understand QAPI enough to understand why exactly this is needed (so I would like to get feedback from somebody who actually understands QAPI unions), but I have one comment below.
It's needed so the option visitor can support nested structures properly without flattening them (or breaking backward compatibility).
There is some discussion here:
http://lists.nongnu.org/archive/html/qemu-devel/2015-06/msg04438.html
But basically the thing is that with new new opts visitor, unless we convert NumaOptions into a flat union, the user would have to type -numa node,node.nodeid=foo instead of -numa node,nodeid=foo which would break backward compatibility.
Quoted 14 lines
[...]
qapi-schema.json line 3572
Quoted 9 lines
##
qapi-schema.json +8
-0+# @NumaDriver +# +# List of possible numa drivers. +# +# Since: 2.5 +## +{ 'enum': 'NumaDriver', + 'data': [ 'node' ] }Why is the name "NumaDriver"? Below, the field is called "type", so why not something like "NumaOptionType"?
No particular reason other than the example in docs/qapi-code-gen.txt used driver. The field is called type because in the non-flat union the discriminator is called type.
Quoted 35 lines
Quoted 34 lines
qapi-schema.json +28
-1+ +## +# @NumaCommonOptions +# +# Common set of numa options. +# +# @type: the numa driver to use +# +# Since: 2.5 +## +{ 'struct': 'NumaCommonOptions', + 'data': { + 'type': 'NumaDriver' } } + +## +# @NumaOptions +# +# A discriminated record of NUMA options. (for OptsVisitor) +# +# Since 2.1 +## +{ 'union': 'NumaOptions', + 'base': 'NumaCommonOptions', + 'discriminator': 'type', + 'data': { + 'node': 'NumaNodeOptions' }} + +## # @HostMemPolicy # # Host memory policy types --2.5.0
Re: [Qemu-devel] [PATCH v2 03/49] qapi: convert NumaOptions into a flat union
Quoted 11 lines · Kővágó Zoltán
2015-08-22 01:13 keltezéssel, Eduardo Habkost írta:
Quoted 6 lines · Zoltán
Quoted 1 line
Signed-off-by Kővágó, Zoltán <[email protected]>I don't understand QAPI enough to understand why exactly this is needed (so I would like to get feedback from somebody who actually understands QAPI unions), but I have one comment below.
It's needed so the option visitor can support nested structures properly without flattening them (or breaking backward compatibility).
Quoted 7 lines
There is some discussion here:
http://lists.nongnu.org/archive/html/qemu-devel/2015-06/msg04438.htmlBut basically the thing is that with new new opts visitor, unless we convert NumaOptions into a flat union, the user would have to type -numa node,node.nodeid=foo instead of -numa node,nodeid=foo which would break backward compatibility.
As long as somebody who understands QAPI says the changes make sense and should work, I am OK with them if the following is changed:
Quoted 14 lines
Quoted 13 lines
[...]
qapi-schema.json line 3572
Quoted 9 lines
##
qapi-schema.json +8
-0+# @NumaDriver +# +# List of possible numa drivers. +# +# Since: 2.5 +## +{ 'enum': 'NumaDriver', + 'data': [ 'node' ] }Why is the name "NumaDriver"? Below, the field is called "type", so why not something like "NumaOptionType"?
Quoted 3 lines
No particular reason other than the example in
docs/qapi-code-gen.txtused driver. The field is called type because in the non-flat union the discriminator is called type.
In the docs/qapi-code-gen.txt example, the option is about an actual blockdev driver, and the discriminator is really called "driver".
In this case, the field is called "type" and has nothing to do with drivers, so something like NumaOptionType makes more sense.
Signature · 1 line
Eduardo
Re: [Qemu-devel] [PATCH v2 03/49] qapi: convert NumaOptions into a flat union
Quoted 2 lines · Eduardo Habkost
As long as somebody who understands QAPI says the changes make sense and should work, I am OK with them if the following is changed:
That would be me, right? See my other mail for my tentative R-b; although if you start renaming things due to this discussion, maybe I should review v3 more closely after all.
Quoted 11 lines
Quoted 10 lines
Quoted 6 lines
qapi-schema.json line 3572
Quoted 3 lines
qapi-schema.json +3
-0+## +{ 'enum': 'NumaDriver', + 'data': [ 'node' ] }Why is the name "NumaDriver"? Below, the field is called "type", so why not something like "NumaOptionType"?
No particular reason other than the example in
docs/qapi-code-gen.txtused driver. The field is called type because in the non-flat union the discriminator is called type.
Quoted 5 lines
In the
docs/qapi-code-gen.txtexample, the option is about an actual blockdev driver, and the discriminator is really called "driver".In this case, the field is called "type" and has nothing to do with drivers, so something like NumaOptionType makes more sense.
The enum name is not ABI (we can name it whatever makes sense), but does show up in the C code that interacts with the generated type. In fact, if you could name the enum type 'NumaOptionsKind', then the C enum name would not change (staying at NUMA_OPTIONS_KIND_NODE instead of your change to NUMA_DRIVER_NODE). Except that right now, the qapi generator doesn't allow user-defined types ending in 'Kind'. :(
I don't know if naming it NumaDriver makes sense; and so your suggestion of naming it NumaOptionsType may be better in the long run. It would make your C enum become NUMA_OPTIONS_TYPE_NODE.
Or maybe you wait for me to do a followup patch to the qapi generator to allow user-defined types ending in 'Kind'.
Signature · 2 lines
Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org
Re: [Qemu-devel] [PATCH v2 03/49] qapi: convert NumaOptions into a flat union
In reply to Kővágó, ZoltánQuoted 1 line · Zoltán
Signed-off-by Kővágó, Zoltán <[email protected]>
The subject line is a one-line "what", and the commit body should be the "why" - all but the most trivial "what" deserve a non-empty commit body.
In particular, I think you NEED to mention in the commit body that the conversion does not strictly follow the QMP wire equivalency between simple and flat unions as spelled out in docs/qapi-code-gen.txt, but that this is okay because we do not have any QMP commands that use the NumaOptions type to begin with (so there is no observable change to any commands sent over QMP). Meanwhile, mention that the change is made to convert the generated C code into something that will ultimately be easier to work with.
Quoted 9 lines
--- numa.c | 2 +- qapi-schema.json | 47 ++++++++++++++++++++++++++++++++++++----------- 2 files changed, 37 insertions(+), 12 deletions(-)+++
b/numa.c
numa.c static int parse_numa(void *opaque, QemuOpts *opts, Error **errp) · line 230
Quoted 5 lines
numa.c +1
-1@@ -227,7 +227,7 @@ static int parse_numa(void *opaque, QemuOpts *opts, Error **errp) }switch (object->kind) { -case NUMA_OPTIONS_KIND_NODE : +case NUMA_DRIVER_NODE :
Now that commit 0f61af3 has landed, you'll have to rebase your patch to use 'switch (object->type) {' here. Basically, the conversion from simple to flat union now (temporarily) generates a different tag name for simple unions than for flat unions (although I have a pending patch
[1] that solves that, but by using object->type everywhere).
[1] https://lists.gnu.org/archive/html/qemu-devel/2015-08/msg02061.html
Quoted 4 lines
qapi-schema.json +1
-0+++ b/qapi-schema.json@@ -3536,17 +3536,6 @@ 'data': { '*console':'int', 'events': [ 'InputEvent' ] } }
qapi-schema.json line 3547
Quoted 10 lines
qapi-schema.json +0
-9## -# @NumaOptions -# -# A discriminated record of NUMA options. (for OptsVisitor) -# -# Since 2.1 -## -{ 'union': 'NumaOptions', - 'data': { - 'node': 'NumaNodeOptions' }}
If we were following the equivalency documented in docs/qapi-code-gen.txt, then this part is okay (you are removing the simple union),...
qapi-schema.json line 3572
Quoted 9 lines
qapi-schema.json +8
-0## +# @NumaDriver +# +# List of possible numa drivers. +# +# Since: 2.5 +## +{ 'enum': 'NumaDriver', + 'data': [ 'node' ] }
...this part is okay (you are creating a new enum, which covers all branches present in the former simple union),...
qapi-schema.json line 3585
Quoted 13 lines
qapi-schema.json +13
-0+ +## +# @NumaCommonOptions +# +# Common set of numa options. +# +# @type: the numa driver to use +# +# Since: 2.5 +## +{ 'struct': 'NumaCommonOptions', + 'data': { + 'type': 'NumaDriver' } }
...this part is okay (you are creating a new base type, which consists of a single common member named 'type' of the new enum type),...
[By the way, while the base type is currently required, I have a pending patch that would add syntax sugar to avoid it, so maybe you want to wait for my patch [2] to land?
[2] https://lists.gnu.org/archive/html/qemu-devel/2015-08/msg02321.html
so you could write 'base': { 'type': 'NumaDriver' } directly in the flat union, instead of having to declare NumaCommonOptions]
qapi-schema.json line 3598
Quoted 13 lines
qapi-schema.json +13
-0+ +## +# @NumaOptions +# +# A discriminated record of NUMA options. (for OptsVisitor) +# +# Since 2.1 +## +{ 'union': 'NumaOptions', + 'base': 'NumaCommonOptions', + 'discriminator': 'type', + 'data': { + 'node': 'NumaNodeOptions' }}
...but this part is missing one piece of the conversion (to be strictly QMP compatible with the simple union, each branch of the flat union must be a NEW type that contains a single member 'data' of the old type).
That is, if we were TRYING to preserve QMP compatibility, we'd need:
{ 'struct': 'NumaNodeOptionsWrapper',
'data': { 'data': 'NumaNodeOptions' } }
{ 'union': 'NumaOptions', 'base': 'NumaCommonOptions',
'discriminator': 'type', 'data': {
'node': 'NumaNodeOptionsWrapper' } }The difference on the wire is that the old simple union, or with my version of the flat union, would allow:
{ 'command': 'foo', 'arguments': {
'type': 'numa', 'data': { 'nodeid': 1 } } }while the new flat union as you wrote it reduces nesting:
{ 'command': 'foo', 'arguments': {
'type': 'numa', 'nodeid': 1 } }That said, there is another point of view to worry about, which is what C structures get generated. Here, I'm using output after Markus' v4 series is applied (since it is slightly more legible than current qemu.git mainline generated output) (and although I still have further pending patches that improve it further). The pre-patch simple union would generate:
struct NumaOptions {
NumaOptionsKind kind;
union { /* union tag is @kind */
void *data;
NumaNodeOptions *node;
};
};and your version would generate (notice the rename from 'kind' to 'type'):
struct NumaOptions {
/* Members inherited from NumaCommonOptions: */
NumaDriver type;
/* Own members: */
union { /* union tag is @type */
void *data;
NumaNodeOptions *node;
};
};but my proposal to keep QMP compatibility would generate an incompatible layer of boxing:
struct NumaOptions {
/* Members inherited from NumaCommonOptions: */
NumaDriver type;
/* Own members: */
union { /* union tag is @type */
void *data;
NumaNodeOptionsWrapper *node;
};
};So, in conclusion, since no existing QMP command used the old type, and your choice of changes preserved the generated struct layout, it means we have no change to command line parsing and no user-visible changes to worry about. And I'm fine with this patch, once you improve the commit message and rebase to mainline:
Signature · 2 lines
Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org
PATCH v2 4/49 net: remove NetLegacy struct
In reply to Kővágó, ZoltánNetLegacy is just Netdev with some extra fields (name, vlan) and an optional id. This patch merges the two structs, and net_client_init1 got some extra checks to make sure only accept valid -netdev command lines. This is some extra work, but allows us to uniformly manage both legacy -net and non-legacy -netdev in code.
--- net/net.c | 42 +++++++++++++++++++++--------------------- qapi-schema.json | 30 +++++++++--------------------- 2 files changed, 30 insertions(+), 42 deletions(-)
net/net.c +21 -21
@@ -911,17 +911,29 @@ static int (* const net_client_init_fun[NET_CLIENT_OPTIONS_KIND_MAX])( }; -static int net_client_init1 (const void *object,int is_netdev,Error **errp) +static int net_client_init1 (const Netdev *netdev,int is_netdev,Error **errp) { -const NetClientOptions *opts; +const NetClientOptions *opts = netdev->opts;const char *name;NetClientState *peer =NULL ;if (is_netdev) { -const Netdev *netdev = object; - opts = netdev->opts; name = netdev->id; +/* validate -netdev option: has id, no vlan or name */ +if (!netdev->has_id) { +error_setg (errp,QERR_MISSING_PARAMETER ,"id" ); +return -1 ; + } +if (netdev->has_name) { +error_setg (errp,QERR_INVALID_PARAMETER ,"name" ); +return -1 ; + } +if (netdev->has_vlan) { +error_setg (errp,QERR_INVALID_PARAMETER ,"vlan" ); +return -1 ; + } +if (opts->kind ==NET_CLIENT_OPTIONS_KIND_DUMP || opts->kind ==NET_CLIENT_OPTIONS_KIND_NIC || !net_client_init_fun[opts->kind]) {
@@ -930,10 +942,8 @@ static int net_client_init1(const void *object, int is_netdev, Error **errp)return -1 ; } }else { -const NetLegacy *net = object; - opts = net->opts;/* missing optional values have been initialized to "all bits zero" */ - name = net->has_id ? net->id : net->name; + name = netdev->has_id ? netdev->id : netdev->name;if (opts->kind ==NET_CLIENT_OPTIONS_KIND_NONE ) {return 0 ;/* nothing to do */
@@ -954,7 +964,7 @@ static int net_client_init1(const void *object, int is_netdev, Error **errp)/* Do not add to a vlan if it's a nic with a netdev= parameter. */ if (opts->kind !=NET_CLIENT_OPTIONS_KIND_NIC || !opts->nic->has_netdev) { - peer =net_hub_add_port (net->has_vlan ? net->vlan :0 ,NULL ); + peer =net_hub_add_port (netdev->has_vlan ? netdev->vlan :0 ,NULL ); } }
@@ -970,26 +980,16 @@ static int net_client_init1(const void *object, int is_netdev, Error **errp) } -static void net_visit (Visitor *v,int is_netdev,void **object,Error **errp) -{ -if (is_netdev) { -visit_type_Netdev (v, (Netdev **)object,NULL , errp); - }else { -visit_type_NetLegacy (v, (NetLegacy **)object,NULL , errp); - } -} - -int net_client_init (QemuOpts *opts,int is_netdev,Error **errp) { -void *object =NULL ; +Netdev *object =NULL ;Error *err =NULL ;int ret =-1 ; {OptsVisitor *ov =opts_visitor_new (opts); -net_visit (opts_get_visitor (ov), is_netdev, &object, &err); +visit_type_Netdev (opts_get_visitor (ov), &object,NULL , &err);opts_visitor_cleanup (ov); }
@@ -1000,7 +1000,7 @@ int net_client_init(QemuOpts *opts, int is_netdev, Error **errp)if (object) {QapiDeallocVisitor *dv =qapi_dealloc_visitor_new (); -net_visit (qapi_dealloc_get_visitor (dv), is_netdev, &object,NULL ); +visit_type_Netdev (qapi_dealloc_get_visitor (dv), &object,NULL ,NULL );qapi_dealloc_visitor_cleanup (dv); }
qapi-schema.json +9 -21
@@ -2499,21 +2499,25 @@ 'vhost-user': 'NetdevVhostUserOptions' } } ## -# @NetLegacy +# @Netdev # -# Captures the configuration of a network device; legacy. +# Captures the configuration of a network device. # -# @vlan: #optional vlan number +# @vlan: #optional vlan number (legacy, forbidden with -netdev) # -# @id: #optional identifier for monitor commands +# @id: #optional identifier for monitor commands (required with -netdev) # # @name: #optional identifier for monitor commands, ignored if @id is present +# (legacy, forbidden with -netdev) # # @opts: device type specific properties (legacy) # # Since 1.2 +# +# @id #optional - since 2.5 +# @vlan, @name - since 2.5 ## -{ 'struct': 'NetLegacy', +{ 'struct': 'Netdev', 'data': { '*vlan': 'int32', '*id': 'str',
@@ -2521,22 +2525,6 @@ 'opts': 'NetClientOptions' } } ## -# @Netdev -# -# Captures the configuration of a network device. -# -# @id: identifier for monitor commands. -# -# @opts: device type specific properties -# -# Since 1.2 -## -{ 'struct': 'Netdev', - 'data': { - 'id': 'str', - 'opts': 'NetClientOptions' } } - -## # @InetSocketAddress # # Captures a socket address or address range in the Internet namespace.
Signature · 1 line
2.5.0
Re: [Qemu-devel] [PATCH v2 04/49] net: remove NetLegacy struct
Quoted 17 lines · Zoltán
NetLegacy is just Netdev with some extra fields (name, vlan) and an optional id. This patch merges the two structs, and
net_client_init1got some extra checks to make sure only accept valid -netdev command lines. This is some extra work, but allows us to uniformly manage both legacy -net and non-legacy -netdev in code.Signed-off-by Kővágó, Zoltán <[email protected]>--- net/net.c | 42 +++++++++++++++++++++--------------------- qapi-schema.json | 30 +++++++++--------------------- 2 files changed, 30 insertions(+), 42 deletions(-)net/net.c +0
-0
net/net.c static int (* const net_client_init_fun[NET_CLIENT_OPTIONS_KIND_MAX])( · line 914
Quoted 5 lines
net/net.c +1
-1@@ -911,17 +911,29 @@ static int (* const net_client_init_fun[NET_CLIENT_OPTIONS_KIND_MAX])( }; -static int net_client_init1 (const void *object,int is_netdev,Error **errp) +static int net_client_init1 (const Netdev *netdev,int is_netdev,Error **errp)
I'm really hoping to fix QMP netdev_add to use a flat union type from the get-go rather than its current type-unsafe gunk. It may be safer from the point of view of this patch to wait for that to land first (among others, we'll want:
https://lists.gnu.org/archive/html/qemu-devel/2015-08/msg02093.html)
So I'm reluctant to review this right now, if it will just add churn into getting that part done correctly.
Don't throw this away just yet, because I'm not sure if QMP netdev_add needs to interact with command-line NetdevLegacy. But be aware that it is still an area under active debate/development.
Signature · 2 lines
Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org
PATCH v2 5/49 net: use Netdev instead of NetClientOptions in client init
In reply to Kővágó, ZoltánThis way we no longer need NetClientOptions and can convert Netdev into a flat union.
--- net/clients.h | 20 ++++++++++---------- net/dump.c | 6 +++--- net/hub.c | 6 +++--- net/l2tpv3.c | 6 +++--- net/net.c | 29 ++++++++++++++--------------- net/netmap.c | 4 ++-- net/slirp.c | 6 +++--- net/socket.c | 6 +++--- net/tap-win32.c | 6 +++--- net/tap.c | 12 ++++++------ net/vde.c | 6 +++--- net/vhost-user.c | 6 +++--- 12 files changed, 56 insertions(+), 57 deletions(-)
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 Netdev *netdev,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 Netdev *netdev,const char *name,NetClientState *peer,Error **errp);#endif -int net_init_hubport (const NetClientOptions *opts,const char *name, +int net_init_hubport (const Netdev *netdev,const char *name,NetClientState *peer,Error **errp); -int net_init_socket (const NetClientOptions *opts,const char *name, +int net_init_socket (const Netdev *netdev,const char *name,NetClientState *peer,Error **errp); -int net_init_tap (const NetClientOptions *opts,const char *name, +int net_init_tap (const Netdev *netdev,const char *name,NetClientState *peer,Error **errp); -int net_init_bridge (const NetClientOptions *opts,const char *name, +int net_init_bridge (const Netdev *netdev,const char *name,NetClientState *peer,Error **errp); -int net_init_l2tpv3 (const NetClientOptions *opts,const char *name, +int net_init_l2tpv3 (const Netdev *netdev,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 Netdev *netdev,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 Netdev *netdev,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 Netdev *netdev,const char *name,NetClientState *peer,Error **errp);#endif /* QEMU_NET_CLIENTS_H */
net/dump.c +3 -3
@@ -146,7 +146,7 @@ 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 Netdev *netdev,const char *name,NetClientState *peer,Error **errp) {int len;
@@ -154,8 +154,8 @@ int net_init_dump(const NetClientOptions *opts, const char *name,char def_file[128 ];const NetdevDumpOptions *dump; -assert (opts->kind ==NET_CLIENT_OPTIONS_KIND_DUMP ); - dump = opts->dump; +assert (netdev->opts->kind ==NET_CLIENT_OPTIONS_KIND_DUMP ); + dump = netdev->opts->dump;assert (peer);
net/hub.c +3 -3
@@ -280,14 +280,14 @@ 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 Netdev *netdev,const char *name,NetClientState *peer,Error **errp) {const NetdevHubPortOptions *hubport; -assert (opts->kind ==NET_CLIENT_OPTIONS_KIND_HUBPORT ); +assert (netdev->opts->kind ==NET_CLIENT_OPTIONS_KIND_HUBPORT );assert (!peer); - hubport = opts->hubport; + hubport = netdev->opts->hubport;net_hub_add_port (hubport->hubid, name);return 0 ;
net/l2tpv3.c +3 -3
@@ -524,7 +524,7 @@ static NetClientInfo net_l2tpv3_info = { .cleanup = net_l2tpv3_cleanup, }; -int net_init_l2tpv3 (const NetClientOptions *opts, +int net_init_l2tpv3 (const Netdev *netdev,const char *name,NetClientState *peer,Error **errp) {
@@ -545,8 +545,8 @@ 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; +assert (netdev->opts->kind ==NET_CLIENT_OPTIONS_KIND_L2TPV3 ); + l2tpv3 = netdev->opts->l2tpv3;if (l2tpv3->has_ipv6 && l2tpv3->ipv6) { s->ipv6 = l2tpv3->ipv6;
net/net.c +14 -15
@@ -813,15 +813,15 @@ int qemu_find_nic_model(NICInfo *nd, const char * const *models,return -1 ; } -static int net_init_nic (const NetClientOptions *opts,const char *name, +static int net_init_nic (const Netdev *netdev,const char *name,NetClientState *peer,Error **errp) {int idx;NICInfo *nd;const NetLegacyNicOptions *nic; -assert (opts->kind ==NET_CLIENT_OPTIONS_KIND_NIC ); - nic = opts->nic; +assert (netdev->opts->kind ==NET_CLIENT_OPTIONS_KIND_NIC ); + nic = netdev->opts->nic; idx =nic_get_free_idx ();if (idx ==-1 || nb_nics >=MAX_NICS ) {
@@ -882,7 +882,7 @@ static int net_init_nic(const NetClientOptions *opts, const char *name,static int (*const net_client_init_fun[NET_CLIENT_OPTIONS_KIND_MAX ])( -const NetClientOptions *opts, +const Netdev *netdev,const char *name,NetClientState *peer,Error **errp) = { [NET_CLIENT_OPTIONS_KIND_NIC ] = net_init_nic,
@@ -913,7 +913,6 @@ static int (* const net_client_init_fun[NET_CLIENT_OPTIONS_KIND_MAX])(static int net_client_init1 (const Netdev *netdev,int is_netdev,Error **errp) { -const NetClientOptions *opts = netdev->opts;const char *name;NetClientState *peer =NULL ;
@@ -934,9 +933,9 @@ static int net_client_init1(const Netdev *netdev, int is_netdev, Error **errp)return -1 ; } -if (opts->kind ==NET_CLIENT_OPTIONS_KIND_DUMP || - opts->kind ==NET_CLIENT_OPTIONS_KIND_NIC || - !net_client_init_fun[opts->kind]) { +if (netdev->opts->kind ==NET_CLIENT_OPTIONS_KIND_DUMP || + netdev->opts->kind ==NET_CLIENT_OPTIONS_KIND_NIC || + !net_client_init_fun[netdev->opts->kind]) {error_setg (errp,QERR_INVALID_PARAMETER_VALUE ,"type" ,"a netdev backend type" );return -1 ;
@@ -945,16 +944,16 @@ static int net_client_init1(const Netdev *netdev, int is_netdev, Error **errp)/* missing optional values have been initialized to "all bits zero" */ name = netdev->has_id ? netdev->id : netdev->name; -if (opts->kind ==NET_CLIENT_OPTIONS_KIND_NONE ) { +if (netdev->opts->kind ==NET_CLIENT_OPTIONS_KIND_NONE ) {return 0 ;/* nothing to do */ } -if (opts->kind ==NET_CLIENT_OPTIONS_KIND_HUBPORT ) { +if (netdev->opts->kind ==NET_CLIENT_OPTIONS_KIND_HUBPORT ) {error_setg (errp,QERR_INVALID_PARAMETER_VALUE ,"type" ,"a net type" );return -1 ; } -if (!net_client_init_fun[opts->kind]) { +if (!net_client_init_fun[netdev->opts->kind]) {error_setg (errp,QERR_INVALID_PARAMETER_VALUE ,"type" ,"a net backend type (maybe it is not compiled " "into this binary)" );
@@ -962,17 +961,17 @@ static int net_client_init1(const Netdev *netdev, int is_netdev, Error **errp) }/* Do not add to a vlan if it's a nic with a netdev= parameter. */ -if (opts->kind !=NET_CLIENT_OPTIONS_KIND_NIC || - !opts->nic->has_netdev) { +if (netdev->opts->kind !=NET_CLIENT_OPTIONS_KIND_NIC || + !netdev->opts->nic->has_netdev) { peer =net_hub_add_port (netdev->has_vlan ? netdev->vlan :0 ,NULL ); } } -if (net_client_init_fun[opts->kind](opts, name, peer, errp) <0 ) { +if (net_client_init_fun[netdev->opts->kind](netdev, name, peer, errp) <0 ) {/* FIXME drop when all init functions store an Error */ if (errp && !*errp) {error_setg (errp,QERR_DEVICE_INIT_FAILED , - NetClientOptionsKind_lookup[opts->kind]); + NetClientOptionsKind_lookup[netdev->opts->kind]); }return -1 ; }
net/netmap.c +2 -2
@@ -435,11 +435,11 @@ static NetClientInfo net_netmap_info = {* * ... -net netmap,ifname="..." */ -int net_init_netmap (const NetClientOptions *opts, +int net_init_netmap (const Netdev *netdev,const char *name,NetClientState *peer,Error **errp) {/* FIXME error_setg(errp, ...) on failure */ -const NetdevNetmapOptions *netmap_opts = opts->netmap; +const NetdevNetmapOptions *netmap_opts = netdev->opts->netmap;NetClientState *nc;NetmapPriv me;NetmapState *s;
net/slirp.c +3 -3
@@ -736,7 +736,7 @@ 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 Netdev *netdev,const char *name,NetClientState *peer,Error **errp) {/* FIXME error_setg(errp, ...) on failure */
@@ -746,8 +746,8 @@ int net_init_slirp(const NetClientOptions *opts, const char *name,const NetdevUserOptions *user;const char **dnssearch; -assert (opts->kind ==NET_CLIENT_OPTIONS_KIND_USER ); - user = opts->user; +assert (netdev->opts->kind ==NET_CLIENT_OPTIONS_KIND_USER ); + user = netdev->opts->user; vnet = user->has_net ?g_strdup (user->net) : user->has_ip ? g_strdup_printf("%s/24", user->ip) :
net/socket.c +3 -3
@@ -699,15 +699,15 @@ 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 Netdev *netdev,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; +assert (netdev->opts->kind ==NET_CLIENT_OPTIONS_KIND_SOCKET ); + sock = netdev->opts->socket;if (sock->has_fd + sock->has_listen + sock->has_connect + sock->has_mcast + sock->has_udp !=1 ) {
net/tap-win32.c +3 -3
@@ -761,14 +761,14 @@ 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 Netdev *netdev,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; +assert (netdev->opts->kind ==NET_CLIENT_OPTIONS_KIND_TAP ); + tap = netdev->opts->tap;if (!tap->has_ifname) {error_report ("tap: no interface name" );
net/tap.c +6 -6
@@ -557,7 +557,7 @@ 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 Netdev *netdev,const char *name,NetClientState *peer,Error **errp) {const NetdevBridgeOptions *bridge;
@@ -565,8 +565,8 @@ int net_init_bridge(const NetClientOptions *opts, const char *name,TAPState *s;int fd, vnet_hdr; -assert (opts->kind ==NET_CLIENT_OPTIONS_KIND_BRIDGE ); - bridge = opts->bridge; +assert (netdev->opts->kind ==NET_CLIENT_OPTIONS_KIND_BRIDGE ); + bridge = netdev->opts->bridge; helper = bridge->has_helper ? bridge->helper :DEFAULT_BRIDGE_HELPER ; br = bridge->has_br ? bridge->br :DEFAULT_BRIDGE_INTERFACE ;
@@ -716,7 +716,7 @@ 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 Netdev *netdev,const char *name,NetClientState *peer,Error **errp) {const NetdevTapOptions *tap;
@@ -728,8 +728,8 @@ 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; +assert (netdev->opts->kind ==NET_CLIENT_OPTIONS_KIND_TAP ); + tap = netdev->opts->tap; queues = tap->has_queues ? tap->queues :1 ; vhostfdname = tap->has_vhostfd ? tap->vhostfd :NULL ;
net/vde.c +3 -3
@@ -109,14 +109,14 @@ 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 Netdev *netdev,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; +assert (netdev->opts->kind ==NET_CLIENT_OPTIONS_KIND_VDE ); + vde = netdev->opts->vde;/* 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 +3 -3
@@ -223,14 +223,14 @@ 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 Netdev *netdev,const char *name,NetClientState *peer,Error **errp) {const NetdevVhostUserOptions *vhost_user_opts;CharDriverState *chr; -assert (opts->kind ==NET_CLIENT_OPTIONS_KIND_VHOST_USER ); - vhost_user_opts = opts->vhost_user; +assert (netdev->opts->kind ==NET_CLIENT_OPTIONS_KIND_VHOST_USER ); + vhost_user_opts = netdev->opts->vhost_user; chr =net_vhost_parse_chardev (vhost_user_opts, errp);if (!chr) {
Signature · 1 line
2.5.0
Re: [Qemu-devel] [PATCH v2 05/49] net: use Netdev instead of NetClientOptions in client init
Quoted 4 lines · Zoltán
This way we no longer need NetClientOptions and can convert Netdev into a flat union.
Signed-off-by Kővágó, Zoltán <[email protected]>
Quoted 14 lines
--- net/clients.h | 20 ++++++++++---------- net/dump.c | 6 +++--- net/hub.c | 6 +++--- net/l2tpv3.c | 6 +++--- net/net.c | 29 ++++++++++++++--------------- net/netmap.c | 4 ++-- net/slirp.c | 6 +++--- net/socket.c | 6 +++--- net/tap-win32.c | 6 +++--- net/tap.c | 12 ++++++------ net/vde.c | 6 +++--- net/vhost-user.c | 6 +++--- 12 files changed, 56 insertions(+), 57 deletions(-)
Nice; you've already done some of the work that I saw as needing to be done for my plans to convert QMP netdev_add to use a flat union instead of 'gen':false.
Conflicts with my s/kind/type/ in
https://lists.gnu.org/archive/html/qemu-devel/2015-08/msg02061.html, so whoever goes in first gets to avoid the obvious merge conflict resolution. :)
Signature · 2 lines
Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org
Re: [Qemu-devel] [PATCH v2 05/49] net: use Netdev instead of NetClientOptions in client init
Quoted 24 lines · Eric Blake
Quoted 4 lines · Zoltán
This way we no longer need NetClientOptions and can convert Netdev into a flat union.
Signed-off-by Kővágó, Zoltán <[email protected]>Quoted 14 lines
--- net/clients.h | 20 ++++++++++---------- net/dump.c | 6 +++--- net/hub.c | 6 +++--- net/l2tpv3.c | 6 +++--- net/net.c | 29 ++++++++++++++--------------- net/netmap.c | 4 ++-- net/slirp.c | 6 +++--- net/socket.c | 6 +++--- net/tap-win32.c | 6 +++--- net/tap.c | 12 ++++++------ net/vde.c | 6 +++--- net/vhost-user.c | 6 +++--- 12 files changed, 56 insertions(+), 57 deletions(-)Nice; you've already done some of the work that I saw as needing to be done for my plans to convert QMP
netdev_addto use a flat union instead of 'gen':false.
Quoted 6 lines
Conflicts with my s/kind/type/ in
https://lists.gnu.org/archive/html/qemu-devel/2015-08/msg02061.html, so whoever goes in first gets to avoid the obvious merge conflict resolution. :)Reviewed-by Eric Blake <[email protected]>
By the way, I was able to get this patch to work without using 4/49 by changing the diff to net_client_init1() to be just the following:
net/net.c +0 -0
@@ -914,11 +914,13 @@ static int (* const
net_client_init_fun[NET_CLIENT_OPTIONS_KIND_MAX])(
static int net_client_init1(const void *object, int is_netdev, Error
**errp)
{
const NetClientOptions *opts;
+ Netdev legacy = {0};
+ const Netdev *netdev;
const char *name;
NetClientState *peer = NULL;
if (is_netdev) {
- const Netdev *netdev = object;
+ netdev = object;
opts = netdev->opts;
name = netdev->id;@@ -931,7 +933,9 @@ static int net_client_init1(const void *object, int is_netdev, Error **errp)
}
} else {
const NetLegacy *net = object;
- opts = net->opts;
+ legacy.id = net->id;
+ opts = legacy.opts = net->opts;
+ netdev = &legacy;
/* missing optional values have been initialized to "all bits
zero" */
name = net->has_id ? net->id : net->name;@@ -958,7 +962,7 @@ static int net_client_init1(const void *object, int is_netdev, Error **errp)
}
}- if (net_client_init_fun[opts->kind](opts, name, peer, errp) < 0) {
+ if (net_client_init_fun[opts->kind](netdev, name, peer, errp) < 0) {
/* FIXME drop when all init functions store an Error */
if (errp && !*errp) {
error_setg(errp, QERR_DEVICE_INIT_FAILED,I may end up using a modified version of your patch in my submission for QMP netdev_add, while still avoiding the merge of NetdevLegacy (I'm not sold on that one yet, because it exists only for the command line and not for QMP, while we want to make QMP become typesafe).
Signature · 2 lines
Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org
PATCH v2 6/49 qapi: change Netdev into a flat union
In reply to Kővágó, ZoltánExcept qapi-schema.json, this patch was generated by:
find . -name .git -prune -o -type f \! -name '*~' -print0 | \
xargs -0 sed -i \
-e 's/NetClientOptionsKind/NetClientDriver/g' \
-e 's/NET_CLIENT_OPTIONS_KIND_/NET_CLIENT_DRIVER_/g' \
-e 's/netdev->opts/netdev/g'--- 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/dump.c | 6 +-- net/hub.c | 22 +++++------ net/l2tpv3.c | 6 +-- net/net.c | 84 ++++++++++++++++++++-------------------- net/netmap.c | 4 +- net/slirp.c | 6 +-- net/socket.c | 8 ++-- net/tap-win32.c | 6 +-- net/tap.c | 24 ++++++------ net/vde.c | 6 +-- net/vhost-user.c | 12 +++--- qapi-schema.json | 36 +++++++++++------ 45 files changed, 166 insertions(+), 154 deletions(-)
hw/arm/musicpal.c +1 -1
@@ -374,7 +374,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), .receive = eth_receive, .cleanup = eth_cleanup,
hw/core/qdev-properties-system.c +1 -1
@@ -229,7 +229,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
@@ -810,7 +810,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
@@ -1515,7 +1515,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
@@ -1832,7 +1832,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), .receive = nic_receive, };
hw/net/etraxfs_eth.c +1 -1
@@ -577,7 +577,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), .receive = eth_receive, .link_status_changed = eth_set_link,
hw/net/fsl_etsec/etsec.c +1 -1
@@ -369,7 +369,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), .receive = etsec_receive, .link_status_changed = etsec_set_link_status,
hw/net/lan9118.c +1 -1
@@ -1305,7 +1305,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), .receive = lan9118_receive, .link_status_changed = lan9118_set_link,
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), .receive = pcnet_receive, .link_status_changed = pcnet_set_link_status,
hw/net/mcf_fec.c +1 -1
@@ -506,7 +506,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), .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), .receive = minimac2_rx, };
hw/net/mipsnet.c +1 -1
@@ -218,7 +218,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), .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), .receive = pcnet_receive, .link_status_changed = pcnet_set_link_status,
hw/net/rocker/rocker_fp.c +1 -1
@@ -166,7 +166,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), .receive = fp_port_receive, .receive_iov = fp_port_receive_iov,
hw/net/rtl8139.c +1 -1
@@ -3462,7 +3462,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
@@ -449,7 +449,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), .receive = stellaris_enet_receive, };
hw/net/vhost_net.c +9 -9
@@ -95,10 +95,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 :
@@ -125,7 +125,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" );
@@ -236,7 +236,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) {
@@ -252,7 +252,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,
@@ -275,14 +275,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,
@@ -399,10 +399,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
@@ -406,7 +406,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 ; }
@@ -421,7 +421,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 ; }
@@ -1595,7 +1595,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
@@ -1986,7 +1986,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
@@ -280,7 +280,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), .receive = net_rx_packet, };
hw/net/xgmac.c +1 -1
@@ -370,7 +370,7 @@ out: }static NetClientInfo net_xgmac_enet_info = { - .type =NET_CLIENT_OPTIONS_KIND_NIC , + .type =NET_CLIENT_DRIVER_NIC , .size =sizeof (NICState), .receive = eth_rx, };
hw/net/xilinx_axienet.c +1 -1
@@ -933,7 +933,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), .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
@@ -1330,7 +1330,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), .receive = usbnet_receive, .cleanup = usbnet_cleanup,
include/net/net.h +2 -2
@@ -59,7 +59,7 @@ typedef int (SetVnetLE)(NetClientState *, bool);typedef int (SetVnetBE )(NetClientState *,bool ); typedef struct NetClientInfo { - NetClientOptionsKind type; + NetClientDriver type; size_t size; NetReceive *receive; NetReceive *receive_raw;
@@ -104,7 +104,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
@@ -4188,8 +4188,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]); } }
@@ -4389,7 +4389,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;
@@ -4414,7 +4414,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;
@@ -4506,7 +4506,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;
@@ -4523,13 +4523,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/dump.c +3 -3
@@ -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,
@@ -154,8 +154,8 @@ int net_init_dump(const Netdev *netdev, const char *name,char def_file[128 ];const NetdevDumpOptions *dump; -assert (netdev->opts->kind ==NET_CLIENT_OPTIONS_KIND_DUMP ); - dump = netdev->opts->dump; +assert (netdev->kind ==NET_CLIENT_DRIVER_DUMP ); + dump = netdev->dump;assert (peer);
net/hub.c +11 -11
@@ -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 ;
@@ -285,9 +285,9 @@ int net_init_hubport(const Netdev *netdev, const char *name, {const NetdevHubPortOptions *hubport; -assert (netdev->opts->kind ==NET_CLIENT_OPTIONS_KIND_HUBPORT ); +assert (netdev->kind ==NET_CLIENT_DRIVER_HUBPORT );assert (!peer); - hubport = netdev->opts->hubport; + hubport = netdev->hubport;net_hub_add_port (hubport->hubid, name);return 0 ;
@@ -314,14 +314,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 -3
@@ -516,7 +516,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,
@@ -545,8 +545,8 @@ int net_init_l2tpv3(const Netdev *netdev, s->queue_tail =0 ; s->header_mismatch = false; -assert (netdev->opts->kind ==NET_CLIENT_OPTIONS_KIND_L2TPV3 ); - l2tpv3 = netdev->opts->l2tpv3; +assert (netdev->kind ==NET_CLIENT_DRIVER_L2TPV3 ); + l2tpv3 = netdev->l2tpv3;if (l2tpv3->has_ipv6 && l2tpv3->ipv6) { s->ipv6 = l2tpv3->ipv6;
net/net.c +42 -42
243 lines not on this page · raw message
net/netmap.c +2 -2
@@ -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,
@@ -439,7 +439,7 @@ int net_init_netmap(const Netdev *netdev, const char *name, NetClientState *peer, Error **errp) { /* FIXME error_setg(errp, ...) on failure */ - const NetdevNetmapOptions *netmap_opts = netdev->opts->netmap; + const NetdevNetmapOptions *netmap_opts = netdev->netmap;NetClientState *nc;NetmapPriv me;NetmapState *s;
net/slirp.c +3 -3
@@ -126,7 +126,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,
@@ -746,8 +746,8 @@ int net_init_slirp(const Netdev *netdev, const char *name,const NetdevUserOptions *user;const char **dnssearch; -assert (netdev->opts->kind ==NET_CLIENT_OPTIONS_KIND_USER ); - user = netdev->opts->user; +assert (netdev->kind ==NET_CLIENT_DRIVER_USER ); + user = netdev->user; vnet = user->has_net ?g_strdup (user->net) : user->has_ip ? g_strdup_printf("%s/24", user->ip) :
net/socket.c +4 -4
@@ -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,
@@ -706,8 +706,8 @@ int net_init_socket(const Netdev *netdev, const char *name,Error *err =NULL ;const NetdevSocketOptions *sock; -assert (netdev->opts->kind ==NET_CLIENT_OPTIONS_KIND_SOCKET ); - sock = netdev->opts->socket; +assert (netdev->kind ==NET_CLIENT_DRIVER_SOCKET ); + sock = netdev->socket;if (sock->has_fd + sock->has_listen + sock->has_connect + sock->has_mcast + sock->has_udp !=1 ) {
net/tap-win32.c +3 -3
@@ -723,7 +723,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,
@@ -767,8 +767,8 @@ int net_init_tap(const Netdev *netdev, const char *name,/* FIXME error_setg(errp, ...) on failure */ const NetdevTapOptions *tap; -assert (netdev->opts->kind ==NET_CLIENT_OPTIONS_KIND_TAP ); - tap = netdev->opts->tap; +assert (netdev->kind ==NET_CLIENT_DRIVER_TAP ); + tap = netdev->tap;if (!tap->has_ifname) {error_report ("tap: no interface name" );
net/tap.c +12 -12
@@ -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;
@@ -326,14 +326,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,
@@ -565,8 +565,8 @@ int net_init_bridge(const Netdev *netdev, const char *name,TAPState *s;int fd, vnet_hdr; -assert (netdev->opts->kind ==NET_CLIENT_OPTIONS_KIND_BRIDGE ); - bridge = netdev->opts->bridge; +assert (netdev->kind ==NET_CLIENT_DRIVER_BRIDGE ); + bridge = netdev->bridge; helper = bridge->has_helper ? bridge->helper :DEFAULT_BRIDGE_HELPER ; br = bridge->has_br ? bridge->br :DEFAULT_BRIDGE_INTERFACE ;
@@ -728,8 +728,8 @@ int net_init_tap(const Netdev *netdev, const char *name,const char *vhostfdname;char ifname[128 ]; -assert (netdev->opts->kind ==NET_CLIENT_OPTIONS_KIND_TAP ); - tap = netdev->opts->tap; +assert (netdev->kind ==NET_CLIENT_DRIVER_TAP ); + tap = netdev->tap; queues = tap->has_queues ? tap->queues :1 ; vhostfdname = tap->has_vhostfd ? tap->vhostfd :NULL ;
@@ -890,7 +890,7 @@ int net_init_tap(const Netdev *netdev, 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 -3
@@ -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,
@@ -115,8 +115,8 @@ int net_init_vde(const Netdev *netdev, const char *name,/* FIXME error_setg(errp, ...) on failure */ const NetdevVdeOptions *vde; -assert (netdev->opts->kind ==NET_CLIENT_OPTIONS_KIND_VDE ); - vde = netdev->opts->vde; +assert (netdev->kind ==NET_CLIENT_DRIVER_VDE ); + vde = netdev->vde;/* 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 -6
@@ -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; }
@@ -75,20 +75,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,
@@ -229,8 +229,8 @@ int net_init_vhost_user(const Netdev *netdev, const char *name,const NetdevVhostUserOptions *vhost_user_opts;CharDriverState *chr; -assert (netdev->opts->kind ==NET_CLIENT_OPTIONS_KIND_VHOST_USER ); - vhost_user_opts = netdev->opts->vhost_user; +assert (netdev->kind ==NET_CLIENT_DRIVER_VHOST_USER ); + vhost_user_opts = netdev->vhost_user; chr =net_vhost_parse_chardev (vhost_user_opts, errp);if (!chr) {
qapi-schema.json +24 -12
@@ -2474,16 +2474,31 @@ '*vhostforce': 'bool' } } ## -# @NetClientOptions +# @NetClientDriver # -# A discriminated record of network device traits. +# Available netdev drivers. +# +# Since 2.5 +## +{ 'enum': 'NetClientDriver', + 'data': [ 'none', 'nic', 'user', 'tap', 'l2tpv3', 'socket', 'vde', 'dump', + 'bridge', 'hubport', 'netmap', 'vhost-user' ] } + +## +# @Netdev +# +# Captures the configuration of a network device. # # Since 1.2 # # 'l2tpv3' - since 2.1 +# @id #optional - since 2.5 +# @vlan, @name - since 2.5 # ## -{ 'union': 'NetClientOptions', +{ 'union': 'Netdev', + 'base': 'NetdevBase', + 'discriminator': 'type', 'data': { 'none': 'NetdevNoneOptions', 'nic': 'NetLegacyNicOptions',
@@ -2499,9 +2514,9 @@ 'vhost-user': 'NetdevVhostUserOptions' } } ## -# @Netdev +# @NetdevBase # -# Captures the configuration of a network device. +# Captures the common configuration of a network device. # # @vlan: #optional vlan number (legacy, forbidden with -netdev) #
@@ -2510,19 +2525,16 @@ # @name: #optional identifier for monitor commands, ignored if @id is present # (legacy, forbidden with -netdev) # -# @opts: device type specific properties (legacy) +# @type: the netdev driver to use # -# Since 1.2 -# -# @id #optional - since 2.5 -# @vlan, @name - since 2.5 +# Since 2.5 ## -{ 'struct': 'Netdev', +{ 'struct': 'NetdevBase', 'data': { '*vlan': 'int32', '*id': 'str', '*name': 'str', - 'opts': 'NetClientOptions' } } + 'type': 'NetClientDriver' } } ## # @InetSocketAddress
Signature · 1 line
2.5.0
Re: [Qemu-devel] [PATCH v2 06/49] qapi: change Netdev into a flat union
Quoted 6 lines · Zoltán
Except qapi-schema.json, this patch was generated by:
find . -name .git -prune -o -type f \! -name '*~' -print0 | \
xargs -0 sed -i \ -e 's/NetClientOptionsKind/NetClientDriver/g' \ -e 's/NET_CLIENT_OPTIONS_KIND_/NET_CLIENT_DRIVER_/g' \
Same question as in 3 about whether 'driver' is the right name for the new enum.
Quoted 7 lines
-e 's/netdev->opts/netdev/g'Signed-off-by Kővágó, Zoltán <[email protected]>---
qapi-schema.json | 36 +++++++++++------ 45 files changed, 166 insertions(+), 154 deletions(-)
So the bulk is mechanical 1:1 replacement, and the qapi change adds a net of 12 lines.
hw/arm/musicpal.c static void eth_cleanup(NetClientState *nc) · line 377
Quoted 11 lines
hw/arm/musicpal.c +1
-1@@ -374,7 +374,7 @@ static void eth_cleanup(NetClientState *nc) }static NetClientInfo net_mv88w8618_info = { - .type =NET_CLIENT_OPTIONS_KIND_NIC , + .type =NET_CLIENT_DRIVER_NIC ,
You know, if we could teach qapi to allow a user-named type with 'Kind' as the suffix, we wouldn't have quite as much churn :)
Quoted 6 lines
hw/arm/musicpal.c +1
-1+++ b/qapi-schema.json@@ -2474,16 +2474,31 @@ '*vhostforce': 'bool' } } ## -# @NetClientOptions
hw/arm/musicpal.c line 2485
Quoted 10 lines
hw/arm/musicpal.c +8
-1+# @NetClientDriver # -# A discriminated record of network device traits. +# Available netdev drivers. +# +# Since 2.5 +## +{ 'enum': 'NetClientDriver', + 'data': [ 'none', 'nic', 'user', 'tap', 'l2tpv3', 'socket', 'vde', 'dump', + 'bridge', 'hubport', 'netmap', 'vhost-user' ] }
Hmm; maybe 'Driver' really is the right name for this enum.
hw/arm/musicpal.c line 2496
Quoted 11 lines
hw/arm/musicpal.c +7
-0+ +## +# @Netdev +# +# Captures the configuration of a network device. ## Since 1.2 # # 'l2tpv3' - since 2.1 +# @id #optional - since 2.5 +# @vlan, @name - since 2.5
I'd document id and vlan prior to the initial 'Since 1.2', then leave the only thing after that line to be just the list of when later drivers were added to the union. Actually, depending on what I decide about 4/49, we may not even be adding vlan and name, and id might not be optional, since that was just NetdevLegacy. And if we do merge NetdevLegacy, then it's better to have separate lines for @vlan and @name, as well as the documentation of when they can be set.
hw/arm/musicpal.c line 2514
Quoted 11 lines
hw/arm/musicpal.c +3
-1# ## -{ 'union': 'NetClientOptions', +{ 'union': 'Netdev', + 'base': 'NetdevBase', + 'discriminator': 'type', 'data': { 'none': 'NetdevNoneOptions', 'nic': 'NetLegacyNicOptions',@@ -2499,9 +2514,9 @@ 'vhost-user': 'NetdevVhostUserOptions' } }
QMP wise (if we were to use Netdev in QMP), this is changing:
{ "command":"foo", "arguments": {
"id":"abc", "opts" { "type":"dump", "data": {
"len":1024, "file":"/path/to/foo" } } } }into
{ "command":"foo", "arguments": {
"id":"abc", "type":"dump",
"len":1024, "file":"/path/to/foo" } }Wow - removing two levels of nesting in one patch. Even cooler, this LOOKS a lot like what QMP 'netdev_add' already parses :)
The corresponding C code loses one layer of boxing (because, as I already pointed out on 3, converting from simple to flat union without creating data wrappers loses one layer of nesting in QMP with no change to the nesting in the matching generated C structure).
So, if we can _avoid_ merging in NetdevLegacy stuff here (but that has knock-on effects, because my hack to use 5/49 without 4/49 doesn't quite work with the sed statement you used here), then you have just created the solution for netdev_add. I'll use your patch as a starting point, coupled with my pending work to allow a boxed flat union as the direct argument to a QMP command.
Quoted 21 lines
hw/arm/musicpal.c +3
-7## -# @Netdev +# @NetdevBase # -# Captures the configuration of a network device. +# Captures the common configuration of a network device. # # @vlan: #optional vlan number (legacy, forbidden with -netdev) #@@ -2510,19 +2525,16 @@ # @name: #optional identifier for monitor commands, ignored if @id is present # (legacy, forbidden with -netdev) # -# @opts: device type specific properties (legacy) +# @type: the netdev driver to use # -# Since 1.2 -# -# @id #optional - since 2.5 -# @vlan, @name - since 2.5
hw/arm/musicpal.c line 2537
Quoted 10 lines
hw/arm/musicpal.c +3
-2+# Since 2.5 ## -{ 'struct': 'Netdev', +{ 'struct': 'NetdevBase', 'data': { '*vlan': 'int32', '*id': 'str', '*name': 'str', - 'opts': 'NetClientOptions' } } + 'type': 'NetClientDriver' } }
This is where I'm not completely sold that the merge from NetdevLegacy makes sense. Like I said, I'm playing with it some on my tree.
Signature · 2 lines
Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org
PATCH v2 7/49 qapi: reorder NetdevBase and Netdev
In reply to Kővágó, ZoltánProbably more logical if NetdevBase comes before Netdev. No schematic changes.
--- qapi-schema.json | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-)
qapi-schema.json +23 -23
@@ -2485,6 +2485,29 @@ 'bridge', 'hubport', 'netmap', 'vhost-user' ] } ## +# @NetdevBase +# +# Captures the commopn configuration of a network device. +# +# @vlan: #optional vlan number (legacy, forbidden with -netdev) +# +# @id: #optional identifier for monitor commands (required with -netdev) +# +# @name: #optional identifier for monitor commands, ignored if @id is present +# (legacy, forbidden with -netdev) +# +# @type: the netdev driver to use +# +# Since 2.5 +## +{ 'struct': 'NetdevBase', + 'data': { + '*vlan': 'int32', + '*id': 'str', + '*name': 'str', + 'type': 'NetClientDriver' } } + +## # @Netdev # # Captures the configuration of a network device.
@@ -2514,29 +2537,6 @@ 'vhost-user': 'NetdevVhostUserOptions' } } ## -# @NetdevBase -# -# Captures the common configuration of a network device. -# -# @vlan: #optional vlan number (legacy, forbidden with -netdev) -# -# @id: #optional identifier for monitor commands (required with -netdev) -# -# @name: #optional identifier for monitor commands, ignored if @id is present -# (legacy, forbidden with -netdev) -# -# @type: the netdev driver to use -# -# Since 2.5 -## -{ 'struct': 'NetdevBase', - 'data': { - '*vlan': 'int32', - '*id': 'str', - '*name': 'str', - 'type': 'NetClientDriver' } } - -## # @InetSocketAddress # # Captures a socket address or address range in the Internet namespace.
Signature · 1 line
2.5.0
Re: [Qemu-devel] [PATCH v2 07/49] qapi: reorder NetdevBase and Netdev
Quoted 7 lines · Zoltán
Probably more logical if NetdevBase comes before Netdev. No schematic changes.
Signed-off-by Kővágó, Zoltán <[email protected]>--- qapi-schema.json | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-)
Just code motion; doesn't affect generated output or semantics.
But does depend on my earlier comments about whether the merge with NetdevLegacy was right. So it may hit merge conflicts, depending on where I go with that; in which case dropping the patch altogether may be easiest.
Signature · 2 lines
Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org
PATCH v2 8/49 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 backend specific option (as all other backends currently ignore it)
--- Makefile | 4 +- qapi-schema.json | 3 + qapi/audio.json | 263 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 268 insertions(+), 2 deletions(-) create mode 100644 qapi/audio.json
Makefile +2 -2
@@ -262,8 +262,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 +263 -0
263 lines not on this page · raw message
Signature · 1 line
2.5.0
PATCH v2 9/49 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 qapi flattening commits hopefully ensures that this change doesn't create backward compatibility problems.
--- qapi/opts-visitor.c | 116 ++++++++++++++++++++++++++------ tests/qapi-schema/qapi-schema-test.json | 9 ++- tests/qapi-schema/qapi-schema-test.out | 6 +- tests/test-opts-visitor.c | 34 ++++++++++ 4 files changed, 141 insertions(+), 24 deletions(-)
qapi/opts-visitor.c +95 -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,55 @@ 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 = key; + key =NULL ; + } - list =g_hash_table_lookup (ov->unprocessed_opts, name);if (!list) {error_setg (errp,QERR_MISSING_PARAMETER , name); } + +g_free (key);return list; }
@@ -218,7 +268,8 @@ 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); +assert (ov->repeated_opts ==NULL && ov->repeated_name ==NULL ); + ov->repeated_opts =lookup_distinct (ov, name, &ov->repeated_name, errp);if (ov->repeated_opts !=NULL ) { ov->list_mode =LM_STARTED ; }
@@ -254,11 +305,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 +333,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 +376,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 +394,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 +413,15 @@ opts_type_bool(Visitor *v, bool *obj, const char *name, Error **errp) }else {error_setg (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 +433,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 +454,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 +481,7 @@ opts_type_int(Visitor *v, int64_t *obj, const char *name, Error **errp)error_setg (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 +493,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 +512,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 +537,7 @@ opts_type_uint64(Visitor *v, uint64_t *obj, const char *name, Error **errp)error_setg (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 +548,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 +560,13 @@ opts_type_size(Visitor *v, uint64_t *obj, const char *name, Error **errp)if (val <0 || *endptr) {error_setg (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 +577,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 +588,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 +633,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/qapi-schema/qapi-schema-test.out +4 -2
@@ -17,7 +17,8 @@ OrderedDict([('command', 'user_def_cmd1'), ('data', OrderedDict([('ud1a', 'UserDefOne')]))]), OrderedDict([('command', 'user_def_cmd2'), ('data', OrderedDict([('ud1a', 'UserDefOne'), ('*ud1b', 'UserDefOne')])), ('returns', 'UserDefTwo')]), OrderedDict([('command', 'user_def_cmd3'), ('data', OrderedDict([('a', 'int'), ('*b', 'int')])), ('returns', 'int')]), - OrderedDict([('struct', 'UserDefOptions'), ('data', OrderedDict([('*i64', ['int']), ('*u64', ['uint64']), ('*u16', ['uint16']), ('*i64x', 'int'), ('*u64x', 'uint64')]))]), + OrderedDict([('struct', 'UserDefOptionsSub'), ('data', OrderedDict([('*nint', 'int')]))]), + OrderedDict([('struct', 'UserDefOptions'), ('data', OrderedDict([('*i64', ['int']), ('*u64', ['uint64']), ('*u16', ['uint16']), ('*i64x', 'int'), ('*u64x', 'uint64'), ('sub0', 'UserDefOptionsSub'), ('sub1', 'UserDefOptionsSub')]))]), OrderedDict([('struct', 'EventStructOne'), ('data', OrderedDict([('struct1', 'UserDefOne'), ('string', 'str'), ('*enum2', 'EnumOne')]))]), OrderedDict([('event', 'EVENT_A')]), OrderedDict([('event', 'EVENT_B'), ('data', OrderedDict())]),
@@ -48,7 +49,8 @@ OrderedDict([('struct', 'UserDefB'), ('data', OrderedDict([('integer', 'int')]))]), OrderedDict([('struct', 'UserDefC'), ('data', OrderedDict([('string1', 'str'), ('string2', 'str')]))]), OrderedDict([('struct', 'UserDefUnionBase'), ('data', OrderedDict([('string', 'str'), ('enum1', 'EnumOne')]))]), - OrderedDict([('struct', 'UserDefOptions'), ('data', OrderedDict([('*i64', ['int']), ('*u64', ['uint64']), ('*u16', ['uint16']), ('*i64x', 'int'), ('*u64x', 'uint64')]))]), + OrderedDict([('struct', 'UserDefOptionsSub'), ('data', OrderedDict([('*nint', 'int')]))]), + OrderedDict([('struct', 'UserDefOptions'), ('data', OrderedDict([('*i64', ['int']), ('*u64', ['uint64']), ('*u16', ['uint16']), ('*i64x', 'int'), ('*u64x', 'uint64'), ('sub0', 'UserDefOptionsSub'), ('sub1', 'UserDefOptionsSub')]))]), OrderedDict([('struct', 'EventStructOne'), ('data', OrderedDict([('struct1', 'UserDefOne'), ('string', 'str'), ('*enum2', 'EnumOne')]))]), OrderedDict([('struct', '__org.qemu_x-Base'), ('data', OrderedDict([('__org.qemu_x-member1', '__org.qemu_x-Enum')]))]), OrderedDict([('struct', '__org.qemu_x-Struct'), ('base', '__org.qemu_x-Base'), ('data', OrderedDict([('__org.qemu_x-member2', 'str')]))]),
tests/test-opts-visitor.c +34 -0
@@ -178,6 +178,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
@@ -271,6 +299,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.5.0
Re: [Qemu-devel] [PATCH v2 09/49] qapi: support nested structs in OptsVisitor
Quoted 9 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'.
s/orout/or out/
Quoted 2 lines
You must provide a full path even in non-ambigous cases. The qapi
s/ambigous/ambiguous/
Quoted 2 lines
flattening commits hopefully ensures that this change doesn't create backward compatibility problems.
Give me some more time to think about 8 and 9 (it's nearly the start of a 3-day weekend for me). I know I said I'd look at these patches before Monday, but for now you'll have to live with my review on just 1-7. Oh well. I know what I'm starting on next week when I return :)
And we still have plenty of time before qemu 2.5 to get things right.
Signature · 2 lines
Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org
PATCH v2 10/49 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.
--- 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
@@ -128,7 +128,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);
@@ -256,7 +256,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
@@ -136,7 +136,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
@@ -2363,12 +2363,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);
@@ -3069,7 +3069,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.5.0
PATCH v2 11/49 audio: -audiodev command line option: documentation
In reply to Kővágó, ZoltánThis patch adds documentation of an -audiodev command line option, that deprecates the old QEMU_* environment variables for audio backend configuration. It's syntax is similar to existing options (-netdev, -device, etc):
-audiodev driver_name,property=value,...
Although now it's possible to specify multiple -audiodev options on command line, multiple audio backends are not supported yet.
--- qemu-options.hx | 222 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 219 insertions(+), 3 deletions(-)
qemu-options.hx +219 -3
@@ -313,14 +313,230 @@ The default is @code{en-us}. ETEXI +HXCOMM Deprecated by -audiodev DEF("audio-help", 0, QEMU_OPTION_audio_help, - "-audio-help print list of audio drivers and their options\n", + "-audio-help show -audiodev equivalent of the currently specified audio settings\n", QEMU_ARCH_ALL) STEXI @item -audio-help @findex -audio-help -Will show the audio subsystem help: list of drivers, tunable -parameters. +Will show the -audiodev equivalent of the currently specified +(deprecated) environment variables. +ETEXI + +DEF("audiodev", HAS_ARG, QEMU_OPTION_audiodev, + "-audiodev [driver=]driver,id=id[,prop[=value][,...]]\n" + " specifies the audio backend to use\n" + " id= identifier of the backend\n" + " timer-period= timer period in microseconds\n" + " in|out.fixed-settings= use fixed settings for host audio\n" + " in|out.frequency= frequency to use with fixed settings\n" + " in|out.channels= number of channels to use with fixed settings\n" + " in|out.format= sample format to use with fixed settings\n" + " valid values: s8, s16, s32, u8, u16, u32\n" + " in|out.voices= number of voices to use\n" + " in|out.buffer-len= size of buffer in microseconds\n" + " in|out.buffer-count= number of buffers\n" + "-audiodev none,id=id,[,prop[=value][,...]]\n" + " dummy driver that discards all output\n" +#ifdef CONFIG_ALSA + "-audiodev alsa,id=id[,prop[=value][,...]]\n" + " alsa-in|alsa-out.dev= name of the audio device to use\n" + " alsa-in|alsa-out.try-poll= attempt to use poll mode\n" + " threshold= threshold (in microseconds) when playback starts\n" +#endif +#ifdef CONFIG_COREAUDIO + "-audiodev coreaudio,id=id[,prop[=value][,...]]\n" +#endif +#ifdef CONFIG_DSOUND + "-audiodev dsound,id=id[,prop[=value][,...]]\n" + " latency= add extra latency to playback in microseconds\n" +#endif +#ifdef CONFIG_OSS + "-audiodev oss,id=id[,prop[=value][,...]]\n" + " oss-in|oss-out.dev= path of the audio device to use\n" + " oss-in|oss-out.try-poll= attempt to use poll mode\n" + " try-mmap= try using memory mapped access\n" + " exclusive= open device in exclusive mode\n" + " dsp-policy= set timing policy (0..10), -1 to use fragment mode\n" +#endif +#ifdef CONFIG_PA + "-audiodev pa,id=id[,prop[=value][,...]]\n" + " server= PulseAudio server address\n" + " sink|source.name= sink/source device name\n" +#endif +#ifdef CONFIG_SDL + "-audiodev sdl,id=id[,prop[=value][,...]]\n" +#endif +#ifdef CONFIG_SPICE + "-audiodev spice,id=id[,prop[=value][,...]]\n" +#endif + "-audiodev wav,id=id[,prop[=value][,...]]\n" + " path= path of wav file to record\n", + QEMU_ARCH_ALL) +STEXI +@item -audiodev [driver=]@var{driver},id=@var{id}[,@var{prop}[=@var{value}][,...]] +@findex -audiodev +Adds a new audio backend @var{driver} identified by @var{id}. There are +global and driver specific properties. Some values can be set +differently for input and output, they're marked with @code{in|out.}. +You can set the input's property with @code{in.@var{prop}} and the +output's property with @code{out.@var{prop}}. For example: +@example +-audiodev alsa,id=example,in.frequency=44110,out.frequency=8000 +-audiodev alsa,id=example,out.channels=1 # leaves in.channels unspecified +@end example + +Valid global options are: + +@table @option +@item id=@var{identifier} +Identifies the audio backend. + +@item timer-period=@var{period} +Sets the timer @var{period} used by the audio subsystem in microseconds. +Default is 10000 (10 ms). + +@item in|out.fixed-settings=on|off +Use fixed settings for host audio. When off, it will change based on +how the guest opens the sound card. In this case you must not specify +@var{frequency}, @var{channels} or @var{format}. Default is on. + +@item in|out.frequency=@var{frequency} +Specify the @var{frequency} to use when using @var{fixed-settings}. +Default is 44100Hz. + +@item in|out.channels=@var{channels} +Specify the number of @var{channels} to use when using +@var{fixed-settings}. Default is 2 (stereo). + +@item in|out.format=@var{format} +Specify the sample @var{format} to use when using @var{fixed-settings}. +Valid values are: @code{s8}, @code{s16}, @code{s32}, @code{u8}, +@code{u16}, @code{u32}. Default is @code{s16}. + +@item in|out.voices=@var{voices} +Specify the number of @var{voices} to use. Default is 1. + +@item in|out.buffer=@var{usecs} +Sets the size of the buffer in microseconds. + +@item in|out.buffer-count=@var{count} +Sets the @var{count} of the buffers. + +@end table + +@item -audiodev none,id=@var{id}[,@var{prop}[=@var{value}][,...]] +Creates a dummy backend that discards all outputs. This backend has no +backend specific properties. + +@item -audiodev alsa,id=@var{id}[,@var{prop}[=@var{value}][,...]] +Creates backend using the ALSA. This backend is only available on +Linux. + +ALSA specific options are: + +@table @option +@item alsa-in|alsa-out.dev=@var{device} +Specify the ALSA @var{device} to use for input and/or output. Default +is @code{default}. + +@item alsa-in|alsa-out.try-poll=on|off +Attempt to use poll mode with the device. Default is on. + +@item threshold=@var{threshold} +Threshold (in microseconds) when playback starts. Default is 0. + +@end table + +@item -audiodev coreaudio,id=@var{id}[,@var{prop}[=@var{value}][,...]] +Creates a backend using Apple's Core Audio. This backend is only +available on Mac OS and only supports playback. This backend has no +backend specific properties. + +@item -audiodev dsound,id=@var{id}[,@var{prop}[=@var{value}][,...]] +Creates a backend using Microsoft's DirectSound. This backend is only +available on Windows and only supports playback. + +Backend specific options are: + +@table @option + +@item latency=@var{usecs} +Add extra @var{usecs} microseconds latency to playback. Default is +10000 (10 ms). + +@end table + +@item -audiodev oss,id=@var{id}[,@var{prop}[=@var{value}][,...]] +Creates a backend using OSS. This backend is available on most +Unix-like systems. + +OSS specific options are: + +@table @option + +@item oss-in|oss-out.dev=@var{device} +Specify the file name of the OSS @var{device} to use. Default is +@code{/dev/dsp}. + +@item oss-in|oss-out.try-poll=on|of +Attempt to use poll mode with the device. Default is on. + +@item try-mmap=on|off +Try using memory mapped device access. Default is off. + +@item exclusive=on|off +Open the device in exclusive mode (vmix won't work in this case). +Default is off. + +@item dsp-policy=@var{policy} +Sets the timing policy (between 0 and 10, where smaller number means +smaller latency but higher CPU usage). Use -1 to use buffer sizes +specified by @code{buffer} and @code{buffer-count}. This option is +ignored if you do not have OSS 4. Default is 5. + +@end table + +@item -audiodev pa,id=@var{id}[,@var{prop}[=@var{value}][,...]] +Creates a backend using PulseAudio. This backend is available on most +systems. + +PulseAudio specific options are: + +@table @option + +@item server=@var{server} +Sets the PulseAudio @var{server} to connect to. + +@item sink|source.name=@var{sink} +Use the specified sink/source for playback/recording. + +@end table + +@item -audiodev sdl,id=@var{id}[,@var{prop}[=@var{value}][,...]] +Creates a backend using SDL. This backend is available on most systems, +but you should use your platform's native backend if possible. This +backend has no backend specific properties. + +@item -audiodev spice,id=@var{id}[,@var{prop}[=@var{value}][,...]] +Creates a backend that sends audio through SPICE. This backend requires +@code{-spice} and automatically selected in that case, so usually you +can ignore this option. This backend has no backend specific +properties. + +@item -audiodev wav,id=@var{id}[,@var{prop}[=@var{value}][,...]] +Creates a backend that writes audio to a WAV file. + +Backend specific options are: + +@table @option + +@item path=@var{path} +Write recorded audio into the specified file. Default is +@code{qemu.wav}. + +@end table ETEXI DEF("soundhw", HAS_ARG, QEMU_OPTION_soundhw,
Signature · 1 line
2.5.0
PATCH v2 12/49 audio: -audiodev command line option basic implementation
In reply to Kővágó, ZoltánAudio 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.
Note that backends are not updated and still rely on environment variables.
Also note that (due to moving try-poll from global to backend specific option) currently ALSA and OSS will always try poll mode, regardless of environment variables or -audiodev options.
--- audio/Makefile.objs | 2 +- audio/alsaaudio.c | 2 +- audio/audio.c | 566 +++++++++++++++++++------------------------------ audio/audio.h | 23 +- audio/audio_int.h | 6 +- audio/audio_legacy.c | 202 ++++++++++++++++++ audio/audio_template.h | 13 +- audio/coreaudio.c | 2 +- audio/dsoundaudio.c | 2 +- audio/noaudio.c | 2 +- audio/ossaudio.c | 2 +- audio/paaudio.c | 2 +- audio/sdlaudio.c | 2 +- audio/spiceaudio.c | 2 +- audio/wavaudio.c | 2 +- vl.c | 10 +- 16 files changed, 472 insertions(+), 368 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 +1 -1
@@ -1126,7 +1126,7 @@ static ALSAConf glob_conf = { .pcm_name_in = "default", }; -static void *alsa_audio_init (void ) +static void *alsa_audio_init (Audiodev *dev) {ALSAConf *conf =g_malloc (sizeof (ALSAConf)); *conf = glob_conf;
audio/audio.c +217 -349
718 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 -1
@@ -144,7 +144,7 @@ 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 +190,7 @@ struct SWVoiceCap {struct AudioState {struct audio_driver *drv; +Audiodev *dev;void *drv_opaque;QEMUTimer *ts;
@@ -200,6 +201,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 +215,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 +202 -0
202 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 +1 -1
@@ -502,7 +502,7 @@ static CoreaudioConf glob_conf = { .nbuffers = 4, }; -static void *coreaudio_audio_init (void ) +static void *coreaudio_audio_init (Audiodev *dev) {CoreaudioConf *conf =g_malloc (sizeof (CoreaudioConf)); *conf = glob_conf;
audio/dsoundaudio.c +1 -1
@@ -782,7 +782,7 @@ static void dsound_audio_fini (void *opaque)g_free (s); } -static void *dsound_audio_init (void ) +static void *dsound_audio_init (Audiodev *dev) {int err;HRESULT hr;
audio/noaudio.c +1 -1
@@ -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; }
audio/ossaudio.c +1 -1
@@ -846,7 +846,7 @@ static OSSConf glob_conf = { .policy = 5 }; -static void *oss_audio_init (void ) +static void *oss_audio_init (Audiodev *dev) {OSSConf *conf =g_malloc (sizeof (OSSConf)); *conf = glob_conf;
audio/paaudio.c +1 -1
@@ -812,7 +812,7 @@ static PAConf glob_conf = { .samples = 4096, }; -static void *qpa_audio_init (void ) +static void *qpa_audio_init (Audiodev *dev) {paaudio *g =g_malloc (sizeof (paaudio)); g->conf = glob_conf;
audio/sdlaudio.c +1 -1
@@ -391,7 +391,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) {
audio/spiceaudio.c +1 -1
@@ -75,7 +75,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 ;
audio/wavaudio.c +1 -1
@@ -231,7 +231,7 @@ static WAVConf glob_conf = { .wav_path = "qemu.wav" }; -static void *wav_audio_init (void ) +static void *wav_audio_init (Audiodev *dev) {WAVConf *conf =g_malloc (sizeof (WAVConf)); *conf = glob_conf;
vl.c +9 -1
@@ -3004,6 +3004,7 @@ int main(int argc, char **argv, char **envp)qemu_add_opts (&qemu_trace_opts);qemu_add_opts (&qemu_option_rom_opts);qemu_add_opts (&qemu_machine_opts); +qemu_add_opts (&qemu_audiodev_opts);qemu_add_opts (&qemu_mem_opts);qemu_add_opts (&qemu_smp_opts);qemu_add_opts (&qemu_boot_opts);
@@ -3309,9 +3310,15 @@ int main(int argc, char **argv, char **envp)add_device_config (DEV_BT , optarg);break ;case QEMU_OPTION_audio_help: -AUD_help (); +audio_legacy_help ();exit (0 );break ; +case QEMU_OPTION_audiodev: +if (!qemu_opts_parse_noisily (qemu_find_opts ("audiodev" ), + optarg, true)) { +exit (1 ); + } +break ;case QEMU_OPTION_soundhw:select_soundhw (optarg);break ;
@@ -4511,6 +4518,7 @@ int main(int argc, char **argv, char **envp)realtime_init (); +audio_set_options ();audio_init ();cpu_synchronize_all_post_init ();
Signature · 1 line
2.5.0
PATCH v2 13/49 alsaaudio: port to -audiodev config
In reply to Kővágó, Zoltán--- audio/alsaaudio.c | 310 ++++++++++++++------------------------------------- audio/audio_legacy.c | 64 +++++++++++ 2 files changed, 148 insertions(+), 226 deletions(-)
audio/alsaaudio.c +84 -226
@@ -22,6 +22,7 @@* THE SOFTWARE. */ #include <alsa/asoundlib.h> +#include "qapi-visit.h" #include "qemu-common.h" #include "qemu/main-loop.h" #include "audio.h"
@@ -34,28 +35,9 @@#define AUDIO_CAP "alsa"#include "audio_int.h" -typedef struct ALSAConf { -int size_in_usec_in; -int size_in_usec_out; -const char *pcm_name_in; -const char *pcm_name_out; -unsigned int buffer_size_in; -unsigned int period_size_in; -unsigned int buffer_size_out; -unsigned int period_size_out; -unsigned int threshold; - -int buffer_size_in_overridden; -int period_size_in_overridden; - -int buffer_size_out_overridden; -int period_size_out_overridden; -}ALSAConf ; -struct pollhlp {snd_pcm_t *handle;struct pollfd *pfds; -ALSAConf *conf;int count;int mask; };
@@ -67,6 +49,7 @@ typedef struct ALSAVoiceOut {void *pcm_buf;snd_pcm_t *handle;struct pollhlp pollhlp; +Audiodev *dev; } ALSAVoiceOut; typedef struct ALSAVoiceIn {
@@ -74,16 +57,13 @@ typedef struct ALSAVoiceIn {snd_pcm_t *handle;void *pcm_buf;struct pollhlp pollhlp; +Audiodev *dev; } ALSAVoiceIn;struct alsa_params_req {int freq;snd_pcm_format_t fmt;int nchannels; -int size_in_usec; -int override_mask; -unsigned int buffer_size; -unsigned int period_size; };struct alsa_params_obt {
@@ -409,7 +389,8 @@ static int alsa_to_audfmt (snd_pcm_format_t alsafmt, AudioFormat *fmt,static void alsa_dump_info (struct alsa_params_req *req,struct alsa_params_obt *obt, -snd_pcm_format_t obtfmt) +snd_pcm_format_t obtfmt, +AudiodevPerDirectionOptions *pdo) {dolog ("parameter | requested value | obtained value\n" );dolog ("format | %10d | %10d\n" , req->fmt, obtfmt);
@@ -417,8 +398,9 @@ static void alsa_dump_info (struct alsa_params_req *req, req->nchannels, obt->nchannels);dolog ("frequency | %10d | %10d\n" , req->freq, obt->freq);dolog ("============================================\n" ); -dolog ("requested: buffer size %d period size %d\n" , - req->buffer_size, req->period_size); +dolog ("requested: buffer len %" PRId64" buffer count %" PRId64"\n" , + pdo->has_buffer_len ? pdo->buffer_len :0 , + pdo->has_buffer_count ? pdo->buffer_count :0 );dolog ("obtained: samples %ld\n" , obt->samples); }
@@ -452,23 +434,25 @@ static void alsa_set_threshold (snd_pcm_t *handle, snd_pcm_uframes_t threshold) } } -static int alsa_open (int in,struct alsa_params_req *req, -struct alsa_params_obt *obt,snd_pcm_t **handlep, -ALSAConf *conf) +static int alsa_open (bool in,struct alsa_params_req *req, +struct alsa_params_obt *obt,snd_pcm_t **handlep, +Audiodev *dev) { +AudiodevPerDirectionOptions *pdo = in ? dev->in : dev->out; +AudiodevAlsaOptions *aopts = dev->alsa; +AudiodevAlsaPerDirectionOptions *apdo = + in ? aopts->alsa_in : aopts->alsa_out;snd_pcm_t *handle;snd_pcm_hw_params_t *hw_params;int err; -int size_in_usec;unsigned int freq, nchannels; -const char *pcm_name = in ? conf->pcm_name_in : conf->pcm_name_out; +const char *pcm_name = apdo->has_dev ? apdo->dev :"default" ;snd_pcm_uframes_t obt_buffer_size;const char *typ = in ?"ADC" :"DAC" ;snd_pcm_format_t obtfmt; freq = req->freq; nchannels = req->nchannels; - size_in_usec = req->size_in_usec;snd_pcm_hw_params_alloca (&hw_params);
@@ -528,79 +512,49 @@ static int alsa_open (int in, struct alsa_params_req *req, goto err; } -if (req->buffer_size) { -unsigned long obt; +if (pdo->buffer_count) { +if (pdo->buffer_len) { +int64_t req = pdo->buffer_len * pdo->buffer_count; -if (size_in_usec) {int dir =0 ; -unsigned int btime = req->buffer_size; +unsigned int btime = req; - err =snd_pcm_hw_params_set_buffer_time_near ( - handle, - hw_params, - &btime, - &dir - ); - obt = btime; - } -else { -snd_pcm_uframes_t bsize = req->buffer_size; + err =snd_pcm_hw_params_set_buffer_time_near ( + handle, hw_params, &btime, &dir); - err =snd_pcm_hw_params_set_buffer_size_near ( - handle, - hw_params, - &bsize - ); - obt = bsize; - } -if (err <0 ) { -alsa_logerr2 (err, typ,"Failed to set buffer %s to %d\n" , - size_in_usec ?"time" :"size" , req->buffer_size); - goto err; - } +if (err <0 ) { +alsa_logerr2 (err, typ, +"Failed to set buffer time to %" PRId64"\n" , + req); + goto err; + } -if ((req->override_mask &2 ) && (obt - req->buffer_size)) -dolog ("Requested buffer %s %u was rejected, using %lu\n" , - size_in_usec ?"time" :"size" , req->buffer_size, obt); +if (pdo->has_buffer_count && btime != req) { +dolog ("Requested buffer time %" PRId64 +" was rejected, using %u\n" , req, btime); + } + }else { +dolog ("Can't set buffer-count without buffer-len!\n" ); + } } -if (req->period_size) { -unsigned long obt; +if (pdo->buffer_len) { +int dir =0 ; +unsigned int ptime = pdo->buffer_len; -if (size_in_usec) { -int dir =0 ; -unsigned int ptime = req->period_size; - - err =snd_pcm_hw_params_set_period_time_near ( - handle, - hw_params, - &ptime, - &dir - ); - obt = ptime; - } -else { -int dir =0 ; -snd_pcm_uframes_t psize = req->period_size; - - err =snd_pcm_hw_params_set_period_size_near ( - handle, - hw_params, - &psize, - &dir - ); - obt = psize; - } + err =snd_pcm_hw_params_set_period_time_near (handle, hw_params, &ptime, + &dir);if (err <0 ) { -alsa_logerr2 (err, typ,"Failed to set period %s to %d\n" , - size_in_usec ?"time" :"size" , req->period_size); +alsa_logerr2 (err, typ,"Failed to set period time to %" PRId64"\n" , + pdo->buffer_len); goto err; } -if (((req->override_mask &1 ) && (obt - req->period_size))) -dolog ("Requested period %s %u was rejected, using %lu\n" , - size_in_usec ?"time" :"size" , req->period_size, obt); +if (pdo->has_buffer_len && ptime != pdo->buffer_len) { +dolog ("Requested period time %" PRId64" was rejected, using %d\n" , + pdo->buffer_len, ptime); + } } err =snd_pcm_hw_params (handle, hw_params);
@@ -632,33 +586,10 @@ static int alsa_open (int in, struct alsa_params_req *req, goto err; } -if (!in && conf->threshold) { -snd_pcm_uframes_t threshold; -int bytes_per_sec; - - bytes_per_sec = freq << (nchannels ==2 ); - -switch (obt->fmt) { -case AUDIO_FORMAT_S8 : -case AUDIO_FORMAT_U8 : -break ; - -case AUDIO_FORMAT_S16 : -case AUDIO_FORMAT_U16 : - bytes_per_sec <<=1 ; -break ; - -case AUDIO_FORMAT_S32 : -case AUDIO_FORMAT_U32 : - bytes_per_sec <<=2 ; -break ; - -default : -abort (); - } - - threshold = (conf->threshold * bytes_per_sec) /1000 ; -alsa_set_threshold (handle, threshold); +if (!in && aopts->has_threshold && aopts->threshold) { +struct audsettings as = { .freq = freq }; +alsa_set_threshold (handle, +audio_buffer_frames (pdo, &as, aopts->threshold)); } obt->nchannels = nchannels;
@@ -671,11 +602,11 @@ static int alsa_open (int in, struct alsa_params_req *req, obt->nchannels != req->nchannels || obt->freq != req->freq) {dolog ("Audio parameters for %s\n" , typ); -alsa_dump_info (req, obt, obtfmt); +alsa_dump_info (req, obt, obtfmt, pdo); }#ifdef DEBUG -alsa_dump_info (req, obt, obtfmt); +alsa_dump_info (req, obt, obtfmt, pdo);#endif return 0 ;
@@ -801,19 +732,13 @@ static int alsa_init_out(HWVoiceOut *hw, struct audsettings *as,struct alsa_params_obt obt;snd_pcm_t *handle;struct audsettings obt_as; -ALSAConf *conf = drv_opaque; +Audiodev *dev = drv_opaque; req.fmt =aud_to_alsafmt (as->fmt, as->endianness); req.freq = as->freq; req.nchannels = as->nchannels; - req.period_size = conf->period_size_out; - req.buffer_size = conf->buffer_size_out; - req.size_in_usec = conf->size_in_usec_out; - req.override_mask = - (conf->period_size_out_overridden ?1 :0 ) | - (conf->buffer_size_out_overridden ?2 :0 ); -if (alsa_open (0 , &req, &obt, &handle, conf)) { +if (alsa_open (0 , &req, &obt, &handle, dev)) {return -1 ; }
@@ -834,7 +759,7 @@ static int alsa_init_out(HWVoiceOut *hw, struct audsettings *as, } alsa->handle = handle; - alsa->pollhlp.conf = conf; + alsa->dev = dev;return 0 ; }
@@ -874,16 +799,12 @@ static int alsa_voice_ctl (snd_pcm_t *handle, const char *typ, int ctl)static int alsa_ctl_out (HWVoiceOut *hw,int cmd, ...) {ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw; +AudiodevAlsaPerDirectionOptions *apdo = alsa->dev->alsa->alsa_out;switch (cmd) {case VOICE_ENABLE : { -va_list ap; -int poll_mode; - -va_start (ap, cmd); - poll_mode =va_arg (ap, int); -va_end (ap); +bool poll_mode = !apdo->has_try_poll || apdo->try_poll;ldebug ("enabling voice\n" );if (poll_mode &&alsa_poll_out (hw)) {
@@ -912,19 +833,13 @@ static int alsa_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque)struct alsa_params_obt obt;snd_pcm_t *handle;struct audsettings obt_as; -ALSAConf *conf = drv_opaque; +Audiodev *dev = drv_opaque; req.fmt =aud_to_alsafmt (as->fmt, as->endianness); req.freq = as->freq; req.nchannels = as->nchannels; - req.period_size = conf->period_size_in; - req.buffer_size = conf->buffer_size_in; - req.size_in_usec = conf->size_in_usec_in; - req.override_mask = - (conf->period_size_in_overridden ?1 :0 ) | - (conf->buffer_size_in_overridden ?2 :0 ); -if (alsa_open (1 , &req, &obt, &handle, conf)) { +if (alsa_open (1 , &req, &obt, &handle, dev)) {return -1 ; }
@@ -945,7 +860,7 @@ static int alsa_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque) } alsa->handle = handle; - alsa->pollhlp.conf = conf; + alsa->dev = dev;return 0 ; }
@@ -1087,16 +1002,12 @@ static int alsa_read (SWVoiceIn *sw, void *buf, int size)static int alsa_ctl_in (HWVoiceIn *hw,int cmd, ...) {ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw; +AudiodevAlsaPerDirectionOptions *apdo = alsa->dev->alsa->alsa_in;switch (cmd) {case VOICE_ENABLE : { -va_list ap; -int poll_mode; - -va_start (ap, cmd); - poll_mode =va_arg (ap, int); -va_end (ap); +bool poll_mode = !apdo->has_try_poll || apdo->try_poll;ldebug ("enabling voice\n" );if (poll_mode &&alsa_poll_in (hw)) {
@@ -1119,88 +1030,36 @@ static int alsa_ctl_in (HWVoiceIn *hw, int cmd, ...)return -1 ; } -static ALSAConf glob_conf = { - .buffer_size_out =4096 , - .period_size_out =1024 , - .pcm_name_out ="default" , - .pcm_name_in ="default" , -}; -static void *alsa_audio_init (Audiodev *dev) { -ALSAConf *conf =g_malloc (sizeof (ALSAConf)); - *conf = glob_conf; -return conf; +assert (dev->kind ==AUDIODEV_DRIVER_ALSA ); + +/* need to define them, as otherwise alsa produces no sound +* doesn't set has_* so alsa_open can identify it wasn't set by the user */ +if (!dev->out->has_buffer_count) { + dev->out->buffer_count =4 ; + } +if (!dev->out->has_buffer_len) { +/* 1024 frames assuming 44100Hz */ + dev->out->buffer_len =1024 *1000000 /44100 ; + } + +/* OptsVisitor sets unspecified optional fields to zero, but do not depend +* on it... */ +if (!dev->in->has_buffer_count) { + dev->in->buffer_count =0 ; + } +if (!dev->in->has_buffer_len) { + dev->in->buffer_len =0 ; + } + +return dev; }static void alsa_audio_fini (void *opaque) { -g_free (opaque); } -static struct audio_option alsa_options[] = { - { - .name ="DAC_SIZE_IN_USEC" , - .tag =AUD_OPT_BOOL , - .valp = &glob_conf.size_in_usec_out, - .descr ="DAC period/buffer size in microseconds (otherwise in frames)" - }, - { - .name ="DAC_PERIOD_SIZE" , - .tag =AUD_OPT_INT , - .valp = &glob_conf.period_size_out, - .descr ="DAC period size (0 to go with system default)" , - .overriddenp = &glob_conf.period_size_out_overridden - }, - { - .name ="DAC_BUFFER_SIZE" , - .tag =AUD_OPT_INT , - .valp = &glob_conf.buffer_size_out, - .descr ="DAC buffer size (0 to go with system default)" , - .overriddenp = &glob_conf.buffer_size_out_overridden - }, - { - .name ="ADC_SIZE_IN_USEC" , - .tag =AUD_OPT_BOOL , - .valp = &glob_conf.size_in_usec_in, - .descr = -"ADC period/buffer size in microseconds (otherwise in frames)" - }, - { - .name ="ADC_PERIOD_SIZE" , - .tag =AUD_OPT_INT , - .valp = &glob_conf.period_size_in, - .descr ="ADC period size (0 to go with system default)" , - .overriddenp = &glob_conf.period_size_in_overridden - }, - { - .name ="ADC_BUFFER_SIZE" , - .tag =AUD_OPT_INT , - .valp = &glob_conf.buffer_size_in, - .descr ="ADC buffer size (0 to go with system default)" , - .overriddenp = &glob_conf.buffer_size_in_overridden - }, - { - .name ="THRESHOLD" , - .tag =AUD_OPT_INT , - .valp = &glob_conf.threshold, - .descr ="(undocumented)" - }, - { - .name ="DAC_DEV" , - .tag =AUD_OPT_STR , - .valp = &glob_conf.pcm_name_out, - .descr ="DAC device name (for instance dmix)" - }, - { - .name ="ADC_DEV" , - .tag =AUD_OPT_STR , - .valp = &glob_conf.pcm_name_in, - .descr ="ADC device name" - }, - {/* End of list */ } -}; -static struct audio_pcm_ops alsa_pcm_ops = { .init_out = alsa_init_out, .fini_out = alsa_fini_out,
@@ -1218,7 +1077,6 @@ static struct audio_pcm_ops alsa_pcm_ops = {struct audio_driver alsa_audio_driver = { .name ="alsa" , .descr ="ALSA http://www.alsa-project.org" , - .options = alsa_options, .init = alsa_audio_init, .fini = alsa_audio_fini, .pcm_ops = &alsa_pcm_ops,
audio/audio_legacy.c +64 -0
82 lines not on this page · raw message
Signature · 1 line
2.5.0
PATCH v2 14/49 coreaudio: port to -audiodev config
In reply to Kővágó, Zoltán--- audio/audio_legacy.c | 10 ++++++++++ audio/coreaudio.c | 47 ++++++++++------------------------------------- 2 files changed, 20 insertions(+), 37 deletions(-)
audio/audio_legacy.c +10 -0
@@ -58,6 +58,14 @@ SimpleEnvMap alsa_map[] = { {/* End of list */ } }; +SimpleEnvMap coreaudio_map[] = { + {"QEMU_COREAUDIO_BUFFER_SIZE" ,"buffer-len" , +ENV_TRANSFORM_FRAMES_TO_USECS_OUT }, + {"QEMU_COREAUDIO_BUFFER_COUNT" ,"buffer-count" }, + + {/* End of list */ } +}; +static unsigned long long toull (const char *str) {unsigned long long ret;
@@ -228,6 +236,8 @@ static void legacy_opt(const char *drv)if (strcmp (drv,"alsa" ) ==0 ) {handle_env_opts (opts, alsa_map);handle_alsa (opts); + }else if (strcmp (drv,"coreaudio" ) ==0 ) { +handle_env_opts (opts, coreaudio_map); } }
audio/coreaudio.c +10 -37
99 lines not on this page · raw message
Signature · 1 line
2.5.0
PATCH v2 15/49 dsoundaudio: port to -audiodev config
In reply to Kővágó, Zoltán--- audio/audio_legacy.c | 12 ++++++++++ audio/dsound_template.h | 6 ++--- audio/dsoundaudio.c | 59 ++++++++++++++----------------------------------- 3 files changed, 32 insertions(+), 45 deletions(-)
audio/audio_legacy.c +12 -0
@@ -66,6 +66,16 @@ SimpleEnvMap coreaudio_map[] = { {/* End of list */ } }; +SimpleEnvMap dsound_map[] = { + {"QEMU_DSOUND_LATENCY_MILLIS" ,"latency" ,ENV_TRANSFORM_MILLIS_TO_USECS }, + {"QEMU_DSOUND_BUFSIZE_OUT" ,"out.buffer-len" , +ENV_TRANSFORM_BYTES_TO_USECS_OUT }, + {"QEMU_DSOUND_BUFSIZE_IN" ,"in.buffer-len" , +ENV_TRANSFORM_BYTES_TO_USECS_IN }, + + {/* End of list */ } +}; +static unsigned long long toull (const char *str) {unsigned long long ret;
@@ -238,6 +248,8 @@ static void legacy_opt(const char *drv)handle_alsa (opts); }else if (strcmp (drv,"coreaudio" ) ==0 ) {handle_env_opts (opts, coreaudio_map); + }else if (strcmp (drv,"dsound" ) ==0 ) { +handle_env_opts (opts, dsound_map); } }
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 -42
124 lines not on this page · raw message
Signature · 1 line
2.5.0
PATCH v2 16/49 noaudio: port to -audiodev config
In reply to Kővágó, Zoltán--- audio/noaudio.c | 1 - 1 file changed, 1 deletion(-)
audio/noaudio.c +0 -1
@@ -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,
Signature · 1 line
2.5.0
PATCH v2 17/49 ossaudio: port to -audiodev config
In reply to Kővágó, Zoltán--- audio/audio_legacy.c | 17 ++++++ audio/ossaudio.c | 153 ++++++++++++++------------------------------------- 2 files changed, 59 insertions(+), 111 deletions(-)
audio/audio_legacy.c +17 -0
@@ -76,6 +76,21 @@ SimpleEnvMap dsound_map[] = { {/* End of list */ } }; +SimpleEnvMap oss_map[] = { + {"QEMU_AUDIO_DAC_TRY_POLL" ,"oss-out.try-poll" ,ENV_TRANSFORM_BOOL }, + {"QEMU_AUDIO_ADC_TRY_POLL" ,"oss-in.try-poll" ,ENV_TRANSFORM_BOOL }, + + {"QEMU_OSS_FRAGSIZE" ,"buffer-len" ,ENV_TRANSFORM_BYTES_TO_USECS_OUT }, + {"QEMU_OSS_NFRAGS" ,"buffer-count" }, + {"QEMU_OSS_MMAP" ,"try-mmap" ,ENV_TRANSFORM_BOOL }, + {"QEMU_OSS_DAC_DEV" ,"oss-out.dev" }, + {"QEMU_OSS_ADC_DEV" ,"oss-in.dev" }, + {"QEMU_OSS_EXCLUSIVE" ,"exclusive" ,ENV_TRANSFORM_BOOL }, + {"QEMU_OSS_POLICY" ,"dsp-policy" }, + + {/* End of list */ } +}; +static unsigned long long toull (const char *str) {unsigned long long ret;
@@ -250,6 +265,8 @@ static void legacy_opt(const char *drv)handle_env_opts (opts, coreaudio_map); }else if (strcmp (drv,"dsound" ) ==0 ) {handle_env_opts (opts, dsound_map); + }else if (strcmp (drv,"oss" ) ==0 ) { +handle_env_opts (opts, oss_map); } }
audio/ossaudio.c +42 -111
301 lines not on this page · raw message
Signature · 1 line
2.5.0
PATCH v2 18/49 paaudio: port to -audiodev config
In reply to Kővágó, Zoltán--- audio/audio_legacy.c | 11 ++++++++ audio/paaudio.c | 80 +++++++++++++++++++--------------------------------- 2 files changed, 40 insertions(+), 51 deletions(-)
audio/audio_legacy.c +11 -0
@@ -91,6 +91,15 @@ SimpleEnvMap oss_map[] = { {/* End of list */ } }; +SimpleEnvMap pa_map[] = { + {"QEMU_PA_SAMPLES" ,"buffer" ,ENV_TRANSFORM_SAMPLES_TO_USECS_OUT }, + {"QEMU_PA_SERVER" ,"server" }, + {"QEMU_PA_SINK" ,"sink.name" }, + {"QEMU_PA_SOURCE" ,"source.name" }, + + {/* End of list */ } +}; +static unsigned long long toull (const char *str) {unsigned long long ret;
@@ -267,6 +276,8 @@ static void legacy_opt(const char *drv)handle_env_opts (opts, dsound_map); }else if (strcmp (drv,"oss" ) ==0 ) {handle_env_opts (opts, oss_map); + }else if (strcmp (drv,"pa" ) ==0 ) { +handle_env_opts (opts, pa_map); } }
audio/paaudio.c +29 -51
184 lines not on this page · raw message
Signature · 1 line
2.5.0
PATCH v2 19/49 sdlaudio: port to -audiodev config
In reply to Kővágó, Zoltán--- audio/audio_legacy.c | 7 +++++++ audio/sdlaudio.c | 22 ++++------------------ 2 files changed, 11 insertions(+), 18 deletions(-)
audio/audio_legacy.c +7 -0
@@ -100,6 +100,11 @@ SimpleEnvMap pa_map[] = { {/* End of list */ } }; +SimpleEnvMap sdl_map[] = { + {"QEMU_SDL_SAMPLES" ,"buffer-len" ,ENV_TRANSFORM_SAMPLES_TO_USECS_OUT }, + {/* End of list */ } +}; +static unsigned long long toull (const char *str) {unsigned long long ret;
@@ -278,6 +283,8 @@ static void legacy_opt(const char *drv)handle_env_opts (opts, oss_map); }else if (strcmp (drv,"pa" ) ==0 ) {handle_env_opts (opts, pa_map); + }else if (strcmp (drv,"sdl" ) ==0 ) { +handle_env_opts (opts, sdl_map); } }
audio/sdlaudio.c +4 -18
@@ -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;
@@ -420,6 +415,7 @@ static void *sdl_audio_init(Audiodev *dev) } 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,
Signature · 1 line
2.5.0
PATCH v2 20/49 spiceaudio: port to -audiodev config
In reply to Kővágó, Zoltán--- audio/spiceaudio.c | 5 ----- 1 file changed, 5 deletions(-)
audio/spiceaudio.c +0 -5
@@ -371,10 +371,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,
@@ -392,7 +388,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,
Signature · 1 line
2.5.0
PATCH v2 21/49 wavaudio: port to -audiodev config
In reply to Kővágó, Zoltán--- audio/audio_legacy.c | 10 +++++++++ audio/wavaudio.c | 58 ++++++++-------------------------------------------- 2 files changed, 19 insertions(+), 49 deletions(-)
audio/audio_legacy.c +10 -0
@@ -105,6 +105,14 @@ SimpleEnvMap sdl_map[] = { {/* End of list */ } }; +SimpleEnvMap wav_map[] = { + {"QEMU_WAV_FREQUENCY" ,"out.frequency" }, + {"QEMU_WAV_FORMAT" ,"out.format" ,ENV_TRANSFORM_FMT }, + {"QEMU_WAV_DAC_FIXED_CHANNELS" ,"out.channels" }, + {"QEMU_WAV_PATH" ,"path" }, + {/* End of list */ } +}; +static unsigned long long toull (const char *str) {unsigned long long ret;
@@ -285,6 +293,8 @@ static void legacy_opt(const char *drv)handle_env_opts (opts, pa_map); }else if (strcmp (drv,"sdl" ) ==0 ) {handle_env_opts (opts, sdl_map); + }else if (strcmp (drv,"wav" ) ==0 ) { +handle_env_opts (opts, wav_map); } }
audio/wavaudio.c +9 -49
105 lines not on this page · raw message
Signature · 1 line
2.5.0
PATCH v2 22/49 audio: -audiodev command line option: cleanup
In reply to Kővágó, ZoltánRemove no longer needed codes.
--- audio/audio.c | 202 ++---------------------------------------------------- audio/audio_int.h | 17 ----- 2 files changed, 4 insertions(+), 215 deletions(-)
audio/audio.c +4 -198
@@ -142,114 +142,6 @@ void *audio_calloc (const char *funcname, int nmemb, size_t size)return g_malloc0 (len); } -static const char *audio_audfmt_to_string (AudioFormat fmt) -{ -switch (fmt) { -case AUDIO_FORMAT_U8 : -return "U8" ; - -case AUDIO_FORMAT_U16 : -return "U16" ; - -case AUDIO_FORMAT_S8 : -return "S8" ; - -case AUDIO_FORMAT_S16 : -return "S16" ; - -case AUDIO_FORMAT_U32 : -return "U32" ; - -case AUDIO_FORMAT_S32 : -return "S32" ; - -default : -abort (); - } - -dolog ("Bogus audfmt %d returning S16\n" , fmt); -return "S16" ; -} - -static AudioFormat audio_string_to_audfmt (const char *s,AudioFormat defval, -int *defaultp) -{ -if (!strcasecmp (s,"u8" )) { - *defaultp =0 ; -return AUDIO_FORMAT_U8 ; - } -else if (!strcasecmp (s,"u16" )) { - *defaultp =0 ; -return AUDIO_FORMAT_U16 ; - } -else if (!strcasecmp (s,"u32" )) { - *defaultp =0 ; -return AUDIO_FORMAT_U32 ; - } -else if (!strcasecmp (s,"s8" )) { - *defaultp =0 ; -return AUDIO_FORMAT_S8 ; - } -else if (!strcasecmp (s,"s16" )) { - *defaultp =0 ; -return AUDIO_FORMAT_S16 ; - } -else if (!strcasecmp (s,"s32" )) { - *defaultp =0 ; -return AUDIO_FORMAT_S32 ; - } -else { -dolog ("Bogus audio format `%s' using %s\n" , - s,audio_audfmt_to_string (defval)); - *defaultp =1 ; -return defval; - } -} - -static AudioFormat audio_get_conf_fmt (const char *envname, -AudioFormat defval, -int *defaultp) -{ -const char *var =getenv (envname); -if (!var) { - *defaultp =1 ; -return defval; - } -return audio_string_to_audfmt (var, defval, defaultp); -} - -static int audio_get_conf_int (const char *key,int defval,int *defaultp) -{ -int val; -char *strval; - - strval =getenv (key); -if (strval) { - *defaultp =0 ; - val =atoi (strval); -return val; - } -else { - *defaultp =1 ; -return defval; - } -} - -static const char *audio_get_conf_str (const char *key, -const char *defval, -int *defaultp) -{ -const char *val =getenv (key); -if (!val) { - *defaultp =1 ; -return defval; - } -else { - *defaultp =0 ; -return val; - } -} -void AUD_vlog (const char *cap,const char *fmt,va_list ap) {if (cap) {
@@ -268,89 +160,6 @@ void AUD_log (const char *cap, const char *fmt, ...)va_end (ap); } -static void audio_process_options (const char *prefix, -struct audio_option *opt) -{ -char *optname; -const char qemu_prefix[] ="QEMU_" ; -size_t preflen, optlen; - -if (audio_bug (AUDIO_FUNC , !prefix)) { -dolog ("prefix = NULL\n" ); -return ; - } - -if (audio_bug (AUDIO_FUNC , !opt)) { -dolog ("opt = NULL\n" ); -return ; - } - - preflen =strlen (prefix); - -for (; opt->name; opt++) { -size_t len, i; -int def; - -if (!opt->valp) { -dolog ("Option value pointer for `%s' is not set\n" , - opt->name); -continue ; - } - - len =strlen (opt->name); -/* len of opt->name + len of prefix + size of qemu_prefix -* (includes trailing zero) + zero + underscore (on behalf of -* sizeof) */ - optlen = len + preflen +sizeof (qemu_prefix) +1 ; - optname =g_malloc (optlen); - -pstrcpy (optname, optlen, qemu_prefix); - -/* copy while upper-casing, including trailing zero */ -for (i =0 ; i <= preflen; ++i) { - optname[i +sizeof (qemu_prefix) -1 ] =qemu_toupper (prefix[i]); - } -pstrcat (optname, optlen,"_" ); -pstrcat (optname, optlen, opt->name); - - def =1 ; -switch (opt->tag) { -case AUD_OPT_BOOL : -case AUD_OPT_INT : - { -int *intp = opt->valp; - *intp =audio_get_conf_int (optname, *intp, &def); - } -break ; - -case AUD_OPT_FMT : - { -AudioFormat *fmtp = opt->valp; - *fmtp =audio_get_conf_fmt (optname, *fmtp, &def); - } -break ; - -case AUD_OPT_STR : - { -const char **strp = opt->valp; - *strp =audio_get_conf_str (optname, *strp, &def); - } -break ; - -default : -dolog ("Bad value tag for option `%s' - %d\n" , - optname, opt->tag); -break ; - } - -if (!opt->overriddenp) { - opt->overriddenp = &opt->overridden; - } - *opt->overriddenp = !def; -g_free (optname); - } -} -static void audio_print_settings (struct audsettings *as) {dolog ("frequency=%d nchannels=%d fmt=" , as->freq, as->nchannels);
@@ -1047,7 +856,7 @@ void AUD_set_active_out (SWVoiceOut *sw, int on)if (!hw->enabled) { hw->enabled =1 ;if (s->vm_running) { - hw->pcm_ops->ctl_out (hw,VOICE_ENABLE , true/* todo */ ); + hw->pcm_ops->ctl_out (hw,VOICE_ENABLE );audio_reset_timer (s); } }
@@ -1092,7 +901,7 @@ void AUD_set_active_in (SWVoiceIn *sw, int on)if (!hw->enabled) { hw->enabled =1 ;if (s->vm_running) { - hw->pcm_ops->ctl_in (hw,VOICE_ENABLE , true/* todo */ ); + hw->pcm_ops->ctl_in (hw,VOICE_ENABLE );audio_reset_timer (s); } }
@@ -1412,9 +1221,6 @@ void audio_run (const char *msg)static int audio_driver_init (AudioState *s,struct audio_driver *drv,Audiodev *dev) { -if (drv->options) { -audio_process_options (drv->name, drv->options); - } s->drv_opaque = drv->init (dev);if (s->drv_opaque) {
@@ -1439,11 +1245,11 @@ static void audio_vm_change_state_handler (void *opaque, int running, s->vm_running = running;while ((hwo =audio_pcm_hw_find_any_enabled_out (hwo))) { - hwo->pcm_ops->ctl_out (hwo, op, true/* todo */ ); + hwo->pcm_ops->ctl_out (hwo, op); }while ((hwi =audio_pcm_hw_find_any_enabled_in (hwi))) { - hwi->pcm_ops->ctl_in (hwi, op, true/* todo */ ); + hwi->pcm_ops->ctl_in (hwi, op); }audio_reset_timer (s); }
audio/audio_int.h +0 -17
@@ -32,22 +32,6 @@struct audio_pcm_ops ; -typedef enum { -AUD_OPT_INT , -AUD_OPT_FMT , -AUD_OPT_STR , -AUD_OPT_BOOL -}audio_option_tag_e ; - -struct audio_option { -const char *name; -audio_option_tag_e tag; -void *valp; -const char *descr; -int *overriddenp; -int overridden; -}; -struct audio_callback {void *opaque;audio_callback_fn fn;
@@ -143,7 +127,6 @@ struct SWVoiceIn {struct audio_driver {const char *name;const char *descr; -struct audio_option *options;void *(*init) (Audiodev *);void (*fini) (void *);struct audio_pcm_ops *pcm_ops;
Signature · 1 line
2.5.0
PATCH v2 23/49 audio: reduce glob_audio_state usage
In reply to Kővágó, ZoltánRemove glob_audio_state from functions, where possible without breaking the API. This means that most static functions in audio.c now take an AudioState pointer instead of implicitly using glob_audio_state. Also included a pointer in SWVoice*, HWVoice* structs, so that functions dealing them can know the audio state without having to pass it around separately.
This is required in order to support multiple simultaneous audio backends (added in a later commit).
--- audio/audio.c | 41 ++++++++++++++++++++--------------------- audio/audio_int.h | 4 ++++ audio/audio_template.h | 46 ++++++++++++++++++++++------------------------ 3 files changed, 46 insertions(+), 45 deletions(-)
audio/audio.c +20 -21
@@ -367,12 +367,10 @@ static void noop_conv (struct st_sample *dst, const void *src, int samples) (void ) samples; } -static CaptureVoiceOut *audio_pcm_capture_find_specific ( -struct audsettings *as - ) +static CaptureVoiceOut *audio_pcm_capture_find_specific (AudioState *s, +struct audsettings *as) {CaptureVoiceOut *cap; -AudioState *s = &glob_audio_state;for (cap = s->cap_head.lh_first; cap; cap = cap->entries.le_next) {if (audio_pcm_info_eq (&cap->hw.info, as)) {
@@ -449,7 +447,7 @@ static void audio_detach_capture (HWVoiceOut *hw)static int audio_attach_capture (HWVoiceOut *hw) { -AudioState *s = &glob_audio_state; +AudioState *s = hw->s;CaptureVoiceOut *cap;audio_detach_capture (hw);
@@ -762,15 +760,15 @@ static void audio_pcm_print_info (const char *cap, struct audio_pcm_info *info)/* * Timer */ -static int audio_is_timer_needed (void ) +static int audio_is_timer_needed (AudioState *s) {HWVoiceIn *hwi =NULL ;HWVoiceOut *hwo =NULL ; -while ((hwo =audio_pcm_hw_find_any_enabled_out (hwo))) { +while ((hwo =audio_pcm_hw_find_any_enabled_out (s, hwo))) {if (!hwo->poll_mode)return 1 ; } -while ((hwi =audio_pcm_hw_find_any_enabled_in (hwi))) { +while ((hwi =audio_pcm_hw_find_any_enabled_in (s, hwi))) {if (!hwi->poll_mode)return 1 ; }return 0 ;
@@ -778,7 +776,7 @@ static int audio_is_timer_needed (void)static void audio_reset_timer (AudioState *s) { -if (audio_is_timer_needed ()) { +if (audio_is_timer_needed (s)) {timer_mod (s->ts,qemu_clock_get_ns (QEMU_CLOCK_VIRTUAL ) + s->period_ticks); }
@@ -847,7 +845,7 @@ void AUD_set_active_out (SWVoiceOut *sw, int on) hw = sw->hw;if (sw->active != on) { -AudioState *s = &glob_audio_state; +AudioState *s = sw->s;SWVoiceOut *temp_sw;SWVoiceCap *sc;
@@ -894,7 +892,7 @@ void AUD_set_active_in (SWVoiceIn *sw, int on) hw = sw->hw;if (sw->active != on) { -AudioState *s = &glob_audio_state; +AudioState *s = sw->s;SWVoiceIn *temp_sw;if (on) {
@@ -1017,7 +1015,7 @@ static void audio_run_out (AudioState *s)HWVoiceOut *hw =NULL ;SWVoiceOut *sw; -while ((hw =audio_pcm_hw_find_any_enabled_out (hw))) { +while ((hw =audio_pcm_hw_find_any_enabled_out (s, hw))) {int played;int live, free, nb_live, cleanup_required, prev_rpos;
@@ -1121,7 +1119,7 @@ static void audio_run_in (AudioState *s) {HWVoiceIn *hw =NULL ; -while ((hw =audio_pcm_hw_find_any_enabled_in (hw))) { +while ((hw =audio_pcm_hw_find_any_enabled_in (s, hw))) {SWVoiceIn *sw;int captured, min;
@@ -1224,8 +1222,8 @@ static int audio_driver_init(AudioState *s, struct audio_driver *drv, s->drv_opaque = drv->init (dev);if (s->drv_opaque) { -audio_init_nb_voices_out (drv); -audio_init_nb_voices_in (drv); +audio_init_nb_voices_out (s, drv); +audio_init_nb_voices_in (s, drv); s->drv = drv;return 0 ; }
@@ -1244,11 +1242,11 @@ static void audio_vm_change_state_handler (void *opaque, int running,int op = running ?VOICE_ENABLE :VOICE_DISABLE ; s->vm_running = running; -while ((hwo =audio_pcm_hw_find_any_enabled_out (hwo))) { +while ((hwo =audio_pcm_hw_find_any_enabled_out (s, hwo))) { hwo->pcm_ops->ctl_out (hwo, op); } -while ((hwi =audio_pcm_hw_find_any_enabled_in (hwi))) { +while ((hwi =audio_pcm_hw_find_any_enabled_in (s, hwi))) { hwi->pcm_ops->ctl_in (hwi, op); }audio_reset_timer (s);
@@ -1260,7 +1258,7 @@ static void audio_atexit (void)HWVoiceOut *hwo =NULL ;HWVoiceIn *hwi =NULL ; -while ((hwo =audio_pcm_hw_find_any_out (hwo))) { +while ((hwo =audio_pcm_hw_find_any_out (s, hwo))) {SWVoiceCap *sc;if (hwo->enabled) {
@@ -1278,7 +1276,7 @@ static void audio_atexit (void) } } -while ((hwi =audio_pcm_hw_find_any_in (hwi))) { +while ((hwi =audio_pcm_hw_find_any_in (s, hwi))) {if (hwi->enabled) { hwi->pcm_ops->ctl_in (hwi,VOICE_DISABLE ); }
@@ -1459,7 +1457,7 @@ CaptureVoiceOut *AUD_add_capture ( cb->ops = *ops; cb->opaque = cb_opaque; - cap =audio_pcm_capture_find_specific (as); + cap =audio_pcm_capture_find_specific (s, as);if (cap) {QLIST_INSERT_HEAD (&cap->cb_head, cb, entries);return cap;
@@ -1476,6 +1474,7 @@ CaptureVoiceOut *AUD_add_capture ( } hw = &cap->hw; + hw->s = s;QLIST_INIT (&hw->sw_head);QLIST_INIT (&cap->cb_head);
@@ -1509,7 +1508,7 @@ CaptureVoiceOut *AUD_add_capture (QLIST_INSERT_HEAD (&cap->cb_head, cb, entries); hw =NULL ; -while ((hw =audio_pcm_hw_find_any_out (hw))) { +while ((hw =audio_pcm_hw_find_any_out (s, hw))) {audio_attach_capture (hw); }return cap;
audio/audio_int.h +4 -0
@@ -51,6 +51,7 @@ struct audio_pcm_info {typedef struct SWVoiceCap SWVoiceCap ; typedef struct HWVoiceOut { + AudioState *s; int enabled; int poll_mode; int pending_disable;
@@ -72,6 +73,7 @@ typedef struct HWVoiceOut { } HWVoiceOut; typedef struct HWVoiceIn { + AudioState *s; int enabled; int poll_mode; struct audio_pcm_info info;
@@ -93,6 +95,7 @@ typedef struct HWVoiceIn {struct SWVoiceOut {QEMUSoundCard *card; +AudioState *s;struct audio_pcm_info info;t_sample *conv;int64_t ratio;
@@ -110,6 +113,7 @@ struct SWVoiceOut {struct SWVoiceIn {QEMUSoundCard *card; +AudioState *s;int active;struct audio_pcm_info info;int64_t ratio;
audio/audio_template.h +22 -24
137 lines not on this page · raw message
Signature · 1 line
2.5.0
PATCH v2 24/49 audio: basic support for multi backend audio
In reply to Kővágó, ZoltánAudio functions no longer access glob_audio_state, instead they get an AudioState as a parameter. This is required in order to support multiple backends.
glob_audio_state is also gone, and replaced with a tailq so we can store more than one states.
--- audio/audio.c | 98 +++++++++++++++++++++++++++++++++++++------------- audio/audio.h | 12 +++++-- audio/audio_int.h | 2 ++ audio/audio_template.h | 2 +- audio/wavcapture.c | 6 ++-- hmp-commands.hx | 11 +++--- monitor.c | 12 ++++++- qemu-options.hx | 5 +++ ui/vnc.c | 15 +++++++- ui/vnc.h | 2 ++ vl.c | 3 +- 11 files changed, 129 insertions(+), 39 deletions(-)
audio/audio.c +74 -24
@@ -55,7 +55,8 @@ struct audio_driver *drvtab[] = {NULL }; -static AudioState glob_audio_state; +static QTAILQ_HEAD(AudioStateHead, AudioState) audio_states = +QTAILQ_HEAD_INITIALIZER (audio_states);const struct mixeng_volume nominal_volume = { .mute =0 ,
@@ -1193,11 +1194,14 @@ static void audio_run_capture (AudioState *s)void audio_run (const char *msg) { -AudioState *s = &glob_audio_state; +AudioState *s; + + QTAILQ_FOREACH(s, &audio_states, list) { +audio_run_out (s); +audio_run_in (s); +audio_run_capture (s); + } -audio_run_out (s); -audio_run_in (s); -audio_run_capture (s);#ifdef DEBUG_POLL {static double prevtime;
@@ -1252,9 +1256,8 @@ static void audio_vm_change_state_handler (void *opaque, int running,audio_reset_timer (s); } -static void audio_atexit (void ) +static void free_audio_state (AudioState *s) { -AudioState *s = &glob_audio_state;HWVoiceOut *hwo =NULL ;HWVoiceIn *hwi =NULL ;
@@ -1288,6 +1291,16 @@ static void audio_atexit (void) }qapi_free_Audiodev (s->dev); +g_free (s); +} + +static void audio_atexit (void ) +{ +while (!QTAILQ_EMPTY (&audio_states)) { +AudioState *s =QTAILQ_FIRST (&audio_states); +QTAILQ_REMOVE (&audio_states, s, list); +free_audio_state (s); + } }static const VMStateDescription vmstate_audio = {
@@ -1300,26 +1313,27 @@ static const VMStateDescription vmstate_audio = { };static Audiodev *parse_option (QemuOpts *opts,Error **errp); -static int audio_init (Audiodev *dev) + +/* if we have dev, this function was called because of an -audiodev argument => +* initialize a new state with it +* if dev == NULL => legacy implicit initialization, return the already created +* state or create a new one */ +static AudioState *audio_init (Audiodev *dev) { +static bool atexit_registered;size_t i;int done =0 ;const char *drvname =NULL ;VMChangeStateEntry *e; -AudioState *s = &glob_audio_state; +AudioState *s;QemuOptsList *list =NULL ;/* silence gcc warning about uninitialized * variable */ -if (s->drv) { -if (dev) { -dolog ("Cannot create more than one audio backend, sorry\n" ); -qapi_free_Audiodev (dev); - } -return -1 ; - } -if (dev) { drvname = AudiodevDriver_lookup[dev->kind]; + }else if (!QTAILQ_EMPTY (&audio_states)) { +/* todo: chack for -audiodev we have normal audiodev selection support */ +return QTAILQ_FIRST (&audio_states); }else {audio_handle_legacy_opts (); list =qemu_find_opts ("audiodev" );
@@ -1328,12 +1342,18 @@ static int audio_init(Audiodev *dev)exit (1 ); } } + + s =g_malloc0 (sizeof (AudioState)); s->dev = dev;QLIST_INIT (&s->hw_head_out);QLIST_INIT (&s->hw_head_in);QLIST_INIT (&s->cap_head); -atexit (audio_atexit); +if (!atexit_registered) { +atexit (audio_atexit); + atexit_registered = true; + } +QTAILQ_INSERT_TAIL (&audio_states, s, list); s->ts =timer_new_ns (QEMU_CLOCK_VIRTUAL , audio_timer, s);if (!s->ts) {
@@ -1414,15 +1434,18 @@ static int audio_init(Audiodev *dev)QLIST_INIT (&s->card_head);vmstate_register (NULL ,0 , &vmstate_audio, s); -return 0 ; +return s; }void AUD_register_card (const char *name,QEMUSoundCard *card) { -audio_init (NULL ); +if (!card->state) { + card->state =audio_init (NULL ); + } + card->name =g_strdup (name);memset (&card->entries,0 ,sizeof (card->entries)); -QLIST_INSERT_HEAD (&glob_audio_state.card_head, card, entries); +QLIST_INSERT_HEAD (&card->state->card_head, card, entries); }void AUD_remove_card (QEMUSoundCard *card)
@@ -1432,16 +1455,21 @@ void AUD_remove_card (QEMUSoundCard *card) } -CaptureVoiceOut *AUD_add_capture ( +CaptureVoiceOut *AUD_add_capture ( +AudioState *s,struct audsettings *as,struct audio_capture_ops *ops,void *cb_opaque ) { -AudioState *s = &glob_audio_state;CaptureVoiceOut *cap;struct capture_callback *cb; +if (!s) { +/* todo: remove when we have normal audiodev selection support */ + s =QTAILQ_FIRST (&audio_states); + } +if (audio_validate_settings (as)) {dolog ("Invalid settings were passed when trying to add capture\n" );audio_print_settings (as);
@@ -1677,7 +1705,7 @@ static int each_option(void *opaque, QemuOpts *opts, Error **errp)if (!dev) {return -1 ; } -return audio_init (dev); +return audio_init (dev) ?0 :-1 ; }void audio_set_options (void )
@@ -1743,3 +1771,25 @@ int audio_buffer_bytes(AudiodevPerDirectionOptions *pdo,return audio_buffer_samples (pdo, as, def_usecs) *audioformat_bytes_per_sample (as->fmt); } + +AudioState *audio_state_by_name (const char *name) +{ +AudioState *s; + QTAILQ_FOREACH(s, &audio_states, list) { +assert (s->dev); +if (strcmp (name, s->dev->id) ==0 ) { +return s; + } + } +return NULL ; +} + +const char *audio_get_id (QEMUSoundCard *card) +{ +if (card->state) { +assert (card->state->dev); +return card->state->dev->id; + }else { +return "" ; + } +}
audio/audio.h +9 -3
@@ -80,8 +80,10 @@ typedef struct SWVoiceOut SWVoiceOut;typedef struct CaptureVoiceOut CaptureVoiceOut ;typedef struct SWVoiceIn SWVoiceIn ; +typedef struct AudioState AudioState ;typedef struct QEMUSoundCard {char *name; +AudioState *state;QLIST_ENTRY (QEMUSoundCard) entries; }QEMUSoundCard ;
@@ -96,7 +98,8 @@ void AUD_log (const char *cap, const char *fmt, ...) GCC_FMT_ATTR(2, 3);void AUD_register_card (const char *name,QEMUSoundCard *card);void AUD_remove_card (QEMUSoundCard *card); -CaptureVoiceOut *AUD_add_capture ( +CaptureVoiceOut *AUD_add_capture ( +AudioState *s,struct audsettings *as,struct audio_capture_ops *ops, void *opaque
@@ -164,11 +167,14 @@ static inline void *advance (void *p, int incr)#define audio_MAX (a, b) ((a)<(b)?(b):(a))#endif -int wav_start_capture (CaptureState *s,const char *path,int freq, -int bits,int nchannels); +int wav_start_capture (AudioState *state,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 ); +AudioState *audio_state_by_name (const char *name); +const char *audio_get_id (QEMUSoundCard *card); +#endif /* audio.h */
audio/audio_int.h +2 -0
@@ -189,6 +189,8 @@ struct AudioState {int nb_hw_voices_in;int vm_running;int64_t period_ticks; + +QTAILQ_ENTRY (AudioState) list; };extern struct audio_driver no_audio_driver;
audio/audio_template.h +1 -1
@@ -399,7 +399,7 @@ SW *glue (AUD_open_, TYPE) (struct audsettings *as ) { -AudioState *s = &glob_audio_state; +AudioState *s = card->state;AudiodevPerDirectionOptions *pdo = s->dev->TYPE;if (audio_bug (AUDIO_FUNC , !card || !name || !callback_fn || !as)) {
audio/wavcapture.c +3 -3
@@ -104,8 +104,8 @@ static struct capture_ops wav_capture_ops = { .info = wav_capture_info }; -int wav_start_capture (CaptureState *s,const char *path,int freq, -int bits,int nchannels) +int wav_start_capture (AudioState *state,CaptureState *s,const char *path, +int freq,int bits,int nchannels) {Monitor *mon = cur_mon;WAVState *wav;
@@ -172,7 +172,7 @@ int wav_start_capture (CaptureState *s, const char *path, int freq, goto error_free; } - cap =AUD_add_capture (&as, &ops, wav); + cap =AUD_add_capture (state, &as, &ops, wav);if (!cap) {monitor_printf (mon,"Failed to add audio capture\n" ); goto error_free;
hmp-commands.hx +6 -5
@@ -741,16 +741,17 @@ ETEXI { .name = "wavcapture", - .args_type = "path:F,freq:i?,bits:i?,nchannels:i?", - .params = "path [frequency [bits [channels]]]", + .args_type = "path:F,freq:i?,bits:i?,nchannels:i?,audiodev:s?", + .params = "path [frequency [bits [channels [audiodev]]]]", .help = "capture audio to a wave file (default frequency=44100 bits=16 channels=2)", .mhandler.cmd = hmp_wavcapture, }, STEXI -@item wavcapture @var{filename} [@var{frequency} [@var{bits} [@var{channels}]]] +@item wavcapture @var{filename} [@var{frequency} [@var{bits} [@var{channels} [@var{audiodev}]]]] @findex wavcapture -Capture audio into @var{filename}. Using sample rate @var{frequency} -bits per sample @var{bits} and number of channels @var{channels}. +Capture audio into @var{filename} from @var{audiodev}. Using sample rate +@var{frequency} bits per sample @var{bits} and number of channels +@var{channels}. Defaults: @itemize @minus
monitor.c +11 -1
@@ -1944,7 +1944,17 @@ static void hmp_wavcapture(Monitor *mon, const QDict *qdict)int bits =qdict_get_try_int (qdict,"bits" ,-1 );int has_channels =qdict_haskey (qdict,"nchannels" );int nchannels =qdict_get_try_int (qdict,"nchannels" ,-1 ); +const char *audiodev =qdict_get_try_str (qdict,"audiodev" );CaptureState *s; +AudioState *as =NULL ; + +if (audiodev) { + as =audio_state_by_name (audiodev); +if (!as) { +monitor_printf (mon,"Invalid audiodev specified\n" ); +return ; + } + } s =g_malloc0 (sizeof (*s));
@@ -1952,7 +1962,7 @@ static void hmp_wavcapture(Monitor *mon, const QDict *qdict) bits = has_bits ? bits :16 ; nchannels = has_channels ? nchannels :2 ; -if (wav_start_capture (s, path, freq, bits, nchannels)) { +if (wav_start_capture (as, s, path, freq, bits, nchannels)) {monitor_printf (mon,"Failed to add wave capture\n" );g_free (s);return ;
qemu-options.hx +5 -0
@@ -1538,6 +1538,11 @@ everybody else. 'ignore' completely ignores the shared flag and allows everybody connect unconditionally. Doesn't conform to the rfb spec but is traditional QEMU behavior. +@item audiodev=@var{audiodev} + +Use the specified @var{audiodev} when the VNC client requests audio +transmission. + @end table ETEXI
ui/vnc.c +14 -1
@@ -1193,7 +1193,7 @@ static void audio_add(VncState *vs) ops.destroy = audio_capture_destroy; ops.capture = audio_capture; - vs->audio_cap =AUD_add_capture (&vs->as, &ops, vs); + vs->audio_cap =AUD_add_capture (vs->vd->audio_state, &vs->as, &ops, vs);if (!vs->audio_cap) {error_report ("Failed to add audio capture" ); }
@@ -3295,6 +3295,9 @@ static QemuOptsList qemu_vnc_opts = { },{ .name = "non-adaptive", .type = QEMU_OPT_BOOL, + },{ + .name = "audiodev", + .type = QEMU_OPT_STRING, }, {/* end of list */ } },
@@ -3455,6 +3458,7 @@ void vnc_display_open(const char *id, Error **errp)int acl =0 ;#endif int lock_key_sync =1 ; +const char *audiodev;if (!vs) {error_setg (errp,"VNC display not active" );
@@ -3637,6 +3641,15 @@ void vnc_display_open(const char *id, Error **errp)#endif vs->lock_key_sync = lock_key_sync; + audiodev =qemu_opt_get (opts,"audiodev" ); +if (audiodev) { + vs->audio_state =audio_state_by_name (audiodev); +if (!vs->audio_state) { +error_setg (errp,"Audiodev '%s' not found" , audiodev); + goto fail; + } + } + device_id =qemu_opt_get (opts,"display" );if (device_id) {DeviceState *dev;
ui/vnc.h +2 -0
@@ -187,6 +187,8 @@ struct VncDisplay#ifdef CONFIG_VNC_SASL VncDisplaySASL sasl;#endif + +AudioState *audio_state; }; typedef struct VncTight {
vl.c +2 -1
@@ -4315,6 +4315,8 @@ int main(int argc, char **argv, char **envp)exit (1 ); } +audio_set_options (); + machine_opts =qemu_get_machine_opts ();if (qemu_opt_foreach (machine_opts, machine_set_property, current_machine,NULL )) {
@@ -4518,7 +4520,6 @@ int main(int argc, char **argv, char **envp)realtime_init (); -audio_set_options ();audio_init ();cpu_synchronize_all_post_init ();
Signature · 1 line
2.5.0
PATCH v2 25/49 audio: add audiodev properties to frontends
In reply to Kővágó, ZoltánFinally add audiodev= options to audio frontends so users can specify which backend to use when multiple backends exist. Not specifying an audiodev= option currently causes the first audiodev to be used, this is fixed in the next commit.
Example usage: -audiodev pa,id=foo -device AC97,audiodev=foo
--- audio/audio.h | 3 +++ hw/audio/ac97.c | 1 + hw/audio/adlib.c | 1 + hw/audio/cs4231a.c | 1 + hw/audio/es1370.c | 7 ++++- hw/audio/gus.c | 1 + hw/audio/hda-codec.c | 1 + hw/audio/milkymist-ac97.c | 6 +++++ hw/audio/pcspk.c | 1 + hw/audio/pl041.c | 1 + hw/audio/sb16.c | 1 + hw/audio/wm8750.c | 6 +++++ hw/core/qdev-properties-system.c | 57 ++++++++++++++++++++++++++++++++++++++++ hw/usb/dev-audio.c | 1 + include/hw/qdev-properties.h | 3 +++ 15 files changed, 90 insertions(+), 1 deletion(-)
audio/audio.h +3 -0
@@ -177,4 +177,7 @@ void audio_legacy_help(void);AudioState *audio_state_by_name (const char *name);const char *audio_get_id (QEMUSoundCard *card); +#define DEFINE_AUDIO_PROPERTIES (_s, _f) \ + DEFINE_PROP_AUDIODEV("audiodev", _s, _f) +#endif /* audio.h */
hw/audio/ac97.c +1 -0
@@ -1393,6 +1393,7 @@ static int ac97_init (PCIBus *bus) }static Property ac97_properties[] = { +DEFINE_AUDIO_PROPERTIES (AC97LinkState, card),DEFINE_PROP_UINT32 ("use_broken_id" , AC97LinkState, use_broken_id,0 ),DEFINE_PROP_END_OF_LIST (), };
hw/audio/adlib.c +1 -0
@@ -352,6 +352,7 @@ static void adlib_realizefn (DeviceState *dev, Error **errp) }static Property adlib_properties[] = { +DEFINE_AUDIO_PROPERTIES (AdlibState, card),DEFINE_PROP_UINT32 ("iobase" , AdlibState, port,0x220 ),DEFINE_PROP_UINT32 ("freq" , AdlibState, freq,44100 ),DEFINE_PROP_END_OF_LIST (),
hw/audio/cs4231a.c +1 -0
@@ -672,6 +672,7 @@ static int cs4231a_init (ISABus *bus) }static Property cs4231a_properties[] = { +DEFINE_AUDIO_PROPERTIES (CSState, card),DEFINE_PROP_UINT32 ("iobase" , CSState, port,0x534 ),DEFINE_PROP_UINT32 ("irq" , CSState, irq,9 ),DEFINE_PROP_UINT32 ("dma" , CSState, dma,3 ),
hw/audio/es1370.c +6 -1
@@ -1047,6 +1047,11 @@ static int es1370_init (PCIBus *bus)return 0 ; } +static Property es1370_properties[] = { +DEFINE_AUDIO_PROPERTIES (ES1370State, card), +DEFINE_PROP_END_OF_LIST (), +}; +static void es1370_class_init (ObjectClass *klass,void *data) {DeviceClass *dc =DEVICE_CLASS (klass);
@@ -1061,6 +1066,7 @@ static void es1370_class_init (ObjectClass *klass, void *data)set_bit (DEVICE_CATEGORY_SOUND , dc->categories); dc->desc ="ENSONIQ AudioPCI ES1370" ; dc->vmsd = &vmstate_es1370; + dc->props = es1370_properties; }static const TypeInfo es1370_info = {
@@ -1077,4 +1083,3 @@ static void es1370_register_types (void) }type_init (es1370_register_types) -
hw/audio/gus.c +1 -0
@@ -284,6 +284,7 @@ static int GUS_init (ISABus *bus) }static Property gus_properties[] = { +DEFINE_AUDIO_PROPERTIES (GUSState, card),DEFINE_PROP_UINT32 ("freq" , GUSState, freq,44100 ),DEFINE_PROP_UINT32 ("iobase" , GUSState, port,0x240 ),DEFINE_PROP_UINT32 ("irq" , GUSState, emu.gusirq,7 ),
hw/audio/hda-codec.c +1 -0
@@ -613,6 +613,7 @@ static const VMStateDescription vmstate_hda_audio = { };static Property hda_audio_properties[] = { +DEFINE_AUDIO_PROPERTIES (HDAAudioState, card),DEFINE_PROP_UINT32 ("debug" , HDAAudioState, debug,0 ),DEFINE_PROP_BOOL ("mixer" , HDAAudioState, mixer, true),DEFINE_PROP_END_OF_LIST (),
hw/audio/milkymist-ac97.c +6 -0
@@ -323,6 +323,11 @@ static const VMStateDescription vmstate_milkymist_ac97 = { } }; +static Property milkymist_ac97_properties[] = { +DEFINE_AUDIO_PROPERTIES (MilkymistAC97State, card), +DEFINE_PROP_END_OF_LIST (), +}; +static void milkymist_ac97_class_init (ObjectClass *klass,void *data) {DeviceClass *dc =DEVICE_CLASS (klass);
@@ -331,6 +336,7 @@ static void milkymist_ac97_class_init(ObjectClass *klass, void *data) k->init = milkymist_ac97_init; dc->reset = milkymist_ac97_reset; dc->vmsd = &vmstate_milkymist_ac97; + dc->props = milkymist_ac97_properties; }static const TypeInfo milkymist_ac97_info = {
hw/audio/pcspk.c +1 -0
@@ -181,6 +181,7 @@ static void pcspk_realizefn(DeviceState *dev, Error **errp) }static Property pcspk_properties[] = { +DEFINE_AUDIO_PROPERTIES (PCSpkState, card),DEFINE_PROP_UINT32 ("iobase" , PCSpkState, iobase,-1 ),DEFINE_PROP_PTR ("pit" , PCSpkState, pit),DEFINE_PROP_END_OF_LIST (),
hw/audio/pl041.c +1 -0
@@ -616,6 +616,7 @@ static const VMStateDescription vmstate_pl041 = { };static Property pl041_device_properties[] = { +DEFINE_AUDIO_PROPERTIES (PL041State, codec.card),/* Non-compact FIFO depth property */ DEFINE_PROP_UINT32 ("nc_fifo_depth" , PL041State, fifo_depth,DEFAULT_FIFO_DEPTH ),
hw/audio/sb16.c +1 -0
@@ -1391,6 +1391,7 @@ static int SB16_init (ISABus *bus) }static Property sb16_properties[] = { +DEFINE_AUDIO_PROPERTIES (SB16State, card),DEFINE_PROP_UINT32 ("version" , SB16State, ver,0x0405 ),/* 4.5 */ DEFINE_PROP_UINT32 ("iobase" , SB16State, port,0x220 ),DEFINE_PROP_UINT32 ("irq" , SB16State, irq,5 ),
hw/audio/wm8750.c +6 -0
@@ -695,6 +695,11 @@ void wm8750_set_bclk_in(void *opaque, int new_hz)wm8750_clk_update (s,1 ); } +static Property wm8750_properties[] = { +DEFINE_AUDIO_PROPERTIES (WM8750State, card), +DEFINE_PROP_END_OF_LIST (), +}; +static void wm8750_class_init (ObjectClass *klass,void *data) {DeviceClass *dc =DEVICE_CLASS (klass);
@@ -705,6 +710,7 @@ static void wm8750_class_init(ObjectClass *klass, void *data) sc->recv = wm8750_rx; sc->send = wm8750_tx; dc->vmsd = &vmstate_wm8750; + dc->props = wm8750_properties; }static const TypeInfo wm8750_info = {
hw/core/qdev-properties-system.c +57 -0
69 lines not on this page · raw message
hw/usb/dev-audio.c +1 -0
@@ -662,6 +662,7 @@ static const VMStateDescription vmstate_usb_audio = { };static Property usb_audio_properties[] = { +DEFINE_AUDIO_PROPERTIES (USBAudioState, card),DEFINE_PROP_UINT32 ("debug" , USBAudioState, debug,0 ),DEFINE_PROP_UINT32 ("buffer" , USBAudioState, buffer,8 *USBAUDIO_PACKET_SIZE ),
include/hw/qdev-properties.h +3 -0
@@ -26,6 +26,7 @@ extern PropertyInfo qdev_prop_vlan;extern PropertyInfo qdev_prop_pci_devfn;extern PropertyInfo qdev_prop_blocksize;extern PropertyInfo qdev_prop_pci_host_devaddr; +extern PropertyInfo qdev_prop_audiodev;extern PropertyInfo qdev_prop_arraylen;#define DEFINE_PROP (_name, _state, _field, _prop, _type) { \
@@ -163,6 +164,8 @@ extern PropertyInfo qdev_prop_arraylen; DEFINE_PROP_DEFAULT(_n, _s, _f, 0, qdev_prop_blocksize, uint16_t)#define DEFINE_PROP_PCI_HOST_DEVADDR (_n, _s, _f) \ DEFINE_PROP(_n, _s, _f, qdev_prop_pci_host_devaddr, PCIHostDeviceAddress) +#define DEFINE_PROP_AUDIODEV (_n, _s, _f) \ + DEFINE_PROP(_n, _s, _f, qdev_prop_audiodev, QEMUSoundCard)#define DEFINE_PROP_END_OF_LIST () \ {}
Signature · 1 line
2.5.0
PATCH v2 26/49 audio: audiodev= parameters no longer optional when -audiodev present
In reply to Kővágó, Zoltán---
Changes from v1:
* (probably) more clear error messages
audio/audio.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-)
audio/audio.c +14 -5
@@ -69,6 +69,8 @@ const struct mixeng_volume nominal_volume = {#endif }; +static bool legacy_config; +#ifdef AUDIO_IS_FLAWLESS_AND_NO_CHECKS_ARE_REQURIED #error No its not#else
@@ -1318,7 +1320,7 @@ static Audiodev *parse_option(QemuOpts *opts, Error **errp);* initialize a new state with it * if dev == NULL => legacy implicit initialization, return the already created * state or create a new one */ -static AudioState *audio_init (Audiodev *dev) +static AudioState *audio_init (Audiodev *dev,const char *name) {static bool atexit_registered;size_t i;
@@ -1332,9 +1334,13 @@ static AudioState *audio_init(Audiodev *dev)if (dev) { drvname = AudiodevDriver_lookup[dev->kind]; }else if (!QTAILQ_EMPTY (&audio_states)) { -/* todo: chack for -audiodev we have normal audiodev selection support */ +if (!legacy_config) { +dolog ("You must specify an audiodev= for the device %s\n" , name); +exit (1 ); + }return QTAILQ_FIRST (&audio_states); }else { + legacy_config = true;audio_handle_legacy_opts (); list =qemu_find_opts ("audiodev" ); dev =parse_option (QTAILQ_FIRST (&list->head), &error_abort);
@@ -1440,7 +1446,7 @@ static AudioState *audio_init(Audiodev *dev)void AUD_register_card (const char *name,QEMUSoundCard *card) {if (!card->state) { - card->state =audio_init (NULL ); + card->state =audio_init (NULL , name); } card->name =g_strdup (name);
@@ -1466,7 +1472,10 @@ CaptureVoiceOut *AUD_add_capture(struct capture_callback *cb;if (!s) { -/* todo: remove when we have normal audiodev selection support */ +if (!legacy_config) { +dolog ("You must specify audiodev when trying to capture\n" ); + goto err0; + } s =QTAILQ_FIRST (&audio_states); }
@@ -1705,7 +1714,7 @@ static int each_option(void *opaque, QemuOpts *opts, Error **errp)if (!dev) {return -1 ; } -return audio_init (dev) ?0 :-1 ; +return audio_init (dev,NULL ) ?0 :-1 ; }void audio_set_options (void )
Signature · 1 line
2.5.0
PATCH v2 27/49 paaudio: do not create multiple connections to the same server
In reply to Kővágó, Zoltán--- audio/paaudio.c | 297 ++++++++++++++++++++++++++++++++------------------------ 1 file changed, 171 insertions(+), 126 deletions(-)
audio/paaudio.c +171 -126
@@ -9,10 +9,21 @@#include "audio_int.h" #include "audio_pt_int.h" -typedef struct { -Audiodev *dev; +typedef struct PAConnection { +char *server; +int refcount; +QTAILQ_ENTRY (PAConnection) list; +pa_threaded_mainloop *mainloop;pa_context *context; +}PAConnection ; + +static QTAILQ_HEAD(PAConnectionHead, PAConnection) pa_conns = +QTAILQ_HEAD_INITIALIZER (pa_conns); + +typedef struct { +Audiodev *dev; +PAConnection *conn; }paaudio ; typedef struct {
@@ -43,7 +54,7 @@ typedef struct {int samples; } PAVoiceIn; -static void qpa_audio_fini (void *opaque); +static void qpa_conn_fini (PAConnection *c); static void GCC_FMT_ATTR (2, 3) qpa_logerr (int err, const char *fmt, ...) {
@@ -106,11 +117,11 @@ static inline int PA_STREAM_IS_GOOD(pa_stream_state_t x)static int qpa_simple_read (PAVoiceIn *p,void *data,size_t length,int *rerror) { -paaudio *g = p->g; +PAConnection *c = p->g->conn; -pa_threaded_mainloop_lock (g->mainloop); +pa_threaded_mainloop_lock (c->mainloop); -CHECK_DEAD_GOTO (g, p->stream, rerror, unlock_and_fail); +CHECK_DEAD_GOTO (c, p->stream, rerror, unlock_and_fail);while (length >0 ) {size_t l;
@@ -119,11 +130,11 @@ static int qpa_simple_read (PAVoiceIn *p, void *data, size_t length, int *rerrorint r; r =pa_stream_peek (p->stream, &p->read_data, &p->read_length); -CHECK_SUCCESS_GOTO (g, rerror, r ==0 , unlock_and_fail); +CHECK_SUCCESS_GOTO (c, rerror, r ==0 , unlock_and_fail);if (!p->read_data) { -pa_threaded_mainloop_wait (g->mainloop); -CHECK_DEAD_GOTO (g, p->stream, rerror, unlock_and_fail); +pa_threaded_mainloop_wait (c->mainloop); +CHECK_DEAD_GOTO (c, p->stream, rerror, unlock_and_fail); }else { p->read_index =0 ; }
@@ -146,53 +157,53 @@ static int qpa_simple_read (PAVoiceIn *p, void *data, size_t length, int *rerror p->read_length =0 ; p->read_index =0 ; -CHECK_SUCCESS_GOTO (g, rerror, r ==0 , unlock_and_fail); +CHECK_SUCCESS_GOTO (c, rerror, r ==0 , unlock_and_fail); } } -pa_threaded_mainloop_unlock (g->mainloop); +pa_threaded_mainloop_unlock (c->mainloop);return 0 ; unlock_and_fail: -pa_threaded_mainloop_unlock (g->mainloop); +pa_threaded_mainloop_unlock (c->mainloop);return -1 ; }static int qpa_simple_write (PAVoiceOut *p,const void *data,size_t length,int *rerror) { -paaudio *g = p->g; +PAConnection *c = p->g->conn; -pa_threaded_mainloop_lock (g->mainloop); +pa_threaded_mainloop_lock (c->mainloop); -CHECK_DEAD_GOTO (g, p->stream, rerror, unlock_and_fail); +CHECK_DEAD_GOTO (c, p->stream, rerror, unlock_and_fail);while (length >0 ) {size_t l;int r;while (!(l =pa_stream_writable_size (p->stream))) { -pa_threaded_mainloop_wait (g->mainloop); -CHECK_DEAD_GOTO (g, p->stream, rerror, unlock_and_fail); +pa_threaded_mainloop_wait (c->mainloop); +CHECK_DEAD_GOTO (c, p->stream, rerror, unlock_and_fail); } -CHECK_SUCCESS_GOTO (g, rerror, l != (size_t )-1 , unlock_and_fail); +CHECK_SUCCESS_GOTO (c, rerror, l != (size_t )-1 , unlock_and_fail);if (l > length) { l = length; } r =pa_stream_write (p->stream, data, l,NULL ,0LL ,PA_SEEK_RELATIVE ); -CHECK_SUCCESS_GOTO (g, rerror, r >=0 , unlock_and_fail); +CHECK_SUCCESS_GOTO (c, rerror, r >=0 , unlock_and_fail); data = (const uint8_t *) data + l; length -= l; } -pa_threaded_mainloop_unlock (g->mainloop); +pa_threaded_mainloop_unlock (c->mainloop);return 0 ; unlock_and_fail: -pa_threaded_mainloop_unlock (g->mainloop); +pa_threaded_mainloop_unlock (c->mainloop);return -1 ; }
@@ -430,13 +441,13 @@ static AudioFormat pa_to_audfmt (pa_sample_format_t fmt, int *endianness)static void context_state_cb (pa_context *c,void *userdata) { -paaudio *g = userdata; +PAConnection *conn = userdata;switch (pa_context_get_state (c)) {case PA_CONTEXT_READY :case PA_CONTEXT_TERMINATED :case PA_CONTEXT_FAILED : -pa_threaded_mainloop_signal (g->mainloop,0 ); +pa_threaded_mainloop_signal (conn->mainloop,0 );break ;case PA_CONTEXT_UNCONNECTED :
@@ -449,14 +460,14 @@ static void context_state_cb (pa_context *c, void *userdata)static void stream_state_cb (pa_stream *s,void * userdata) { -paaudio *g = userdata; +PAConnection *c = userdata;switch (pa_stream_get_state (s)) {case PA_STREAM_READY :case PA_STREAM_FAILED :case PA_STREAM_TERMINATED : -pa_threaded_mainloop_signal (g->mainloop,0 ); +pa_threaded_mainloop_signal (c->mainloop,0 );break ;case PA_STREAM_UNCONNECTED :
@@ -467,13 +478,13 @@ static void stream_state_cb (pa_stream *s, void * userdata)static void stream_request_cb (pa_stream *s,size_t length,void *userdata) { -paaudio *g = userdata; +PAConnection *c = userdata; -pa_threaded_mainloop_signal (g->mainloop,0 ); +pa_threaded_mainloop_signal (c->mainloop,0 ); } static pa_stream *qpa_simple_new ( - paaudio *g, + PAConnection *c, const char *name, pa_stream_direction_t dir, const char *dev,
@@ -484,50 +495,48 @@ static pa_stream *qpa_simple_new ( {int r;pa_stream *stream; +pa_stream_flags_t flags; -pa_threaded_mainloop_lock (g->mainloop); +pa_threaded_mainloop_lock (c->mainloop); - stream =pa_stream_new (g->context, name, ss, map); + stream =pa_stream_new (c->context, name, ss, map);if (!stream) { goto fail; } -pa_stream_set_state_callback (stream, stream_state_cb, g); -pa_stream_set_read_callback (stream, stream_request_cb, g); -pa_stream_set_write_callback (stream, stream_request_cb, g); +pa_stream_set_state_callback (stream, stream_state_cb, c); +pa_stream_set_read_callback (stream, stream_request_cb, c); +pa_stream_set_write_callback (stream, stream_request_cb, c); + + flags = + PA_STREAM_INTERPOLATE_TIMING +#ifdef PA_STREAM_ADJUST_LATENCY + |PA_STREAM_ADJUST_LATENCY +#endif + |PA_STREAM_AUTO_TIMING_UPDATE ;if (dir ==PA_STREAM_PLAYBACK ) { - r =pa_stream_connect_playback (stream, dev, attr, -PA_STREAM_INTERPOLATE_TIMING -#ifdef PA_STREAM_ADJUST_LATENCY - |PA_STREAM_ADJUST_LATENCY -#endif - |PA_STREAM_AUTO_TIMING_UPDATE ,NULL ,NULL ); + r =pa_stream_connect_playback (stream, dev, attr, flags,NULL ,NULL ); }else { - r =pa_stream_connect_record (stream, dev, attr, -PA_STREAM_INTERPOLATE_TIMING -#ifdef PA_STREAM_ADJUST_LATENCY - |PA_STREAM_ADJUST_LATENCY -#endif - |PA_STREAM_AUTO_TIMING_UPDATE ); + r =pa_stream_connect_record (stream, dev, attr, flags); }if (r <0 ) { goto fail; } -pa_threaded_mainloop_unlock (g->mainloop); +pa_threaded_mainloop_unlock (c->mainloop);return stream; fail: -pa_threaded_mainloop_unlock (g->mainloop); +pa_threaded_mainloop_unlock (c->mainloop);if (stream) {pa_stream_unref (stream); } - *rerror =pa_context_errno (g->context); + *rerror =pa_context_errno (c->context);return NULL ; }
@@ -543,6 +552,7 @@ static int qpa_init_out(HWVoiceOut *hw, struct audsettings *as,paaudio *g = pa->g = drv_opaque;AudiodevPaOptions *popts = g->dev->pa;AudiodevPaPerDirectionOptions *ppdo = popts->sink; +PAConnection *c = g->conn; ss.format =audfmt_to_pa (as->fmt, as->endianness); ss.channels = as->nchannels;
@@ -560,7 +570,7 @@ static int qpa_init_out(HWVoiceOut *hw, struct audsettings *as, obt_as.fmt =pa_to_audfmt (ss.format, &obt_as.endianness); pa->stream = qpa_simple_new ( - g, + c, "qemu", PA_STREAM_PLAYBACK, ppdo->has_name ? ppdo->name : NULL,
@@ -612,6 +622,7 @@ static int qpa_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque)paaudio *g = pa->g = drv_opaque;AudiodevPaOptions *popts = g->dev->pa;AudiodevPaPerDirectionOptions *ppdo = popts->source; +PAConnection *c = g->conn; ss.format =audfmt_to_pa (as->fmt, as->endianness); ss.channels = as->nchannels;
@@ -620,7 +631,7 @@ static int qpa_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque) obt_as.fmt =pa_to_audfmt (ss.format, &obt_as.endianness); pa->stream = qpa_simple_new ( - g, + c, "qemu", PA_STREAM_RECORD, ppdo->has_name ? ppdo->name : NULL,
@@ -708,7 +719,7 @@ static int qpa_ctl_out (HWVoiceOut *hw, int cmd, ...)PAVoiceOut *pa = (PAVoiceOut *) hw;pa_operation *op;pa_cvolume v; -paaudio *g = pa->g; +PAConnection *c = pa->g->conn;#ifdef PA_CHECK_VERSION /* macro is present in 0.9.16+ */ pa_cvolume_init (&v);/* function is present in 0.9.13+ */
@@ -728,28 +739,28 @@ static int qpa_ctl_out (HWVoiceOut *hw, int cmd, ...) v.values[0 ] = ((PA_VOLUME_NORM -PA_VOLUME_MUTED ) * sw->vol.l) /UINT32_MAX ; v.values[1 ] = ((PA_VOLUME_NORM -PA_VOLUME_MUTED ) * sw->vol.r) /UINT32_MAX ; -pa_threaded_mainloop_lock (g->mainloop); +pa_threaded_mainloop_lock (c->mainloop); - op =pa_context_set_sink_input_volume (g->context, + op =pa_context_set_sink_input_volume (c->context,pa_stream_get_index (pa->stream), &v,NULL ,NULL );if (!op) -qpa_logerr (pa_context_errno (g->context), +qpa_logerr (pa_context_errno (c->context),"set_sink_input_volume() failed\n" );else pa_operation_unref (op); - op =pa_context_set_sink_input_mute (g->context, + op =pa_context_set_sink_input_mute (c->context,pa_stream_get_index (pa->stream), sw->vol.mute,NULL ,NULL );if (!op) { -qpa_logerr (pa_context_errno (g->context), +qpa_logerr (pa_context_errno (c->context),"set_sink_input_mute() failed\n" ); }else {pa_operation_unref (op); } -pa_threaded_mainloop_unlock (g->mainloop); +pa_threaded_mainloop_unlock (c->mainloop); } }return 0 ;
@@ -760,7 +771,7 @@ static int qpa_ctl_in (HWVoiceIn *hw, int cmd, ...)PAVoiceIn *pa = (PAVoiceIn *) hw;pa_operation *op;pa_cvolume v; -paaudio *g = pa->g; +PAConnection *c = pa->g->conn;#ifdef PA_CHECK_VERSION pa_cvolume_init (&v);
@@ -780,123 +791,157 @@ static int qpa_ctl_in (HWVoiceIn *hw, int cmd, ...) v.values[0 ] = ((PA_VOLUME_NORM -PA_VOLUME_MUTED ) * sw->vol.l) /UINT32_MAX ; v.values[1 ] = ((PA_VOLUME_NORM -PA_VOLUME_MUTED ) * sw->vol.r) /UINT32_MAX ; -pa_threaded_mainloop_lock (g->mainloop); +pa_threaded_mainloop_lock (c->mainloop);/* FIXME: use the upcoming "set_source_output_{volume,mute}" */ - op =pa_context_set_source_volume_by_index (g->context, + op =pa_context_set_source_volume_by_index (c->context,pa_stream_get_device_index (pa->stream), &v,NULL ,NULL );if (!op) { -qpa_logerr (pa_context_errno (g->context), +qpa_logerr (pa_context_errno (c->context),"set_source_volume() failed\n" ); }else {pa_operation_unref (op); } - op =pa_context_set_source_mute_by_index (g->context, + op =pa_context_set_source_mute_by_index (c->context,pa_stream_get_index (pa->stream), sw->vol.mute,NULL ,NULL );if (!op) { -qpa_logerr (pa_context_errno (g->context), +qpa_logerr (pa_context_errno (c->context),"set_source_mute() failed\n" ); }else {pa_operation_unref (op); } -pa_threaded_mainloop_unlock (g->mainloop); +pa_threaded_mainloop_unlock (c->mainloop); } }return 0 ; }/* common */ +static void *qpa_conn_init (const char *server) +{ +PAConnection *c =g_malloc0 (sizeof (PAConnection)); +QTAILQ_INSERT_TAIL (&pa_conns, c, list); + + c->mainloop =pa_threaded_mainloop_new (); +if (!c->mainloop) { + goto fail; + } + + c->context =pa_context_new (pa_threaded_mainloop_get_api (c->mainloop), + server); +if (!c->context) { + goto fail; + } + +pa_context_set_state_callback (c->context, context_state_cb, c); + +if (pa_context_connect (c->context, server,0 ,NULL ) <0 ) { +qpa_logerr (pa_context_errno (c->context), +"pa_context_connect() failed\n" ); + goto fail; + } + +pa_threaded_mainloop_lock (c->mainloop); + +if (pa_threaded_mainloop_start (c->mainloop) <0 ) { + goto unlock_and_fail; + } + +for (;;) { +pa_context_state_t state; + + state =pa_context_get_state (c->context); + +if (state ==PA_CONTEXT_READY ) { +break ; + } + +if (!PA_CONTEXT_IS_GOOD (state)) { +qpa_logerr (pa_context_errno (c->context), +"Wrong context state\n" ); + goto unlock_and_fail; + } + +/* Wait until the context is ready */ +pa_threaded_mainloop_wait (c->mainloop); + } + +pa_threaded_mainloop_unlock (c->mainloop); +return c; + +unlock_and_fail: +pa_threaded_mainloop_unlock (c->mainloop); +fail: +AUD_log (AUDIO_CAP ,"Failed to initialize PA context" ); +qpa_conn_fini (c); +return NULL ; +} +static void *qpa_audio_init (Audiodev *dev) {paaudio *g;AudiodevPaOptions *popts;const char *server; +PAConnection *c;assert (dev->kind ==AUDIODEV_DRIVER_PA ); - g =g_malloc (sizeof (paaudio)); + g =g_malloc0 (sizeof (paaudio)); popts = dev->pa; server = popts->has_server ? popts->server :NULL ; g->dev = dev; - g->mainloop =NULL ; - g->context =NULL ; - g->mainloop =pa_threaded_mainloop_new (); -if (!g->mainloop) { - goto fail; - } - - g->context =pa_context_new (pa_threaded_mainloop_get_api (g->mainloop), - server); -if (!g->context) { - goto fail; - } - -pa_context_set_state_callback (g->context, context_state_cb, g); - -if (pa_context_connect (g->context, server,0 ,NULL ) <0 ) { -qpa_logerr (pa_context_errno (g->context), -"pa_context_connect() failed\n" ); - goto fail; - } - -pa_threaded_mainloop_lock (g->mainloop); - -if (pa_threaded_mainloop_start (g->mainloop) <0 ) { - goto unlock_and_fail; - } - -for (;;) { -pa_context_state_t state; - - state =pa_context_get_state (g->context); - -if (state ==PA_CONTEXT_READY ) { + QTAILQ_FOREACH(c, &pa_conns, list) { +if (server ==NULL || c->server ==NULL ? + server == c->server : +strcmp (server, c->server) ==0 ) { + g->conn = c;break ; } - -if (!PA_CONTEXT_IS_GOOD (state)) { -qpa_logerr (pa_context_errno (g->context), -"Wrong context state\n" ); - goto unlock_and_fail; - } - -/* Wait until the context is ready */ -pa_threaded_mainloop_wait (g->mainloop); + } +if (!g->conn) { + g->conn =qpa_conn_init (server); + } +if (!g->conn) { +g_free (g); +return NULL ; } -pa_threaded_mainloop_unlock (g->mainloop); - + ++g->conn->refcount;return g; +} -unlock_and_fail: -pa_threaded_mainloop_unlock (g->mainloop); -fail: -AUD_log (AUDIO_CAP ,"Failed to initialize PA context" ); -qpa_audio_fini (g); -return NULL ; +static void qpa_conn_fini (PAConnection *c) +{ +if (c->mainloop) { +pa_threaded_mainloop_stop (c->mainloop); + } + +if (c->context) { +pa_context_disconnect (c->context); +pa_context_unref (c->context); + } + +if (c->mainloop) { +pa_threaded_mainloop_free (c->mainloop); + } + +QTAILQ_REMOVE (&pa_conns, c, list); +g_free (c); }static void qpa_audio_fini (void *opaque) {paaudio *g = opaque; +PAConnection *c = g->conn; -if (g->mainloop) { -pa_threaded_mainloop_stop (g->mainloop); - } - -if (g->context) { -pa_context_disconnect (g->context); -pa_context_unref (g->context); - } - -if (g->mainloop) { -pa_threaded_mainloop_free (g->mainloop); +if (--c->refcount ==0 ) { +qpa_conn_fini (c); }g_free (g);
Signature · 1 line
2.5.0
PATCH v2 28/49 paaudio: do not move stream when sink/source name is specified
In reply to Kővágó, ZoltánUnless we disable stream moving, pulseaudio can easily move the stream on connect, effectively ignoring the source/sink specified by the user.
--- audio/paaudio.c | 5 +++++ 1 file changed, 5 insertions(+)
audio/paaudio.c +5 -0
@@ -515,6 +515,11 @@ static pa_stream *qpa_simple_new (#endif |PA_STREAM_AUTO_TIMING_UPDATE; +if (dev) { +/* don't move the stream if the user specified a sink/source */ + flags |=PA_STREAM_DONT_MOVE ; + } +if (dir ==PA_STREAM_PLAYBACK ) { r =pa_stream_connect_playback (stream, dev, attr, flags,NULL ,NULL ); }else {
Signature · 1 line
2.5.0
PATCH v2 29/49 paaudio: properly disconnect streams in fini_*
In reply to Kővágó, ZoltánCurrently this needs a workaround due to bug #74624 in pulseaudio.
--- audio/paaudio.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-)
audio/paaudio.c +21 -2
@@ -679,6 +679,25 @@ static int qpa_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque)return -1 ; } +static void qpa_simple_disconnect (PAConnection *c,pa_stream *stream) +{ +int err; + +pa_threaded_mainloop_lock (c->mainloop); +/* wait until actually connects. workaround pa bug #74624 +* https://bugs.freedesktop.org/show_bug.cgi?id=74624 */ +while (pa_stream_get_state (stream) ==PA_STREAM_CREATING ) { +pa_threaded_mainloop_wait (c->mainloop); + } + + err =pa_stream_disconnect (stream); +if (err !=0 ) { +dolog ("Failed to dissconnect! err=%d\n" , err); + } +pa_stream_unref (stream); +pa_threaded_mainloop_unlock (c->mainloop); +} +static void qpa_fini_out (HWVoiceOut *hw) {void *ret;
@@ -690,7 +709,7 @@ static void qpa_fini_out (HWVoiceOut *hw)audio_pt_join (&pa->pt, &ret,AUDIO_FUNC );if (pa->stream) { -pa_stream_unref (pa->stream); +qpa_simple_disconnect (pa->g->conn, pa->stream); pa->stream =NULL ; }
@@ -710,7 +729,7 @@ static void qpa_fini_in (HWVoiceIn *hw)audio_pt_join (&pa->pt, &ret,AUDIO_FUNC );if (pa->stream) { -pa_stream_unref (pa->stream); +qpa_simple_disconnect (pa->g->conn, pa->stream); pa->stream =NULL ; }
Signature · 1 line
2.5.0
PATCH v2 30/49 audio: remove audio_MIN, audio_MAX
In reply to Kővágó, ZoltánThere's already a MIN and MAX macro in include/qemu/osdep.h, use them instead.
---
Changes from v1:
* removed audio_MIN, audio_MAX macros
audio/alsaaudio.c | 6 +++--- audio/audio.c | 20 ++++++++++---------- audio/audio.h | 17 ----------------- audio/coreaudio.c | 2 +- audio/dsoundaudio.c | 2 +- audio/noaudio.c | 10 +++++----- audio/ossaudio.c | 6 +++--- audio/paaudio.c | 12 ++++++------ audio/sdlaudio.c | 6 +++--- audio/spiceaudio.c | 10 +++++----- audio/wavaudio.c | 4 ++-- hw/audio/ac97.c | 10 +++++----- hw/audio/adlib.c | 4 ++-- hw/audio/cs4231a.c | 4 ++-- hw/audio/es1370.c | 6 +++--- hw/audio/gus.c | 6 +++--- hw/audio/milkymist-ac97.c | 8 ++++---- hw/audio/pcspk.c | 2 +- hw/audio/sb16.c | 2 +- hw/audio/wm8750.c | 4 ++-- 20 files changed, 62 insertions(+), 79 deletions(-)
audio/alsaaudio.c +3 -3
@@ -643,7 +643,7 @@ static void alsa_write_pending (ALSAVoiceOut *alsa)while (alsa->pending) {int left_till_end_samples = hw->samples - alsa->wpos; -int len =audio_MIN (alsa->pending, left_till_end_samples); +int len =MIN (alsa->pending, left_till_end_samples);char *src =advance (alsa->pcm_buf, alsa->wpos << hw->info.shift);while (len) {
@@ -706,7 +706,7 @@ static int alsa_run_out (HWVoiceOut *hw, int live)return 0 ; } - decr =audio_MIN (live, avail); + decr =MIN (live, avail); decr =audio_pcm_hw_clip_out (hw, alsa->pcm_buf, decr, alsa->pending); alsa->pending += decr;alsa_write_pending (alsa);
@@ -924,7 +924,7 @@ static int alsa_run_in (HWVoiceIn *hw) } } - decr =audio_MIN (dead, avail); + decr =MIN (dead, avail);if (!decr) {return 0 ; }
audio/audio.c +10 -10
@@ -506,7 +506,7 @@ static int audio_pcm_hw_find_min_in (HWVoiceIn *hw)for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {if (sw->active) { - m =audio_MIN (m, sw->total_hw_samples_acquired); + m =MIN (m, sw->total_hw_samples_acquired); } }return m;
@@ -526,14 +526,14 @@ int audio_pcm_hw_clip_out (HWVoiceOut *hw, void *pcm_buf, int live, int pending) { int left = hw->samples - pending; -int len =audio_MIN (left, live); +int len =MIN (left, live);int clipped =0 ;while (len) {struct st_sample *src = hw->mix_buf + hw->rpos;uint8_t *dst =advance (pcm_buf, hw->rpos << hw->info.shift);int samples_till_end_of_buf = hw->samples - hw->rpos; -int samples_to_clip =audio_MIN (len, samples_till_end_of_buf); +int samples_to_clip =MIN (len, samples_till_end_of_buf); hw->clip (dst, src, samples_to_clip);
@@ -587,7 +587,7 @@ int audio_pcm_sw_read (SWVoiceIn *sw, void *buf, int size) } swlim = (live * sw->ratio) >>32 ; - swlim =audio_MIN (swlim, samples); + swlim =MIN (swlim, samples);while (swlim) { src = hw->conv_buf + rpos;
@@ -635,7 +635,7 @@ static int audio_pcm_hw_find_min_out (HWVoiceOut *hw, int *nb_livep)for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {if (sw->active || !sw->empty) { - m =audio_MIN (m, sw->total_hw_samples_mixed); + m =MIN (m, sw->total_hw_samples_mixed); nb_live +=1 ; } }
@@ -698,7 +698,7 @@ int audio_pcm_sw_write (SWVoiceOut *sw, void *buf, int size) dead = hwsamples - live; swlim = ((int64_t ) dead <<32 ) / sw->ratio; - swlim =audio_MIN (swlim, samples); + swlim =MIN (swlim, samples);if (swlim) { sw->conv (sw->buf, buf, swlim);
@@ -710,7 +710,7 @@ int audio_pcm_sw_write (SWVoiceOut *sw, void *buf, int size)while (swlim) { dead = hwsamples - live; left = hwsamples - wpos; - blck =audio_MIN (dead, left); + blck =MIN (dead, left);if (!blck) {break ; }
@@ -990,7 +990,7 @@ static void audio_capture_mix_and_clear (HWVoiceOut *hw, int rpos, int samples) n = samples;while (n) {int till_end_of_hw = hw->samples - rpos2; -int to_write =audio_MIN (till_end_of_hw, n); +int to_write =MIN (till_end_of_hw, n);int bytes = to_write << hw->info.shift;int written;
@@ -1008,7 +1008,7 @@ static void audio_capture_mix_and_clear (HWVoiceOut *hw, int rpos, int samples) } } - n =audio_MIN (samples, hw->samples - rpos); + n =MIN (samples, hw->samples - rpos);mixeng_clear (hw->mix_buf + rpos, n);mixeng_clear (hw->mix_buf, samples - n); }
@@ -1160,7 +1160,7 @@ static void audio_run_capture (AudioState *s) rpos = hw->rpos;while (live) {int left = hw->samples - rpos; -int to_capture =audio_MIN (live, left); +int to_capture =MIN (live, left);struct st_sample *src;struct capture_callback *cb;
audio/audio.h +0 -17
@@ -150,23 +150,6 @@ static inline void *advance (void *p, int incr)return (d + incr); } -#ifdef __GNUC__ -#define audio_MIN (a, b) ( __extension__ ({ \ - __typeof (a) ta = a; \ - __typeof (b) tb = b; \ - ((ta)>(tb)?(tb):(ta)); \ -})) - -#define audio_MAX (a, b) ( __extension__ ({ \ - __typeof (a) ta = a; \ - __typeof (b) tb = b; \ - ((ta)<(tb)?(tb):(ta)); \ -})) -#else -#define audio_MIN (a, b) ((a)>(b)?(b):(a)) -#define audio_MAX (a, b) ((a)<(b)?(b):(a)) -#endif -int wav_start_capture (AudioState *state,CaptureState *s,const char *path,int freq,int bits,int nchannels);
audio/coreaudio.c +1 -1
@@ -197,7 +197,7 @@ static int coreaudio_run_out (HWVoiceOut *hw, int live) core->live); } - decr =audio_MIN (core->decr, live); + decr =MIN (core->decr, live); core->decr -= decr; core->live = live - decr;
audio/dsoundaudio.c +1 -1
@@ -706,7 +706,7 @@ static int dsound_run_in (HWVoiceIn *hw)if (!len) {return 0 ; } - len =audio_MIN (len, dead); + len =MIN (len, dead); err = dsound_lock_in ( dscb,
audio/noaudio.c +5 -5
@@ -49,11 +49,11 @@ static int no_run_out (HWVoiceOut *hw, int live) now =qemu_clock_get_ns (QEMU_CLOCK_VIRTUAL ); ticks = now - no->old_ticks; bytes =muldiv64 (ticks, hw->info.bytes_per_second,get_ticks_per_sec ()); - bytes =audio_MIN (bytes,INT_MAX ); + bytes =MIN (bytes,INT_MAX ); samples = bytes >> hw->info.shift; no->old_ticks = now; - decr =audio_MIN (live, samples); + decr =MIN (live, samples); hw->rpos = (hw->rpos + decr) % hw->samples;return decr; }
@@ -108,9 +108,9 @@ static int no_run_in (HWVoiceIn *hw)muldiv64 (ticks, hw->info.bytes_per_second,get_ticks_per_sec ()); no->old_ticks = now; - bytes =audio_MIN (bytes,INT_MAX ); + bytes =MIN (bytes,INT_MAX ); samples = bytes >> hw->info.shift; - samples =audio_MIN (samples, dead); + samples =MIN (samples, dead); }return samples; }
@@ -121,7 +121,7 @@ static int no_read (SWVoiceIn *sw, void *buf, int size)* useless resampling/mixing */ int samples = size >> sw->info.shift;int total = sw->hw->total_samples_captured - sw->total_hw_samples_acquired; -int to_clear =audio_MIN (samples, total); +int to_clear =MIN (samples, total); sw->total_hw_samples_acquired += total;audio_pcm_info_clear_buf (&sw->info, buf, to_clear);return to_clear << sw->info.shift;
audio/ossaudio.c +3 -3
@@ -390,7 +390,7 @@ static void oss_write_pending (OSSVoiceOut *oss)int samples_written;ssize_t bytes_written;int samples_till_end = hw->samples - oss->wpos; -int samples_to_write =audio_MIN (oss->pending, samples_till_end); +int samples_to_write =MIN (oss->pending, samples_till_end);int bytes_to_write = samples_to_write << hw->info.shift;void *pcm =advance (oss->pcm_buf, oss->wpos << hw->info.shift);
@@ -439,7 +439,7 @@ static int oss_run_out (HWVoiceOut *hw, int live) pos = hw->rpos << hw->info.shift; bytes =audio_ring_dist (cntinfo.ptr, pos, bufsize); - decr =audio_MIN (bytes >> hw->info.shift, live); + decr =MIN (bytes >> hw->info.shift, live); }else { err =ioctl (oss->fd,SNDCTL_DSP_GETOSPACE , &abinfo);
@@ -458,7 +458,7 @@ static int oss_run_out (HWVoiceOut *hw, int live)return 0 ; } - decr =audio_MIN (abinfo.bytes >> hw->info.shift, live); + decr =MIN (abinfo.bytes >> hw->info.shift, live);if (!decr) {return 0 ; }
audio/paaudio.c +6 -6
@@ -233,7 +233,7 @@ static void *qpa_thread_out (void *arg) } } - decr = to_mix =audio_MIN (pa->live, pa->samples >>2 ); + decr = to_mix =MIN (pa->live, pa->samples >>2 ); rpos = pa->rpos;if (audio_pt_unlock (&pa->pt,AUDIO_FUNC )) {
@@ -242,7 +242,7 @@ static void *qpa_thread_out (void *arg)while (to_mix) {int error; -int chunk =audio_MIN (to_mix, hw->samples - rpos); +int chunk =MIN (to_mix, hw->samples - rpos);struct st_sample *src = hw->mix_buf + rpos; hw->clip (pa->pcm_buf, src, chunk);
@@ -280,7 +280,7 @@ static int qpa_run_out (HWVoiceOut *hw, int live)return 0 ; } - decr =audio_MIN (live, pa->decr); + decr =MIN (live, pa->decr); pa->decr -= decr; pa->live = live - decr; hw->rpos = pa->rpos;
@@ -325,7 +325,7 @@ static void *qpa_thread_in (void *arg) } } - incr = to_grab =audio_MIN (pa->dead, pa->samples >>2 ); + incr = to_grab =MIN (pa->dead, pa->samples >>2 ); wpos = pa->wpos;if (audio_pt_unlock (&pa->pt,AUDIO_FUNC )) {
@@ -334,7 +334,7 @@ static void *qpa_thread_in (void *arg)while (to_grab) {int error; -int chunk =audio_MIN (to_grab, hw->samples - wpos); +int chunk =MIN (to_grab, hw->samples - wpos);void *buf =advance (pa->pcm_buf, wpos); if (qpa_simple_read (pa, buf,
@@ -373,7 +373,7 @@ static int qpa_run_in (HWVoiceIn *hw) live =audio_pcm_hw_get_live_in (hw); dead = hw->samples - live; - incr =audio_MIN (dead, pa->incr); + incr =MIN (dead, pa->incr); pa->incr -= incr; pa->dead = dead - incr; hw->wpos = pa->wpos;
audio/sdlaudio.c +3 -3
@@ -260,10 +260,10 @@ static void sdl_callback (void *opaque, Uint8 *buf, int len) }/* dolog ("in callback live=%d\n", live); */ - to_mix =audio_MIN (samples, sdl->live); + to_mix =MIN (samples, sdl->live); decr = to_mix;while (to_mix) { -int chunk =audio_MIN (to_mix, hw->samples - hw->rpos); +int chunk =MIN (to_mix, hw->samples - hw->rpos);struct st_sample *src = hw->mix_buf + hw->rpos;/* dolog ("in callback to_mix %d, chunk %d\n", to_mix, chunk); */
@@ -306,7 +306,7 @@ static int sdl_run_out (HWVoiceOut *hw, int live) sdl->live); } - decr =audio_MIN (sdl->decr, live); + decr =MIN (sdl->decr, live); sdl->decr -= decr; sdl->live = live - decr;
audio/spiceaudio.c +5 -5
@@ -161,20 +161,20 @@ static int line_out_run (HWVoiceOut *hw, int live) } decr =rate_get_samples (&hw->info, &out->rate); - decr =audio_MIN (live, decr); + decr =MIN (live, decr); samples = decr; rpos = hw->rpos;while (samples) {int left_till_end_samples = hw->samples - rpos; -int len =audio_MIN (samples, left_till_end_samples); +int len =MIN (samples, left_till_end_samples);if (!out->frame) {spice_server_playback_get_buffer (&out->sin, &out->frame, &out->fsize); out->fpos = out->frame; }if (out->frame) { - len =audio_MIN (len, out->fsize); + len =MIN (len, out->fsize); hw->clip (out->fpos, hw->mix_buf + rpos, len); out->fsize -= len; out->fpos += len;
@@ -292,7 +292,7 @@ static int line_in_run (HWVoiceIn *hw) } delta_samp =rate_get_samples (&hw->info, &in->rate); - num_samples =audio_MIN (num_samples, delta_samp); + num_samples =MIN (num_samples, delta_samp); ready =spice_server_record_get_samples (&in->sin, in->samples, num_samples); samples = in->samples;
@@ -302,7 +302,7 @@ static int line_in_run (HWVoiceIn *hw) ready =LINE_IN_SAMPLES ; } - num_samples =audio_MIN (ready, num_samples); + num_samples =MIN (ready, num_samples);if (hw->wpos + num_samples > hw->samples) { len[0 ] = hw->samples - hw->wpos;
audio/wavaudio.c +2 -2
@@ -56,12 +56,12 @@ static int wav_run_out (HWVoiceOut *hw, int live) } wav->old_ticks = now; - decr =audio_MIN (live, samples); + decr =MIN (live, samples); samples = decr; rpos = hw->rpos;while (samples) {int left_till_end_samples = hw->samples - rpos; -int convert_samples =audio_MIN (samples, left_till_end_samples); +int convert_samples =MIN (samples, left_till_end_samples); src = hw->mix_buf + rpos; dst =advance (wav->pcm_buf, rpos << hw->info.shift);
hw/audio/ac97.c +5 -5
@@ -958,7 +958,7 @@ static int write_audio (AC97LinkState *s, AC97BusMasterRegs *r,uint32_t temp = r->picb <<1 ;uint32_t written =0 ;int to_copy =0 ; - temp =audio_MIN (temp, max); + temp =MIN (temp, max);if (!temp) { *stop =1 ;
@@ -967,7 +967,7 @@ static int write_audio (AC97LinkState *s, AC97BusMasterRegs *r,while (temp) {int copied; - to_copy =audio_MIN (temp,sizeof (tmpbuf)); + to_copy =MIN (temp,sizeof (tmpbuf));pci_dma_read (&s->dev, addr, tmpbuf, to_copy); copied =AUD_write (s->voice_po, tmpbuf, to_copy); dolog ("write_audio max=%x to_copy=%x copied=%x\n",
@@ -1013,7 +1013,7 @@ static void write_bup (AC97LinkState *s, int elapsed) }while (elapsed) { -int temp =audio_MIN (elapsed,sizeof (s->silence)); +int temp =MIN (elapsed,sizeof (s->silence));while (temp) {int copied =AUD_write (s->voice_po, s->silence, temp);if (!copied)
@@ -1034,7 +1034,7 @@ static int read_audio (AC97LinkState *s, AC97BusMasterRegs *r,int to_copy =0 ;SWVoiceIn *voice = (r - s->bm_regs) ==MC_INDEX ? s->voice_mc : s->voice_pi; - temp =audio_MIN (temp, max); + temp =MIN (temp, max);if (!temp) { *stop =1 ;
@@ -1043,7 +1043,7 @@ static int read_audio (AC97LinkState *s, AC97BusMasterRegs *r,while (temp) {int acquired; - to_copy =audio_MIN (temp,sizeof (tmpbuf)); + to_copy =MIN (temp,sizeof (tmpbuf)); acquired =AUD_read (voice, tmpbuf, to_copy);if (!acquired) { *stop =1 ;
hw/audio/adlib.c +2 -2
@@ -223,7 +223,7 @@ static void adlib_callback (void *opaque, int free)return ; } - to_play =audio_MIN (s->left, samples); + to_play =MIN (s->left, samples);while (to_play) { written =write_audio (s, to_play);
@@ -238,7 +238,7 @@ static void adlib_callback (void *opaque, int free) } } - samples =audio_MIN (samples, s->samples - s->pos); + samples =MIN (samples, s->samples - s->pos);if (!samples) {return ; }
hw/audio/cs4231a.c +2 -2
@@ -526,7 +526,7 @@ static int cs_write_audio (CSState *s, int nchan, int dma_pos,int copied;size_t to_copy; - to_copy =audio_MIN (temp, left); + to_copy =MIN (temp, left);if (to_copy >sizeof (tmpbuf)) { to_copy =sizeof (tmpbuf); }
@@ -569,7 +569,7 @@ static int cs_dma_read (void *opaque, int nchan, int dma_pos, int dma_len) till = (s->dregs[Playback_Lower_Base_Count] | (s->dregs[Playback_Upper_Base_Count] <<8 )) << s->shift; till -= s->transferred; - copy =audio_MIN (till, copy); + copy =MIN (till, copy); }if ((copy <=0 ) || (dma_len <=0 )) {
hw/audio/es1370.c +3 -3
@@ -790,7 +790,7 @@ static void es1370_transfer_audio (ES1370State *s, struct chan *d, int loop_sel,int size = d->frame_cnt &0xffff ;int left = ((size - cnt +1 ) <<2 ) + d->leftover;int transferred =0 ; -int temp =audio_MIN (max,audio_MIN (left, csc_bytes)); +int temp =MIN (max,MIN (left, csc_bytes));int index = d - &s->chan[0 ]; addr += (cnt <<2 ) + d->leftover;
@@ -799,7 +799,7 @@ static void es1370_transfer_audio (ES1370State *s, struct chan *d, int loop_sel,while (temp) {int acquired, to_copy; - to_copy =audio_MIN ((size_t ) temp,sizeof (tmpbuf)); + to_copy =MIN ((size_t ) temp,sizeof (tmpbuf)); acquired =AUD_read (s->adc_voice, tmpbuf, to_copy);if (!acquired)break ;
@@ -817,7 +817,7 @@ static void es1370_transfer_audio (ES1370State *s, struct chan *d, int loop_sel,while (temp) {int copied, to_copy; - to_copy =audio_MIN ((size_t ) temp,sizeof (tmpbuf)); + to_copy =MIN ((size_t ) temp,sizeof (tmpbuf));pci_dma_read (&s->dev, addr, tmpbuf, to_copy); copied =AUD_write (voice, tmpbuf, to_copy);if (!copied)
hw/audio/gus.c +3 -3
@@ -115,7 +115,7 @@ static void GUS_callback (void *opaque, int free)GUSState *s = opaque; samples = free >> s->shift; - to_play =audio_MIN (samples, s->left); + to_play =MIN (samples, s->left);while (to_play) {int written =write_audio (s, to_play);
@@ -130,7 +130,7 @@ static void GUS_callback (void *opaque, int free) net += written; } - samples =audio_MIN (samples, s->samples); + samples =MIN (samples, s->samples);if (samples) {gus_mixvoices (&s->emu, s->freq, samples, s->mixbuf);
@@ -188,7 +188,7 @@ static int GUS_read_DMA (void *opaque, int nchan, int dma_pos, int dma_len)ldebug ("read DMA %#x %d\n" , dma_pos, dma_len); mode =DMA_get_channel_mode (s->emu.gusdma);while (left) { -int to_copy =audio_MIN ((size_t ) left,sizeof (tmpbuf)); +int to_copy =MIN ((size_t ) left,sizeof (tmpbuf));int copied;ldebug ("left=%d to_copy=%d pos=%d\n" , left, to_copy, pos);
hw/audio/milkymist-ac97.c +4 -4
@@ -182,7 +182,7 @@ static void ac97_in_cb(void *opaque, int avail_b)MilkymistAC97State *s = opaque;uint8_t buf[4096 ];uint32_t remaining = s->regs[R_U_REMAINING ]; -int temp =audio_MIN (remaining, avail_b); +int temp =MIN (remaining, avail_b);uint32_t addr = s->regs[R_U_ADDR ];int transferred =0 ;
@@ -196,7 +196,7 @@ static void ac97_in_cb(void *opaque, int avail_b)while (temp) {int acquired, to_copy; - to_copy =audio_MIN (temp,sizeof (buf)); + to_copy =MIN (temp,sizeof (buf)); acquired =AUD_read (s->voice_in, buf, to_copy);if (!acquired) {break ;
@@ -225,7 +225,7 @@ static void ac97_out_cb(void *opaque, int free_b)MilkymistAC97State *s = opaque;uint8_t buf[4096 ];uint32_t remaining = s->regs[R_D_REMAINING ]; -int temp =audio_MIN (remaining, free_b); +int temp =MIN (remaining, free_b);uint32_t addr = s->regs[R_D_ADDR ];int transferred =0 ;
@@ -239,7 +239,7 @@ static void ac97_out_cb(void *opaque, int free_b)while (temp) {int copied, to_copy; - to_copy =audio_MIN (temp,sizeof (buf)); + to_copy =MIN (temp,sizeof (buf));cpu_physical_memory_read (addr, buf, to_copy); copied =AUD_write (s->voice_out, buf, to_copy);if (!copied) {
hw/audio/pcspk.c +1 -1
@@ -100,7 +100,7 @@ static void pcspk_callback(void *opaque, int free) }while (free >0 ) { - n =audio_MIN (s->samples - s->play_pos, (unsigned int )free); + n =MIN (s->samples - s->play_pos, (unsigned int )free); n =AUD_write (s->voice, &s->sample_buf[s->play_pos], n);if (!n)break ;
hw/audio/sb16.c +1 -1
@@ -1152,7 +1152,7 @@ static int write_audio (SB16State *s, int nchan, int dma_pos,int copied;size_t to_copy; - to_copy =audio_MIN (temp, left); + to_copy =MIN (temp, left);if (to_copy >sizeof (tmpbuf)) { to_copy =sizeof (tmpbuf); }
hw/audio/wm8750.c +2 -2
@@ -68,7 +68,7 @@ static inline void wm8750_in_load(WM8750State *s) {if (s->idx_in + s->req_in <=sizeof (s->data_in))return ; - s->idx_in =audio_MAX (0 , (int )sizeof (s->data_in) - s->req_in); + s->idx_in =MAX (0 , (int )sizeof (s->data_in) - s->req_in);AUD_read (*s->in[0 ], s->data_in + s->idx_in,sizeof (s->data_in) - s->idx_in); }
@@ -99,7 +99,7 @@ static void wm8750_audio_out_cb(void *opaque, int free_b)wm8750_out_flush (s); }else s->req_out = free_b - s->idx_out; - + s->data_req (s->opaque, s->req_out >>2 , s->req_in >>2 ); }
Signature · 1 line
2.5.0
PATCH v2 31/49 audio: do not run each backend in audio_run
In reply to Kővágó, Zoltánaudio_run is called manually by alsa and oss backends when polling. In this case only the requesting backend should be run, not all of them.
--- audio/alsaaudio.c | 7 +++++-- audio/audio.c | 17 +++++++---------- audio/audio_int.h | 2 +- audio/ossaudio.c | 12 ++++++------ 4 files changed, 19 insertions(+), 19 deletions(-)
audio/alsaaudio.c +5 -2
@@ -40,6 +40,7 @@ struct pollhlp {struct pollfd *pfds;int count;int mask; +AudioState *s; }; typedef struct ALSAVoiceOut {
@@ -200,11 +201,11 @@ static void alsa_poll_handler (void *opaque)break ;case SND_PCM_STATE_PREPARED : -audio_run ("alsa run (prepared)" ); +audio_run (hlp->s,"alsa run (prepared)" );break ;case SND_PCM_STATE_RUNNING : -audio_run ("alsa run (running)" ); +audio_run (hlp->s,"alsa run (running)" );break ;default :
@@ -758,6 +759,7 @@ static int alsa_init_out(HWVoiceOut *hw, struct audsettings *as,return -1 ; } + alsa->pollhlp.s = hw->s; alsa->handle = handle; alsa->dev = dev;return 0 ;
@@ -859,6 +861,7 @@ static int alsa_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque)return -1 ; } + alsa->pollhlp.s = hw->s; alsa->handle = handle; alsa->dev = dev;return 0 ;
audio/audio.c +7 -10
@@ -790,8 +790,9 @@ static void audio_reset_timer (AudioState *s)static void audio_timer (void *opaque) { -audio_run ("timer" ); -audio_reset_timer (opaque); +AudioState *s = opaque; +audio_run (s,"timer" ); +audio_reset_timer (s); }/*
@@ -1194,15 +1195,11 @@ static void audio_run_capture (AudioState *s) } } -void audio_run (const char *msg) +void audio_run (AudioState *s,const char *msg) { -AudioState *s; - - QTAILQ_FOREACH(s, &audio_states, list) { -audio_run_out (s); -audio_run_in (s); -audio_run_capture (s); - } +audio_run_out (s); +audio_run_in (s); +audio_run_capture (s);#ifdef DEBUG_POLL {
audio/audio_int.h +1 -1
@@ -220,7 +220,7 @@ int audio_pcm_hw_clip_out (HWVoiceOut *hw, void *pcm_buf,int audio_bug (const char *funcname,int cond);void *audio_calloc (const char *funcname,int nmemb,size_t size); -void audio_run (const char *msg); +void audio_run (AudioState *s,const char *msg);#define VOICE_ENABLE 1#define VOICE_DISABLE 2
audio/ossaudio.c +6 -6
@@ -112,28 +112,28 @@ static void oss_anal_close (int *fdp)static void oss_helper_poll_out (void *opaque) { - (void ) opaque; -audio_run ("oss_poll_out" ); +AudioState *s = opaque; +audio_run (s,"oss_poll_out" ); }static void oss_helper_poll_in (void *opaque) { - (void ) opaque; -audio_run ("oss_poll_in" ); +AudioState *s = opaque; +audio_run (s,"oss_poll_in" ); }static void oss_poll_out (HWVoiceOut *hw) {OSSVoiceOut *oss = (OSSVoiceOut *) hw; -qemu_set_fd_handler (oss->fd,NULL , oss_helper_poll_out,NULL ); +qemu_set_fd_handler (oss->fd,NULL , oss_helper_poll_out, hw->s); }static void oss_poll_in (HWVoiceIn *hw) {OSSVoiceIn *oss = (OSSVoiceIn *) hw; -qemu_set_fd_handler (oss->fd, oss_helper_poll_in,NULL ,NULL ); +qemu_set_fd_handler (oss->fd, oss_helper_poll_in,NULL , hw->s); }static int oss_write (SWVoiceOut *sw,void *buf,int len)
Signature · 1 line
2.5.0
PATCH v2 32/49 paaudio: fix playback glitches
In reply to Kővágó, ZoltánPulseaudio normally assumes that when the server wants it, the client can generate the audio samples and send it right away. Unfortunately this is not the case with QEMU -- it's up to the emulated system when does it generate the samples. Buffering the samples and sending them from a background thread is just a workaround, that doesn't work too well. Instead enable pa's compatibility support and let pa worry about the details.
--- audio/paaudio.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
audio/paaudio.c +2 -4
@@ -510,10 +510,8 @@ static pa_stream *qpa_simple_new ( flags =PA_STREAM_INTERPOLATE_TIMING -#ifdef PA_STREAM_ADJUST_LATENCY - |PA_STREAM_ADJUST_LATENCY -#endif - |PA_STREAM_AUTO_TIMING_UPDATE ; + |PA_STREAM_AUTO_TIMING_UPDATE + |PA_STREAM_EARLY_REQUESTS ;if (dev) {/* don't move the stream if the user specified a sink/source */
Signature · 1 line
2.5.0
PATCH v2 33/49 audio: remove read and write pcm_ops
In reply to Kővágó, ZoltánThey just called audio_pcm_sw_read/write anyway, so it makes no sense to have them too. (The noaudio's read is the only exception, but it should work with the generic code too.)
--- audio/alsaaudio.c | 12 ------------ audio/audio.c | 14 ++++---------- audio/audio_int.h | 5 ----- audio/coreaudio.c | 6 ------ audio/dsoundaudio.c | 12 ------------ audio/noaudio.c | 19 ------------------- audio/ossaudio.c | 12 ------------ audio/paaudio.c | 12 ------------ audio/sdlaudio.c | 6 ------ audio/spiceaudio.c | 12 ------------ audio/wavaudio.c | 6 ------ 11 files changed, 4 insertions(+), 112 deletions(-)
audio/alsaaudio.c +0 -12
@@ -271,11 +271,6 @@ static int alsa_poll_in (HWVoiceIn *hw)return alsa_poll_helper (alsa->handle, &alsa->pollhlp,POLLIN ); } -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 (AudioFormat fmt,int endianness) {switch (fmt) {
@@ -997,11 +992,6 @@ static int alsa_run_in (HWVoiceIn *hw)return read_samples; } -static int alsa_read (SWVoiceIn *sw,void *buf,int size) -{ -return audio_pcm_sw_read (sw, buf, size); -} -static int alsa_ctl_in (HWVoiceIn *hw,int cmd, ...) {ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;
@@ -1067,13 +1057,11 @@ static struct audio_pcm_ops alsa_pcm_ops = { .init_out = alsa_init_out, .fini_out = alsa_fini_out, .run_out = alsa_run_out, - .write = alsa_write, .ctl_out = alsa_ctl_out, .init_in = alsa_init_in, .fini_in = alsa_fini_in, .run_in = alsa_run_in, - .read = alsa_read, .ctl_in = alsa_ctl_in, };
audio/audio.c +4 -10
@@ -567,7 +567,7 @@ static int audio_pcm_sw_get_rpos_in (SWVoiceIn *sw) } } -int audio_pcm_sw_read (SWVoiceIn *sw,void *buf,int size) +static int audio_pcm_sw_read (SWVoiceIn *sw,void *buf,int size) {HWVoiceIn *hw = sw->hw;int samples, live, ret =0 , swlim, isamp, osamp, rpos, total =0 ;
@@ -669,7 +669,7 @@ static int audio_pcm_hw_get_live_out (HWVoiceOut *hw, int *nb_live)/* * Soft voice (playback) */ -int audio_pcm_sw_write (SWVoiceOut *sw,void *buf,int size) +static int audio_pcm_sw_write (SWVoiceOut *sw,void *buf,int size) {int hwsamples, samples, isamp, osamp, wpos, live, dead, left, swlim, blck;int ret =0 , pos =0 , total =0 ;
@@ -800,8 +800,6 @@ static void audio_timer (void *opaque)*/ int AUD_write (SWVoiceOut *sw,void *buf,int size) { -int bytes; -if (!sw) {/* XXX: Consider options */ return size;
@@ -812,14 +810,11 @@ int AUD_write (SWVoiceOut *sw, void *buf, int size)return 0 ; } - bytes = sw->hw->pcm_ops->write (sw, buf, size); -return bytes; +return audio_pcm_sw_write (sw, buf, size); }int AUD_read (SWVoiceIn *sw,void *buf,int size) { -int bytes; -if (!sw) {/* XXX: Consider options */ return size;
@@ -830,8 +825,7 @@ int AUD_read (SWVoiceIn *sw, void *buf, int size)return 0 ; } - bytes = sw->hw->pcm_ops->read (sw, buf, size); -return bytes; +return audio_pcm_sw_read (sw, buf, size); }int AUD_get_buffer_size_out (SWVoiceOut *sw)
audio/audio_int.h +0 -5
@@ -146,13 +146,11 @@ struct audio_pcm_ops {int (*init_out)(HWVoiceOut *hw,struct audsettings *as,void *drv_opaque);void (*fini_out)(HWVoiceOut *hw);int (*run_out) (HWVoiceOut *hw,int live); -int (*write) (SWVoiceOut *sw,void *buf,int size);int (*ctl_out) (HWVoiceOut *hw,int cmd, ...);int (*init_in) (HWVoiceIn *hw,struct audsettings *as,void *drv_opaque);void (*fini_in) (HWVoiceIn *hw);int (*run_in) (HWVoiceIn *hw); -int (*read) (SWVoiceIn *sw,void *buf,int size);int (*ctl_in) (HWVoiceIn *hw,int cmd, ...); };
@@ -209,11 +207,8 @@ 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); -int audio_pcm_sw_write (SWVoiceOut *sw,void *buf,int len);int audio_pcm_hw_get_live_in (HWVoiceIn *hw); -int audio_pcm_sw_read (SWVoiceIn *sw,void *buf,int len); -int audio_pcm_hw_clip_out (HWVoiceOut *hw,void *pcm_buf,int live,int pending);
audio/coreaudio.c +0 -6
@@ -273,11 +273,6 @@ static OSStatus audioDeviceIOProc(return 0 ; } -static int coreaudio_write (SWVoiceOut *sw,void *buf,int len) -{ -return audio_pcm_sw_write (sw, buf, len); -} -static int coreaudio_init_out (HWVoiceOut *hw,struct audsettings *as,void *drv_opaque) {
@@ -510,7 +505,6 @@ static struct audio_pcm_ops coreaudio_pcm_ops = { .init_out = coreaudio_init_out, .fini_out = coreaudio_fini_out, .run_out = coreaudio_run_out, - .write = coreaudio_write, .ctl_out = coreaudio_ctl_out };
audio/dsoundaudio.c +0 -12
@@ -453,11 +453,6 @@ static int dsound_ctl_out (HWVoiceOut *hw, int cmd, ...)return 0 ; } -static int dsound_write (SWVoiceOut *sw,void *buf,int len) -{ -return audio_pcm_sw_write (sw, buf, len); -} -static int dsound_run_out (HWVoiceOut *hw,int live) {int err;
@@ -644,11 +639,6 @@ static int dsound_ctl_in (HWVoiceIn *hw, int cmd, ...)return 0 ; } -static int dsound_read (SWVoiceIn *sw,void *buf,int len) -{ -return audio_pcm_sw_read (sw, buf, len); -} -static int dsound_run_in (HWVoiceIn *hw) {int err;
@@ -855,13 +845,11 @@ static struct audio_pcm_ops dsound_pcm_ops = { .init_out = dsound_init_out, .fini_out = dsound_fini_out, .run_out = dsound_run_out, - .write = dsound_write, .ctl_out = dsound_ctl_out, .init_in = dsound_init_in, .fini_in = dsound_fini_in, .run_in = dsound_run_in, - .read = dsound_read, .ctl_in = dsound_ctl_in };
audio/noaudio.c +0 -19
@@ -58,11 +58,6 @@ static int no_run_out (HWVoiceOut *hw, int live)return decr; } -static int no_write (SWVoiceOut *sw,void *buf,int len) -{ -return audio_pcm_sw_write (sw, buf, len); -} -static int no_init_out (HWVoiceOut *hw,struct audsettings *as,void *drv_opaque) {audio_pcm_init_info (&hw->info, as);
@@ -115,18 +110,6 @@ static int no_run_in (HWVoiceIn *hw)return samples; } -static int no_read (SWVoiceIn *sw,void *buf,int size) -{ -/* use custom code here instead of audio_pcm_sw_read() to avoid -* useless resampling/mixing */ -int samples = size >> sw->info.shift; -int total = sw->hw->total_samples_captured - sw->total_hw_samples_acquired; -int to_clear =MIN (samples, total); - sw->total_hw_samples_acquired += total; -audio_pcm_info_clear_buf (&sw->info, buf, to_clear); -return to_clear << sw->info.shift; -} -static int no_ctl_in (HWVoiceIn *hw,int cmd, ...) { (void ) hw;
@@ -148,13 +131,11 @@ static struct audio_pcm_ops no_pcm_ops = { .init_out = no_init_out, .fini_out = no_fini_out, .run_out = no_run_out, - .write = no_write, .ctl_out = no_ctl_out, .init_in = no_init_in, .fini_in = no_fini_in, .run_in = no_run_in, - .read = no_read, .ctl_in = no_ctl_in };
audio/ossaudio.c +0 -12
@@ -136,11 +136,6 @@ static void oss_poll_in (HWVoiceIn *hw)qemu_set_fd_handler (oss->fd, oss_helper_poll_in,NULL , hw->s); } -static int oss_write (SWVoiceOut *sw,void *buf,int len) -{ -return audio_pcm_sw_write (sw, buf, len); -} -static int aud_to_ossfmt (AudioFormat fmt,int endianness) {switch (fmt) {
@@ -792,11 +787,6 @@ static int oss_run_in (HWVoiceIn *hw)return read_samples; } -static int oss_read (SWVoiceIn *sw,void *buf,int size) -{ -return audio_pcm_sw_read (sw, buf, size); -} -static int oss_ctl_in (HWVoiceIn *hw,int cmd, ...) {OSSVoiceIn *oss = (OSSVoiceIn *) hw;
@@ -848,13 +838,11 @@ static struct audio_pcm_ops oss_pcm_ops = { .init_out = oss_init_out, .fini_out = oss_fini_out, .run_out = oss_run_out, - .write = oss_write, .ctl_out = oss_ctl_out, .init_in = oss_init_in, .fini_in = oss_fini_in, .run_in = oss_run_in, - .read = oss_read, .ctl_in = oss_ctl_in };
audio/paaudio.c +0 -12
@@ -293,11 +293,6 @@ static int qpa_run_out (HWVoiceOut *hw, int live)return decr; } -static int qpa_write (SWVoiceOut *sw,void *buf,int len) -{ -return audio_pcm_sw_write (sw, buf, len); -} -/* capture */ static void *qpa_thread_in (void *arg) {
@@ -386,11 +381,6 @@ static int qpa_run_in (HWVoiceIn *hw)return incr; } -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 (AudioFormat afmt,int endianness) {int format;
@@ -973,13 +963,11 @@ static struct audio_pcm_ops qpa_pcm_ops = { .init_out = qpa_init_out, .fini_out = qpa_fini_out, .run_out = qpa_run_out, - .write = qpa_write, .ctl_out = qpa_ctl_out, .init_in = qpa_init_in, .fini_in = qpa_fini_in, .run_in = qpa_run_in, - .read = qpa_read, .ctl_in = qpa_ctl_in };
audio/sdlaudio.c +0 -6
@@ -284,11 +284,6 @@ static void sdl_callback (void *opaque, Uint8 *buf, int len)/* dolog ("done len=%d\n", len); */ } -static int sdl_write_out (SWVoiceOut *sw,void *buf,int len) -{ -return audio_pcm_sw_write (sw, buf, len); -} -static int sdl_run_out (HWVoiceOut *hw,int live) {int decr;
@@ -434,7 +429,6 @@ static struct audio_pcm_ops sdl_pcm_ops = { .init_out = sdl_init_out, .fini_out = sdl_fini_out, .run_out = sdl_run_out, - .write = sdl_write_out, .ctl_out = sdl_ctl_out, };
audio/spiceaudio.c +0 -12
@@ -190,11 +190,6 @@ static int line_out_run (HWVoiceOut *hw, int live)return decr; } -static int line_out_write (SWVoiceOut *sw,void *buf,int len) -{ -return audio_pcm_sw_write (sw, buf, len); -} -static int line_out_ctl (HWVoiceOut *hw,int cmd, ...) {SpiceVoiceOut *out =container_of (hw, SpiceVoiceOut, hw);
@@ -323,11 +318,6 @@ static int line_in_run (HWVoiceIn *hw)return num_samples; } -static int line_in_read (SWVoiceIn *sw,void *buf,int size) -{ -return audio_pcm_sw_read (sw, buf, size); -} -static int line_in_ctl (HWVoiceIn *hw,int cmd, ...) {SpiceVoiceIn *in =container_of (hw, SpiceVoiceIn, hw);
@@ -375,13 +365,11 @@ static struct audio_pcm_ops audio_callbacks = { .init_out = line_out_init, .fini_out = line_out_fini, .run_out = line_out_run, - .write = line_out_write, .ctl_out = line_out_ctl, .init_in = line_in_init, .fini_in = line_in_fini, .run_in = line_in_run, - .read = line_in_read, .ctl_in = line_in_ctl, };
audio/wavaudio.c +0 -6
@@ -81,11 +81,6 @@ static int wav_run_out (HWVoiceOut *hw, int live)return decr; } -static int wav_write_out (SWVoiceOut *sw,void *buf,int len) -{ -return audio_pcm_sw_write (sw, buf, len); -} -/* VICE code: Store number as little endian. */ static void le_store (uint8_t *buf,uint32_t val,int len) {
@@ -237,7 +232,6 @@ static struct audio_pcm_ops wav_pcm_ops = { .init_out = wav_init_out, .fini_out = wav_fini_out, .run_out = wav_run_out, - .write = wav_write_out, .ctl_out = wav_ctl_out, };
Signature · 1 line
2.5.0
PATCH v2 34/49 audio: use size_t where makes sense
In reply to Kővágó, Zoltán--- audio/alsaaudio.c | 8 +-- audio/audio.c | 163 ++++++++++++++++++++++++------------------------- audio/audio.h | 4 +- audio/audio_int.h | 22 +++---- audio/audio_template.h | 6 +- audio/mixeng.h | 11 ++-- audio/ossaudio.c | 18 +++--- audio/paaudio.c | 8 +-- audio/rate_template.h | 2 +- audio/sdlaudio.c | 4 +- audio/wavaudio.c | 4 +- 11 files changed, 125 insertions(+), 125 deletions(-)
audio/alsaaudio.c +4 -4
@@ -748,8 +748,8 @@ static int alsa_init_out(HWVoiceOut *hw, struct audsettings *as, alsa->pcm_buf =audio_calloc (AUDIO_FUNC , obt.samples,1 << hw->info.shift);if (!alsa->pcm_buf) { -dolog ("Could not allocate DAC buffer (%d samples, each %d bytes)\n" , - hw->samples,1 << hw->info.shift); +dolog ("Could not allocate DAC buffer (%zu samples, each %d bytes)\n" , + hw->samples,1 << hw->info.shift);alsa_anal_close1 (&handle);return -1 ; }
@@ -850,8 +850,8 @@ static int alsa_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque) alsa->pcm_buf =audio_calloc (AUDIO_FUNC , hw->samples,1 << hw->info.shift);if (!alsa->pcm_buf) { -dolog ("Could not allocate ADC buffer (%d samples, each %d bytes)\n" , - hw->samples,1 << hw->info.shift); +dolog ("Could not allocate ADC buffer (%zu samples, each %d bytes)\n" , + hw->samples,1 << hw->info.shift);alsa_anal_close1 (&handle);return -1 ; }
audio/audio.c +80 -83
389 lines not on this page · raw message
audio/audio.h +2 -2
@@ -116,7 +116,7 @@ SWVoiceOut *AUD_open_out ( );void AUD_close_out (QEMUSoundCard *card,SWVoiceOut *sw); -int AUD_write (SWVoiceOut *sw,void *pcm_buf,int size); +size_t AUD_write (SWVoiceOut *sw,void *pcm_buf,size_t size);int AUD_get_buffer_size_out (SWVoiceOut *sw);void AUD_set_active_out (SWVoiceOut *sw,int on);int AUD_is_active_out (SWVoiceOut *sw);
@@ -137,7 +137,7 @@ SWVoiceIn *AUD_open_in ( );void AUD_close_in (QEMUSoundCard *card,SWVoiceIn *sw); -int AUD_read (SWVoiceIn *sw,void *pcm_buf,int size); +size_t AUD_read (SWVoiceIn *sw,void *pcm_buf,size_t size);void AUD_set_active_in (SWVoiceIn *sw,int on);int AUD_is_active_in (SWVoiceIn *sw);
audio/audio_int.h +11 -11
@@ -59,12 +59,12 @@ typedef struct HWVoiceOut {f_sample *clip; -int rpos; +size_t rpos;uint64_t ts_helper;struct st_sample *mix_buf; -int samples; +size_t samples; QLIST_HEAD (sw_out_listhead, SWVoiceOut) sw_head; QLIST_HEAD (sw_cap_listhead, SWVoiceCap) cap_head;int ctl_caps;
@@ -80,13 +80,13 @@ typedef struct HWVoiceIn {t_sample *conv; -int wpos; -int total_samples_captured; +size_t wpos; +size_t total_samples_captured;uint64_t ts_helper;struct st_sample *conv_buf; -int samples; +size_t samples; QLIST_HEAD (sw_in_listhead, SWVoiceIn) sw_head;int ctl_caps;struct audio_pcm_ops *pcm_ops;
@@ -101,7 +101,7 @@ struct SWVoiceOut {int64_t ratio;struct st_sample *buf;void *rate; -int total_hw_samples_mixed; +size_t total_hw_samples_mixed;int active;int empty;HWVoiceOut *hw;
@@ -118,7 +118,7 @@ struct SWVoiceIn {struct audio_pcm_info info;int64_t ratio;void *rate; -int total_hw_samples_acquired; +size_t total_hw_samples_acquired;struct st_sample *buf;f_sample *clip;HWVoiceIn *hw;
@@ -207,10 +207,10 @@ 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); -int audio_pcm_hw_get_live_in (HWVoiceIn *hw); +size_t audio_pcm_hw_get_live_in (HWVoiceIn *hw); -int audio_pcm_hw_clip_out (HWVoiceOut *hw,void *pcm_buf, -int live,int pending); +size_t audio_pcm_hw_clip_out (HWVoiceOut *hw,void *pcm_buf, +size_t live,size_t pending);int audio_bug (const char *funcname,int cond);void *audio_calloc (const char *funcname,int nmemb,size_t size);
@@ -223,7 +223,7 @@ void audio_run(AudioState *s, const char *msg);#define VOICE_VOLUME_CAP (1 << VOICE_VOLUME) -static inline int audio_ring_dist (int dst,int src,int len) +static inline size_t audio_ring_dist (size_t dst,size_t src,size_t len) {return (dst >= src) ? (dst - src) : (len - src + dst); }
audio/audio_template.h +3 -3
@@ -79,8 +79,8 @@ static int glue (audio_pcm_hw_alloc_resources_, TYPE) (HW *hw) {HWBUF =audio_calloc (AUDIO_FUNC , hw->samples,sizeof (struct st_sample ));if (!HWBUF ) { -dolog ("Could not allocate " NAME " buffer (%d samples)\n" , - hw->samples); +dolog ("Could not allocate " NAME " buffer (%zu samples)\n" , + hw->samples);return -1 ; }
@@ -265,7 +265,7 @@ static HW *glue(audio_pcm_hw_add_new_, TYPE)(AudioState *s, }if (audio_bug (AUDIO_FUNC , hw->samples <=0 )) { -dolog ("hw->samples=%d\n" , hw->samples); +dolog ("hw->samples=%zu\n" , hw->samples); goto err1; }
audio/mixeng.h +7 -4
@@ -24,6 +24,8 @@#ifndef QEMU_MIXENG_H #define QEMU_MIXENG_H +#include <stddef.h> +#ifdef FLOAT_MIXENG typedef float mixeng_real ;struct mixeng_volume {int mute;mixeng_real r;mixeng_real l; };
@@ -32,6 +34,7 @@ struct st_sample { mixeng_real l; mixeng_real r; };struct mixeng_volume {int mute;int64_t r;int64_t l; };struct st_sample {int64_t l;int64_t r; };#endif +typedef struct st_sample st_sample ;typedef void (t_sample ) (struct st_sample *dst,const void *src,int samples);typedef void (f_sample ) (void *dst,const struct st_sample *src,int samples);
@@ -40,10 +43,10 @@ extern t_sample *mixeng_conv[2][2][2][3];extern f_sample *mixeng_clip[2 ][2 ][2 ][3 ];void *st_rate_start (int inrate,int outrate); -void st_rate_flow (void *opaque,struct st_sample *ibuf,struct st_sample *obuf, -int *isamp,int *osamp); -void st_rate_flow_mix (void *opaque,struct st_sample *ibuf,struct st_sample *obuf, -int *isamp,int *osamp); +void st_rate_flow (void *opaque,st_sample *ibuf,st_sample *obuf, +size_t *isamp,size_t *osamp); +void st_rate_flow_mix (void *opaque,st_sample *ibuf,st_sample *obuf, +size_t *isamp,size_t *osamp);void st_rate_stop (void *opaque);void mixeng_clear (struct st_sample *buf,int len);void mixeng_volume (struct st_sample *buf,int len,struct mixeng_volume *vol);
audio/ossaudio.c +9 -9
@@ -478,8 +478,8 @@ static void oss_fini_out (HWVoiceOut *hw)if (oss->mmapped) { err =munmap (oss->pcm_buf, hw->samples << hw->info.shift);if (err) { -oss_logerr (errno,"Failed to unmap buffer %p, size %d\n" , - oss->pcm_buf, hw->samples << hw->info.shift); +oss_logerr (errno,"Failed to unmap buffer %p, size %zu\n" , + oss->pcm_buf, hw->samples << hw->info.shift); } }else {
@@ -545,8 +545,8 @@ static int oss_init_out(HWVoiceOut *hw, struct audsettings *as,0 );if (oss->pcm_buf ==MAP_FAILED ) { -oss_logerr (errno,"Failed to map %d bytes of DAC\n" , - hw->samples << hw->info.shift); +oss_logerr (errno,"Failed to map %zu bytes of DAC\n" , + hw->samples << hw->info.shift); }else {int err;
@@ -570,8 +570,8 @@ static int oss_init_out(HWVoiceOut *hw, struct audsettings *as,if (!oss->mmapped) { err =munmap (oss->pcm_buf, hw->samples << hw->info.shift);if (err) { -oss_logerr (errno,"Failed to unmap buffer %p size %d\n" , - oss->pcm_buf, hw->samples << hw->info.shift); +oss_logerr (errno,"Failed to unmap buffer %p size %zu\n" , + oss->pcm_buf, hw->samples << hw->info.shift); } } }
@@ -585,7 +585,7 @@ static int oss_init_out(HWVoiceOut *hw, struct audsettings *as, );if (!oss->pcm_buf) {dolog ( -"Could not allocate DAC buffer (%d samples, each %d bytes)\n" , +"Could not allocate DAC buffer (%zu samples, each %d bytes)\n" , hw->samples,1 << hw->info.shift );
@@ -697,8 +697,8 @@ static int oss_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque) hw->samples = (obt.nfrags * obt.fragsize) >> hw->info.shift; oss->pcm_buf =audio_calloc (AUDIO_FUNC , hw->samples,1 << hw->info.shift);if (!oss->pcm_buf) { -dolog ("Could not allocate ADC buffer (%d samples, each %d bytes)\n" , - hw->samples,1 << hw->info.shift); +dolog ("Could not allocate ADC buffer (%zu samples, each %d bytes)\n" , + hw->samples,1 << hw->info.shift);oss_anal_close (&fd);return -1 ; }
audio/paaudio.c +4 -4
@@ -583,8 +583,8 @@ static int qpa_init_out(HWVoiceOut *hw, struct audsettings *as, pa->pcm_buf =audio_calloc (AUDIO_FUNC , hw->samples,1 << hw->info.shift); pa->rpos = hw->rpos;if (!pa->pcm_buf) { -dolog ("Could not allocate buffer (%d bytes)\n" , - hw->samples << hw->info.shift); +dolog ("Could not allocate buffer (%zu bytes)\n" , + hw->samples << hw->info.shift); goto fail2; }
@@ -644,8 +644,8 @@ static int qpa_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque) pa->pcm_buf =audio_calloc (AUDIO_FUNC , hw->samples,1 << hw->info.shift); pa->wpos = hw->wpos;if (!pa->pcm_buf) { -dolog ("Could not allocate buffer (%d bytes)\n" , - hw->samples << hw->info.shift); +dolog ("Could not allocate buffer (%zu bytes)\n" , + hw->samples << hw->info.shift); goto fail2; }
audio/rate_template.h +1 -1
@@ -28,7 +28,7 @@* Return number of samples processed. */ void NAME (void *opaque,struct st_sample *ibuf,struct st_sample *obuf, -int *isamp,int *osamp) +size_t *isamp,size_t *osamp) {struct rate *rate = opaque;struct st_sample *istart, *iend;
audio/sdlaudio.c +2 -2
@@ -250,8 +250,8 @@ static void sdl_callback (void *opaque, Uint8 *buf, int len) }if (audio_bug (AUDIO_FUNC , sdl->live <0 || sdl->live > hw->samples)) { -dolog ("sdl->live=%d hw->samples=%d\n" , - sdl->live, hw->samples); +dolog ("sdl->live=%d hw->samples=%zu\n" , + sdl->live, hw->samples);return ; }
audio/wavaudio.c +2 -2
@@ -136,8 +136,8 @@ static int wav_init_out(HWVoiceOut *hw, struct audsettings *as, hw->samples =1024 ; wav->pcm_buf =audio_calloc (AUDIO_FUNC , hw->samples,1 << hw->info.shift);if (!wav->pcm_buf) { -dolog ("Could not allocate buffer (%d bytes)\n" , - hw->samples << hw->info.shift); +dolog ("Could not allocate buffer (%zu bytes)\n" , + hw->samples << hw->info.shift);return -1 ; }
Signature · 1 line
2.5.0
PATCH v2 35/49 audio: api for mixeng code free backends
In reply to Kővágó, Zoltán--- audio/audio.c | 209 ++++++++++++++++++++++++++++++++++++++++++++++++- audio/audio_int.h | 41 ++++++++-- audio/audio_template.h | 1 + 3 files changed, 241 insertions(+), 10 deletions(-)
audio/audio.c +207 -2
@@ -544,6 +544,25 @@ size_t audio_pcm_hw_clip_out(HWVoiceOut *hw, void *pcm_buf,return clipped; } +static void audio_pcm_hw_clip_out2 (HWVoiceOut *hw,void *pcm_buf,size_t len) +{ +size_t clipped =0 ; +size_t pos = hw->rpos; + +while (len) { +st_sample *src = hw->mix_buf + pos; +uint8_t *dst =advance (pcm_buf, clipped << hw->info.shift); +size_t samples_till_end_of_buf = hw->samples - pos; +size_t samples_to_clip =MIN (len, samples_till_end_of_buf); + + hw->clip (dst, src, samples_to_clip); + + pos = (pos + samples_to_clip) % hw->samples; + len -= samples_to_clip; + clipped += samples_to_clip; + } +} +/* * Soft voice (capture) */
@@ -1005,6 +1024,31 @@ static void audio_capture_mix_and_clear(HWVoiceOut *hw, size_t rpos,mixeng_clear (hw->mix_buf, samples - n); } +static size_t audio_pcm_hw_run_out (HWVoiceOut *hw,size_t live) +{ +size_t clipped =0 ; + +while (live) { +size_t size, decr, proc; +void *buf = hw->pcm_ops->get_buffer_out (hw, &size); + + decr =MIN (size >> hw->info.shift, live); +audio_pcm_hw_clip_out2 (hw, buf, decr); + proc = hw->pcm_ops->put_buffer_out (hw, buf, decr << hw->info.shift) >> + hw->info.shift; + + live -= proc; + clipped += proc; + hw->rpos = (hw->rpos + proc) % hw->samples; + +if (proc ==0 || proc < decr) { +break ; + } + } + +return clipped; +} +static void audio_run_out (AudioState *s) {HWVoiceOut *hw =NULL ;
@@ -1052,7 +1096,11 @@ static void audio_run_out (AudioState *s) } prev_rpos = hw->rpos; - played = hw->pcm_ops->run_out (hw, live); +if (hw->pcm_ops->run_out) { + played = hw->pcm_ops->run_out (hw, live); + }else { + played =audio_pcm_hw_run_out (hw, live); + }if (audio_bug (AUDIO_FUNC , hw->rpos >= hw->samples)) {dolog ("rpos=%zu samples=%zu played=%zu\n" , hw->rpos, hw->samples, played);
@@ -1110,6 +1158,35 @@ static void audio_run_out (AudioState *s) } } +static size_t audio_pcm_hw_run_in (HWVoiceIn *hw,size_t samples) +{ +size_t conv =0 ; + +while (samples) { +size_t proc; +size_t size = samples << hw->info.shift; +void *buf = hw->pcm_ops->get_buffer_in (hw, &size); + +assert ((size & hw->info.align) ==0 ); +if (size ==0 ) { + hw->pcm_ops->put_buffer_in (hw, buf, size); +break ; + } + + proc =MIN (size >> hw->info.shift, + hw->samples - hw->wpos); + + hw->conv (hw->conv_buf + hw->wpos, buf, proc); + hw->wpos = (hw->wpos + proc) % hw->samples; + + samples -= proc; + conv += proc; + hw->pcm_ops->put_buffer_in (hw, buf, proc << hw->info.shift); + } + +return conv; +} +static void audio_run_in (AudioState *s) {HWVoiceIn *hw =NULL ;
@@ -1118,7 +1195,12 @@ static void audio_run_in (AudioState *s)SWVoiceIn *sw;size_t captured, min; - captured = hw->pcm_ops->run_in (hw); +if (hw->pcm_ops->run_in) { + captured = hw->pcm_ops->run_in (hw); + }else { + captured =audio_pcm_hw_run_in ( + hw, hw->samples -audio_pcm_hw_get_live_in (hw)); + } min =audio_pcm_hw_find_min_in (hw); hw->total_samples_captured += captured - min;
@@ -1210,12 +1292,135 @@ void audio_run(AudioState *s, const char *msg)#endif } +void *audio_generic_get_buffer_in (HWVoiceIn *hw,size_t *size) +{ +ssize_t start; + +if (unlikely (!hw->buf_emul)) { +size_t calc_size = hw->samples << hw->info.shift; + hw->buf_emul =g_malloc (calc_size); + hw->size_emul = calc_size; + hw->pos_emul = hw->pending_emul =0 ; + } + +while (hw->pending_emul < hw->size_emul) { +size_t read_len =MIN (hw->size_emul - hw->pos_emul, + hw->size_emul - hw->pending_emul); +size_t read = hw->pcm_ops->read (hw, hw->buf_emul + hw->pos_emul, + read_len); + hw->pending_emul += read; +if (read < read_len) { +break ; + } + } + + start = ((ssize_t ) hw->pos_emul) - hw->pending_emul; +if (start <0 ) { + start += hw->size_emul; + } +assert (start >=0 && start < hw->size_emul); + + *size =MIN (hw->pending_emul, hw->size_emul - start); +return hw->buf_emul + start; +} + +void audio_generic_put_buffer_in (HWVoiceIn *hw,void *buf,size_t size) +{ +assert (size <= hw->pending_emul); + hw->pending_emul -= size; +} + +void *audio_generic_get_buffer_out (HWVoiceOut *hw,size_t *size) +{ +if (unlikely (!hw->buf_emul)) { +size_t calc_size = hw->samples << hw->info.shift; + + hw->buf_emul =g_malloc (calc_size); + hw->size_emul = calc_size; + hw->pos_emul = hw->pending_emul =0 ; + } + + *size =MIN (hw->size_emul - hw->pending_emul, + hw->size_emul - hw->pos_emul); +return hw->buf_emul + hw->pos_emul; +} + +size_t audio_generic_put_buffer_out_nowrite (HWVoiceOut *hw,void *buf, +size_t size) +{ +assert (buf == hw->buf_emul + hw->pos_emul && + size + hw->pending_emul <= hw->size_emul); + + hw->pending_emul += size; + hw->pos_emul = (hw->pos_emul + size) % hw->size_emul; + +return size; +} + +size_t audio_generic_put_buffer_out (HWVoiceOut *hw,void *buf,size_t size) +{ +audio_generic_put_buffer_out_nowrite (hw, buf, size); + +while (hw->pending_emul) { +size_t write_len, written; +ssize_t start = ((ssize_t ) hw->pos_emul) - hw->pending_emul; +if (start <0 ) { + start += hw->size_emul; + } +assert (start >=0 && start < hw->size_emul); + + write_len =MIN (hw->pending_emul, hw->size_emul - start); + + written = hw->pcm_ops->write (hw, hw->buf_emul + start, write_len); + hw->pending_emul -= written; + +if (written < write_len) { +break ; + } + } + +/* fake we have written everything. non-written data remain in pending_emul, +* so we do not have to clip them multiple times */ +return size; +} + +size_t audio_generic_write (HWVoiceOut *hw,void *buf,size_t size) +{ +size_t dst_size, copy_size; +void *dst = hw->pcm_ops->get_buffer_out (hw, &dst_size); + copy_size =MIN (size, dst_size); + +memcpy (dst, buf, copy_size); +return hw->pcm_ops->put_buffer_out (hw, buf, copy_size); +} + +size_t audio_generic_read (HWVoiceIn *hw,void *buf,size_t size) +{ +size_t dst_size, copy_size; +void *dst = hw->pcm_ops->get_buffer_in (hw, &dst_size); + copy_size =MIN (size, dst_size); + +memcpy (dst, buf, copy_size); + hw->pcm_ops->put_buffer_in (hw, buf, copy_size); +return copy_size; +} + +static int audio_driver_init (AudioState *s,struct audio_driver *drv,Audiodev *dev) { s->drv_opaque = drv->init (dev);if (s->drv_opaque) { +if (!drv->pcm_ops->get_buffer_in) { + drv->pcm_ops->get_buffer_in = audio_generic_get_buffer_in; + drv->pcm_ops->put_buffer_in = audio_generic_put_buffer_in; + } +if (!drv->pcm_ops->get_buffer_out) { + drv->pcm_ops->get_buffer_out = audio_generic_get_buffer_out; + drv->pcm_ops->put_buffer_out = audio_generic_put_buffer_out; + } +audio_init_nb_voices_out (s, drv);audio_init_nb_voices_in (s, drv); s->drv = drv;
audio/audio_int.h +33 -8
62 lines not on this page · raw message
audio/audio_template.h +1 -0
@@ -71,6 +71,7 @@ static void glue(audio_init_nb_voices_, TYPE)(AudioState *s,static void glue (audio_pcm_hw_free_resources_ ,TYPE ) (HW *hw) { +g_free (hw->buf_emul);g_free (HWBUF );HWBUF =NULL ; }
Signature · 1 line
2.5.0
PATCH v2 36/49 alsaaudio: port to the new audio backend api
In reply to Kővágó, Zoltán--- audio/alsaaudio.c | 306 +++++++++++++++--------------------------------------- 1 file changed, 81 insertions(+), 225 deletions(-)
audio/alsaaudio.c +81 -225
@@ -45,9 +45,6 @@ struct pollhlp { typedef struct ALSAVoiceOut { HWVoiceOut hw; - int wpos; - int pending; - void *pcm_buf; snd_pcm_t *handle; struct pollhlp pollhlp; Audiodev *dev;
@@ -56,7 +53,6 @@ typedef struct ALSAVoiceOut {typedef struct ALSAVoiceIn {HWVoiceIn hw;snd_pcm_t *handle; -void *pcm_buf;struct pollhlp pollhlp;Audiodev *dev; }ALSAVoiceIn ;
@@ -611,102 +607,62 @@ static int alsa_open(bool in, struct alsa_params_req *req,return -1 ; } -static snd_pcm_sframes_t alsa_get_avail (snd_pcm_t *handle) -{ -snd_pcm_sframes_t avail; - - avail =snd_pcm_avail_update (handle); -if (avail <0 ) { -if (avail == -EPIPE ) { -if (!alsa_recover (handle)) { - avail =snd_pcm_avail_update (handle); - } - } - -if (avail <0 ) { -alsa_logerr (avail, -"Could not obtain number of available frames\n" ); -return -1 ; - } - } - -return avail; -} - -static void alsa_write_pending (ALSAVoiceOut *alsa) -{ -HWVoiceOut *hw = &alsa->hw; - -while (alsa->pending) { -int left_till_end_samples = hw->samples - alsa->wpos; -int len =MIN (alsa->pending, left_till_end_samples); -char *src =advance (alsa->pcm_buf, alsa->wpos << hw->info.shift); - -while (len) { -snd_pcm_sframes_t written; - - written =snd_pcm_writei (alsa->handle, src, len); - -if (written <=0 ) { -switch (written) { -case 0 : -trace_alsa_wrote_zero (len); -return ; - -case -EPIPE : -if (alsa_recover (alsa->handle)) { -alsa_logerr (written,"Failed to write %d frames\n" , - len); -return ; - } -trace_alsa_xrun_out (); -continue ; - -case -ESTRPIPE : -/* stream is suspended and waiting for an -application recovery */ -if (alsa_resume (alsa->handle)) { -alsa_logerr (written,"Failed to write %d frames\n" , - len); -return ; - } -trace_alsa_resume_out (); -continue ; - -case -EAGAIN : -return ; - -default : -alsa_logerr (written,"Failed to write %d frames from %p\n" , - len, src); -return ; - } - } - - alsa->wpos = (alsa->wpos + written) % hw->samples; - alsa->pending -= written; - len -= written; - } - } -} - -static int alsa_run_out (HWVoiceOut *hw,int live) +static size_t alsa_write (HWVoiceOut *hw,void *buf,size_t len) {ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw; -int decr; -snd_pcm_sframes_t avail; +size_t pos =0 ; +size_t len_frames = len >> hw->info.shift; - avail =alsa_get_avail (alsa->handle); -if (avail <0 ) { -dolog ("Could not get number of available playback frames\n" ); -return 0 ; +while (len_frames) { +char *src =advance (buf, pos); +snd_pcm_sframes_t written; + + written =snd_pcm_writei (alsa->handle, src, len_frames); + +if (written <=0 ) { +switch (written) { +case 0 : +trace_alsa_wrote_zero (len_frames); +return pos; + +case -EPIPE : +if (alsa_recover (alsa->handle)) { +alsa_logerr (written,"Failed to write %zu frames\n" , + len_frames); +return pos; + } +trace_alsa_xrun_out (); +continue ; + +case -ESTRPIPE : +/* stream is suspended and waiting for an +application recovery */ +if (alsa_resume (alsa->handle)) { +alsa_logerr (written,"Failed to write %zu frames\n" , + len_frames); +return pos; + } +trace_alsa_resume_out (); +continue ; + +case -EAGAIN : +return pos; + +default : +alsa_logerr (written,"Failed to write %zu frames from %p\n" , + len, src); +return pos; + } + } + + pos += written << hw->info.shift; +if (written < len_frames) { +break ; + } + len_frames -= written; } - decr =MIN (live, avail); - decr =audio_pcm_hw_clip_out (hw, alsa->pcm_buf, decr, alsa->pending); - alsa->pending += decr; -alsa_write_pending (alsa); -return decr; +return pos; }static void alsa_fini_out (HWVoiceOut *hw)
@@ -715,9 +671,6 @@ static void alsa_fini_out (HWVoiceOut *hw)ldebug ("alsa_fini\n" );alsa_anal_close (&alsa->handle, &alsa->pollhlp); - -g_free (alsa->pcm_buf); - alsa->pcm_buf =NULL ; } static int alsa_init_out(HWVoiceOut *hw, struct audsettings *as,
@@ -746,14 +699,6 @@ static int alsa_init_out(HWVoiceOut *hw, struct audsettings *as,audio_pcm_init_info (&hw->info, &obt_as); hw->samples = obt.samples; - alsa->pcm_buf =audio_calloc (AUDIO_FUNC , obt.samples,1 << hw->info.shift); -if (!alsa->pcm_buf) { -dolog ("Could not allocate DAC buffer (%zu samples, each %d bytes)\n" , - hw->samples,1 << hw->info.shift); -alsa_anal_close1 (&handle); -return -1 ; - } - alsa->pollhlp.s = hw->s; alsa->handle = handle; alsa->dev = dev;
@@ -848,14 +793,6 @@ static int alsa_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque)audio_pcm_init_info (&hw->info, &obt_as); hw->samples = obt.samples; - alsa->pcm_buf =audio_calloc (AUDIO_FUNC , hw->samples,1 << hw->info.shift); -if (!alsa->pcm_buf) { -dolog ("Could not allocate ADC buffer (%zu samples, each %d bytes)\n" , - hw->samples,1 << hw->info.shift); -alsa_anal_close1 (&handle); -return -1 ; - } - alsa->pollhlp.s = hw->s; alsa->handle = handle; alsa->dev = dev;
@@ -867,129 +804,48 @@ static void alsa_fini_in (HWVoiceIn *hw)ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;alsa_anal_close (&alsa->handle, &alsa->pollhlp); - -g_free (alsa->pcm_buf); - alsa->pcm_buf =NULL ; } -static int alsa_run_in (HWVoiceIn *hw) +static size_t alsa_read (HWVoiceIn *hw,void *buf,size_t len) {ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw; -int hwshift = hw->info.shift; -int i; -int live =audio_pcm_hw_get_live_in (hw); -int dead = hw->samples - live; -int decr; -struct { -int add; -int len; - } bufs[2 ] = { - { .add = hw->wpos, .len =0 }, - { .add =0 , .len =0 } - }; -snd_pcm_sframes_t avail; -snd_pcm_uframes_t read_samples =0 ; +size_t pos =0 ; -if (!dead) { -return 0 ; - } - - avail =alsa_get_avail (alsa->handle); -if (avail <0 ) { -dolog ("Could not get number of captured frames\n" ); -return 0 ; - } - -if (!avail) { -snd_pcm_state_t state; - - state =snd_pcm_state (alsa->handle); -switch (state) { -case SND_PCM_STATE_PREPARED : - avail = hw->samples; -break ; -case SND_PCM_STATE_SUSPENDED : -/* stream is suspended and waiting for an application recovery */ -if (alsa_resume (alsa->handle)) { -dolog ("Failed to resume suspended input stream\n" ); -return 0 ; - } -trace_alsa_resume_in (); -break ; -default : -trace_alsa_no_frames (state); -return 0 ; - } - } - - decr =MIN (dead, avail); -if (!decr) { -return 0 ; - } - -if (hw->wpos + decr > hw->samples) { - bufs[0 ].len = (hw->samples - hw->wpos); - bufs[1 ].len = (decr - (hw->samples - hw->wpos)); - } -else { - bufs[0 ].len = decr; - } - -for (i =0 ; i <2 ; ++i) { -void *src; -struct st_sample *dst; +while (len) { +void *dst =advance (buf, pos);snd_pcm_sframes_t nread; -snd_pcm_uframes_t len; - len = bufs[i].len; + nread =snd_pcm_readi (alsa->handle, dst, len >> hw->info.shift); - src =advance (alsa->pcm_buf, bufs[i].add << hwshift); - dst = hw->conv_buf + bufs[i].add; +if (nread <=0 ) { +switch (nread) { +case 0 : +trace_alsa_read_zero (len); +return pos;; -while (len) { - nread =snd_pcm_readi (alsa->handle, src, len); - -if (nread <=0 ) { -switch (nread) { -case 0 : -trace_alsa_read_zero (len); - goto exit; - -case -EPIPE : -if (alsa_recover (alsa->handle)) { -alsa_logerr (nread,"Failed to read %ld frames\n" , len); - goto exit; - } -trace_alsa_xrun_in (); -continue ; - -case -EAGAIN : - goto exit; - -default : -alsa_logerr ( - nread, -"Failed to read %ld frames from %p\n" , - len, - src - ); - goto exit; +case -EPIPE : +if (alsa_recover (alsa->handle)) { +alsa_logerr (nread,"Failed to read %zu frames\n" , len); +return pos; } +trace_alsa_xrun_in (); +continue ; + +case -EAGAIN : +return pos; + +default : +alsa_logerr (nread,"Failed to read %zu frames to %p\n" , + len, dst); +return pos;; } - - hw->conv (dst, src, nread); - - src =advance (src, nread << hwshift); - dst += nread; - - read_samples += nread; - len -= nread; } + + pos += nread << hw->info.shift; + len -= nread << hw->info.shift; } - exit: - hw->wpos = (hw->wpos + read_samples) % hw->samples; -return read_samples; +return pos; }static int alsa_ctl_in (HWVoiceIn *hw,int cmd, ...)
@@ -1056,12 +912,12 @@ static void alsa_audio_fini (void *opaque)static struct audio_pcm_ops alsa_pcm_ops = { .init_out = alsa_init_out, .fini_out = alsa_fini_out, - .run_out = alsa_run_out, + .write = alsa_write, .ctl_out = alsa_ctl_out, .init_in = alsa_init_in, .fini_in = alsa_fini_in, - .run_in = alsa_run_in, + .read = alsa_read, .ctl_in = alsa_ctl_in, };
Signature · 1 line
2.5.0
PATCH v2 37/49 coreaudio: port to the new audio backend api
In reply to Kővágó, Zoltán--- audio/coreaudio.c | 130 +++++++++++++++++++++++++++++------------------------- 1 file changed, 69 insertions(+), 61 deletions(-)
audio/coreaudio.c +69 -61
@@ -40,9 +40,6 @@ typedef struct coreaudioVoiceOut {AudioDeviceID outputDeviceID;UInt32 audioDevicePropertyBufferFrameSize;AudioStreamBasicDescription outputStreamBasicDescription; -int live; -int decr; -int rpos; } coreaudioVoiceOut;static void coreaudio_logstatus (OSStatus status)
@@ -181,31 +178,29 @@ static int coreaudio_unlock (coreaudioVoiceOut *core, const char *fn_name)return 0 ; } -static int coreaudio_run_out (HWVoiceOut *hw,int live) -{ -int decr; -coreaudioVoiceOut *core = (coreaudioVoiceOut *) hw; - -if (coreaudio_lock (core,"coreaudio_run_out" )) { -return 0 ; +#define COREAUDIO_WRAPPER_FUNC (name, ret_type, args_decl, args) \ + static ret_type glue(coreaudio_, name)args_decl \ + { \ + coreaudioVoiceOut *core = (coreaudioVoiceOut *) hw; \ + ret_type ret; \ + \ + if (coreaudio_lock(core, "coreaudio_" #name)) { \ + return 0; \ + } \ + \ + ret = glue(audio_generic_, name)args; \ + \ + coreaudio_unlock(core, "coreaudio_" #name); \ + return ret; \ } - -if (core->decr > live) { -ldebug ("core->decr %d live %d core->live %d\n" , - core->decr, - live, - core->live); - } - - decr =MIN (core->decr, live); - core->decr -= decr; - - core->live = live - decr; - hw->rpos = core->rpos; - -coreaudio_unlock (core,"coreaudio_run_out" ); -return decr; -} +COREAUDIO_WRAPPER_FUNC(get_buffer_out, void *, (HWVocieOut *hw, size_t *size), + (hw, size)) +COREAUDIO_WRAPPER_FUNC (put_buffer_out_nowrite, size_t, + (HWVoiceOut *hw, void *buf, size_t size), + (hw, buf, size)) +COREAUDIO_WRAPPER_FUNC(write, size_t, (HWVoiceOut *hw, void *buf, size_t size), + (hw, buf, size)) +#undef COREAUDIO_WRAPPER_FUNC/* callback to feed audiooutput buffer */ static OSStatus audioDeviceIOProc(
@@ -217,19 +212,11 @@ static OSStatus audioDeviceIOProc(const AudioTimeStamp * inOutputTime, void* hwptr) { - UInt32 frame, frameCount; -float *out = outOutputData->mBuffers[0 ].mData; + UInt32 frameCount, pending_frames; +void *out = outOutputData->mBuffers[0 ].mData;HWVoiceOut *hw = hwptr;coreaudioVoiceOut *core = (coreaudioVoiceOut *) hwptr; -int rpos, live; -struct st_sample *src; -#ifndef FLOAT_MIXENG -#ifdef RECIPROCAL -const float scale =1.f /UINT_MAX ; -#else -const float scale =UINT_MAX ; -#endif -#endif +size_t len;if (coreaudio_lock (core,"audioDeviceIOProc" )) { inInputTime =0 ;
@@ -237,42 +224,51 @@ static OSStatus audioDeviceIOProc( } frameCount = core->audioDevicePropertyBufferFrameSize; - live = core->live; + pending_frames = hw->pending_emul >> hw->info.shift;/* if there are not enough samples, set signal and return */ -if (live < frameCount) { +if (pending_frames < frameCount) { inInputTime =0 ;coreaudio_unlock (core,"audioDeviceIOProc(empty)" );return 0 ; } - rpos = core->rpos; - src = hw->mix_buf + rpos; + len = frameCount << hw->info.shift; +while (len) { +size_t write_len; +ssize_t start = ((ssize_t ) hw->pos_emul) - hw->pending_emul; +if (start <0 ) { + start += hw->size_emul; + } +assert (start >=0 && start < hw->size_emul); -/* fill buffer */ -for (frame =0 ; frame < frameCount; frame++) { -#ifdef FLOAT_MIXENG - *out++ = src[frame].l;/* left channel */ - *out++ = src[frame].r;/* right channel */ -#else -#ifdef RECIPROCAL - *out++ = src[frame].l * scale;/* left channel */ - *out++ = src[frame].r * scale;/* right channel */ -#else - *out++ = src[frame].l / scale;/* left channel */ - *out++ = src[frame].r / scale;/* right channel */ -#endif -#endif + write_len =MIN (MIN (hw->pending_emul, len), + hw->size_emul - start); + +memcpy (out, hw->buf_emul + start, write_len); + hw->pending_emul -= write_len; + len -= write_len; + out += write_len; } - rpos = (rpos + frameCount) % hw->samples; - core->decr += frameCount; - core->rpos = rpos; -coreaudio_unlock (core,"audioDeviceIOProc" );return 0 ; } +static UInt32 coreaudio_get_flags (struct audio_pcm_info *info, +struct audsettings *as) +{ +UInt32 flags = info->sign ? kAudioFormatFlagIsSignedInteger :0 ; +if (as->endianness) {/* 0 = little, 1 = big */ + flags |= kAudioFormatFlagIsBigEndian; + } + +if (flags ==0 ) {/* must not be 0 */ + flags = kAudioFormatFlagsAreAllClear; + } +return flags; +} +static int coreaudio_init_out (HWVoiceOut *hw,struct audsettings *as,void *drv_opaque) {
@@ -391,6 +387,16 @@ static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as,/* set Samplerate */ core->outputStreamBasicDescription.mSampleRate = (Float64 ) as->freq; + core->outputStreamBasicDescription.mFormatID = kAudioFormatLinearPCM; + core->outputStreamBasicDescription.mFormatFlags = +coreaudio_get_flags (hw->info, as); + core->outputStreamBasicDescription.mBytesPerPacket = + core->outputStreamBasicDescription.mBytesPerFrame = + hw->info.nchannels * hw->info.bits /8 ; + core->outputStreamBasicDescription.mFramesPerPacket =1 ; + core->outputStreamBasicDescription.mChannelsPerFrame = hw->info.nchannels; + core->outputStreamBasicDescription.mBitsPerChannel = hw->info.bits; + propertySize =sizeof (core->outputStreamBasicDescription); status = AudioDeviceSetProperty( core->outputDeviceID,
@@ -504,7 +510,9 @@ static void coreaudio_audio_fini (void *opaque)static struct audio_pcm_ops coreaudio_pcm_ops = { .init_out = coreaudio_init_out, .fini_out = coreaudio_fini_out, - .run_out = coreaudio_run_out, + .write = coreaudio_write, + .get_buffer_out = coreaudio_get_buffer_out, + .put_buffer_out = coreaudio_put_buffer_out_nowrite, .ctl_out = coreaudio_ctl_out };
Signature · 1 line
2.5.0
PATCH v2 38/49 dsoundaudio: port to the new audio backend api
In reply to Kővágó, Zoltán--- audio/dsound_template.h | 45 +++---- audio/dsoundaudio.c | 328 ++++++++++++------------------------------------ 2 files changed, 102 insertions(+), 271 deletions(-)
audio/dsound_template.h +23 -22
@@ -29,6 +29,8 @@#define BUFPTR LPDIRECTSOUNDCAPTUREBUFFER#define FIELD dsound_capture_buffer#define FIELD2 dsound_capture +#define HWVOICE HWVoiceIn +#define DSOUNDVOICE DSoundVoiceIn#else #define NAME "playback buffer"#define NAME2 "DirectSound"
@@ -37,6 +39,8 @@#define BUFPTR LPDIRECTSOUNDBUFFER#define FIELD dsound_buffer#define FIELD2 dsound +#define HWVOICE HWVoiceOut +#define DSOUNDVOICE DSoundVoiceOut#endif static int glue (dsound_unlock_, TYPE) (
@@ -72,8 +76,6 @@ static int glue (dsound_lock_, TYPE) ( ) {HRESULT hr; -LPVOID p1 =NULL , p2 =NULL ; -DWORD blen1 =0 , blen2 =0 ;DWORD flag;#ifdef DSBTYPE_IN
@@ -81,7 +83,7 @@ static int glue (dsound_lock_, TYPE) (#else flag = entire ?DSBLOCK_ENTIREBUFFER :0 ;#endif - hr =glue (IFACE , _Lock)(buf, pos, len, &p1, &blen1, &p2, &blen2, flag); + hr =glue (IFACE , _Lock)(buf, pos, len, p1p, blen1p, p2p, blen2p, flag);if (FAILED (hr)) {#ifndef DSBTYPE_IN
@@ -96,34 +98,34 @@ static int glue (dsound_lock_, TYPE) ( goto fail; } -if ((p1 && (blen1 & info->align)) || (p2 && (blen2 & info->align))) { +if ((p1p && *p1p && (*blen1p & info->align)) || + (p2p && *p2p && (*blen2p & info->align))) {dolog ("DirectSound returned misaligned buffer %ld %ld\n" , - blen1, blen2); -glue (dsound_unlock_,TYPE ) (buf, p1, p2, blen1, blen2); + *blen1p, *blen2p); +glue (dsound_unlock_,TYPE ) (buf, *p1p, p2p ? *p2p :NULL , *blen1p, + blen2p ? *blen2p :0 ); goto fail; } -if (!p1 && blen1) { -dolog ("warning: !p1 && blen1=%ld\n" , blen1); - blen1 =0 ; +if (p1p && !*p1p && *blen1p) { +dolog ("warning: !p1 && blen1=%ld\n" , *blen1p); + *blen1p =0 ; } -if (!p2 && blen2) { -dolog ("warning: !p2 && blen2=%ld\n" , blen2); - blen2 =0 ; +if (p2p && !*p2p && *blen2p) { +dolog ("warning: !p2 && blen2=%ld\n" , *blen2p); + *blen2p =0 ; } - *p1p = p1; - *p2p = p2; - *blen1p = blen1; - *blen2p = blen2;return 0 ; fail: *p1p =NULL -1 ; - *p2p =NULL -1 ; *blen1p =-1 ; - *blen2p =-1 ; +if (p2p) { + *p2p =NULL -1 ; + *blen2p =-1 ; + }return -1 ; }
@@ -242,7 +244,6 @@ static int dsound_init_out(HWVoiceOut *hw, struct audsettings *as, goto fail0; } - ds->first_time =1 ; obt_as.endianness =0 ;audio_pcm_init_info (&hw->info, &obt_as);
@@ -252,15 +253,13 @@ static int dsound_init_out(HWVoiceOut *hw, struct audsettings *as, bc.dwBufferBytes, hw->info.align +1 ); } + hw->size_emul = bc.dwBufferBytes; hw->samples = bc.dwBufferBytes >> hw->info.shift; ds->s = s;#ifdef DEBUG_DSOUND dolog ("caps %ld, desc %ld\n" , bc.dwBufferBytes, bd.dwBufferBytes); - -dolog ("bufsize %d, freq %d, chan %d, fmt %d\n" , - hw->bufsize, settings.freq, settings.nchannels, settings.fmt);#endif return 0 ;
@@ -276,3 +275,5 @@ static int dsound_init_out(HWVoiceOut *hw, struct audsettings *as,#undef BUFPTR#undef FIELD#undef FIELD2 +#undef HWVOICE +#undef DSOUNDVOICE
audio/dsoundaudio.c +79 -249
395 lines not on this page · raw message
Signature · 1 line
2.5.0
PATCH v2 39/49 noaudio: port to the new audio backend api
In reply to Kővágó, Zoltán--- audio/noaudio.c | 39 +++++++++++++++------------------------ 1 file changed, 15 insertions(+), 24 deletions(-)
audio/noaudio.c +15 -24
@@ -38,10 +38,9 @@ typedef struct NoVoiceIn {int64_t old_ticks; } NoVoiceIn; -static int no_run_out (HWVoiceOut *hw,int live) +static size_t no_write (HWVoiceOut *hw,void *buf,size_t len) {NoVoiceOut *no = (NoVoiceOut *) hw; -int decr, samples;int64_t now;int64_t ticks;int64_t bytes;
@@ -49,13 +48,9 @@ static int no_run_out (HWVoiceOut *hw, int live) now =qemu_clock_get_ns (QEMU_CLOCK_VIRTUAL ); ticks = now - no->old_ticks; bytes =muldiv64 (ticks, hw->info.bytes_per_second,get_ticks_per_sec ()); - bytes =MIN (bytes,INT_MAX ); - samples = bytes >> hw->info.shift; no->old_ticks = now; - decr =MIN (live, samples); - hw->rpos = (hw->rpos + decr) % hw->samples; -return decr; +return MIN (len, bytes); }static int no_init_out (HWVoiceOut *hw,struct audsettings *as,void *drv_opaque)
@@ -89,25 +84,21 @@ static void no_fini_in (HWVoiceIn *hw) (void ) hw; } -static int no_run_in (HWVoiceIn *hw) +static size_t no_read (HWVoiceIn *hw,void *buf,size_t size) { +size_t to_clear;NoVoiceIn *no = (NoVoiceIn *) hw; -int live =audio_pcm_hw_get_live_in (hw); -int dead = hw->samples - live; -int samples =0 ; -if (dead) { -int64_t now =qemu_clock_get_ns (QEMU_CLOCK_VIRTUAL ); -int64_t ticks = now - no->old_ticks; -int64_t bytes = -muldiv64 (ticks, hw->info.bytes_per_second,get_ticks_per_sec ()); +int64_t now =qemu_clock_get_ns (QEMU_CLOCK_VIRTUAL ); +int64_t ticks = now - no->old_ticks; +int64_t bytes = +muldiv64 (ticks, hw->info.bytes_per_second,get_ticks_per_sec ()); - no->old_ticks = now; - bytes =MIN (bytes,INT_MAX ); - samples = bytes >> hw->info.shift; - samples =MIN (samples, dead); - } -return samples; + no->old_ticks = now; + to_clear =MIN (bytes, size); + +audio_pcm_info_clear_buf (&hw->info, buf, to_clear >> hw->info.shift); +return to_clear; }static int no_ctl_in (HWVoiceIn *hw,int cmd, ...)
@@ -130,12 +121,12 @@ static void no_audio_fini (void *opaque)static struct audio_pcm_ops no_pcm_ops = { .init_out = no_init_out, .fini_out = no_fini_out, - .run_out = no_run_out, + .write = no_write, .ctl_out = no_ctl_out, .init_in = no_init_in, .fini_in = no_fini_in, - .run_in = no_run_in, + .read = no_read, .ctl_in = no_ctl_in };
Signature · 1 line
2.5.0
PATCH v2 40/49 ossaudio: port to the new audio backend api
In reply to Kővágó, Zoltán--- audio/ossaudio.c | 289 ++++++++++++++++++++----------------------------------- 1 file changed, 104 insertions(+), 185 deletions(-)
audio/ossaudio.c +104 -185
@@ -42,19 +42,15 @@typedef struct OSSVoiceOut {HWVoiceOut hw; -void *pcm_buf;int fd; -int wpos;int nfrags;int fragsize;int mmapped; -int pending;Audiodev *dev; }OSSVoiceOut ; typedef struct OSSVoiceIn { HWVoiceIn hw; - void *pcm_buf; int fd; int nfrags; int fragsize;
@@ -373,97 +369,87 @@ static int oss_open(int in, struct oss_params *req, audsettings *as,return -1 ; } -static void oss_write_pending (OSSVoiceOut *oss) +static size_t oss_get_available_bytes (OSSVoiceOut *oss) { -HWVoiceOut *hw = &oss->hw; +int err; +struct count_info cntinfo; +assert (oss->mmapped); + err =ioctl (oss->fd,SNDCTL_DSP_GETOPTR , &cntinfo); +if (err <0 ) { +oss_logerr (errno,"SNDCTL_DSP_GETOPTR failed\n" ); +return 0 ; + } + +return audio_ring_dist (cntinfo.ptr, oss->hw.pos_emul, oss->hw.size_emul); +} + +static void *oss_get_buffer_out (HWVoiceOut *hw,size_t *size) +{ +OSSVoiceOut *oss = (OSSVoiceOut *) hw; +if (oss->mmapped) { + *size =MIN (oss_get_available_bytes (oss), hw->size_emul - hw->pos_emul); +return hw->buf_emul + hw->pos_emul; + }else { +return audio_generic_get_buffer_out (hw, size); + } +} + +static size_t oss_put_buffer_out (HWVoiceOut *hw,void *buf,size_t size) +{ +OSSVoiceOut *oss = (OSSVoiceOut *) hw;if (oss->mmapped) { -return ; +assert (buf == hw->buf_emul + hw->pos_emul && size < hw->size_emul); + + hw->pos_emul = (hw->pos_emul + size) % hw->size_emul; +return size; + }else { +return audio_generic_put_buffer_out (hw, buf, size); + } +} + +static size_t oss_write (HWVoiceOut *hw,void *buf,size_t len) +{ +OSSVoiceOut *oss = (OSSVoiceOut *) hw; +size_t pos; + +if (oss->mmapped) { +size_t total_len; + len =MIN (len,oss_get_available_bytes (oss)); + + total_len = len; +while (len) { +size_t to_copy =MIN (len, hw->size_emul - hw->pos_emul); +memcpy (hw->buf_emul + hw->pos_emul, buf, to_copy); + + hw->pos_emul = (hw->pos_emul + to_copy) % hw->pos_emul; + buf += to_copy; + len -= to_copy; + } +return total_len; } -while (oss->pending) { -int samples_written; + pos =0 ; +while (len) {ssize_t bytes_written; -int samples_till_end = hw->samples - oss->wpos; -int samples_to_write =MIN (oss->pending, samples_till_end); -int bytes_to_write = samples_to_write << hw->info.shift; -void *pcm =advance (oss->pcm_buf, oss->wpos << hw->info.shift); +void *pcm =advance (buf, pos); - bytes_written =write (oss->fd, pcm, bytes_to_write); + bytes_written =write (oss->fd, pcm, len);if (bytes_written <0 ) {if (errno !=EAGAIN ) { -oss_logerr (errno,"failed to write %d bytes\n" , - bytes_to_write); +oss_logerr (errno,"failed to write %zu bytes\n" , + len); } -break ; - } - -if (bytes_written & hw->info.align) { -dolog ("misaligned write asked for %d, but got %zd\n" , - bytes_to_write, bytes_written); -return ; +return pos; } - samples_written = bytes_written >> hw->info.shift; - oss->pending -= samples_written; - oss->wpos = (oss->wpos + samples_written) % hw->samples; -if (bytes_written - bytes_to_write) { + pos += bytes_written; +if (bytes_written < len) {break ; } + len -= bytes_written; } -} - -static int oss_run_out (HWVoiceOut *hw,int live) -{ -OSSVoiceOut *oss = (OSSVoiceOut *) hw; -int err, decr; -struct audio_buf_info abinfo; -struct count_info cntinfo; -int bufsize; - - bufsize = hw->samples << hw->info.shift; - -if (oss->mmapped) { -int bytes, pos; - - err =ioctl (oss->fd,SNDCTL_DSP_GETOPTR , &cntinfo); -if (err <0 ) { -oss_logerr (errno,"SNDCTL_DSP_GETOPTR failed\n" ); -return 0 ; - } - - pos = hw->rpos << hw->info.shift; - bytes =audio_ring_dist (cntinfo.ptr, pos, bufsize); - decr =MIN (bytes >> hw->info.shift, live); - } -else { - err =ioctl (oss->fd,SNDCTL_DSP_GETOSPACE , &abinfo); -if (err <0 ) { -oss_logerr (errno,"SNDCTL_DSP_GETOPTR failed\n" ); -return 0 ; - } - -if (abinfo.bytes > bufsize) { -trace_oss_invalid_available_size (abinfo.bytes, bufsize); - abinfo.bytes = bufsize; - } - -if (abinfo.bytes <0 ) { -trace_oss_invalid_available_size (abinfo.bytes, bufsize); -return 0 ; - } - - decr =MIN (abinfo.bytes >> hw->info.shift, live); -if (!decr) { -return 0 ; - } - } - - decr =audio_pcm_hw_clip_out (hw, oss->pcm_buf, decr, oss->pending); - oss->pending += decr; -oss_write_pending (oss); - -return decr; +return pos; }static void oss_fini_out (HWVoiceOut *hw)
@@ -474,18 +460,13 @@ static void oss_fini_out (HWVoiceOut *hw)ldebug ("oss_fini\n" );oss_anal_close (&oss->fd); -if (oss->pcm_buf) { -if (oss->mmapped) { - err =munmap (oss->pcm_buf, hw->samples << hw->info.shift); -if (err) { -oss_logerr (errno,"Failed to unmap buffer %p, size %zu\n" , - oss->pcm_buf, hw->samples << hw->info.shift); - } +if (oss->mmapped && hw->buf_emul) { + err =munmap (hw->buf_emul, hw->size_emul); +if (err) { +oss_logerr (errno,"Failed to unmap buffer %p, size %zu\n" , + hw->buf_emul, hw->size_emul); } -else { -g_free (oss->pcm_buf); - } - oss->pcm_buf =NULL ; + hw->buf_emul =NULL ; } }
@@ -536,19 +517,20 @@ static int oss_init_out(HWVoiceOut *hw, struct audsettings *as, oss->mmapped =0 ;if (oopts->has_try_mmap && oopts->try_mmap) { - oss->pcm_buf =mmap ( + hw->size_emul = hw->samples << hw->info.shift; + hw->buf_emul =mmap (NULL , - hw->samples << hw->info.shift, + hw->size_emul,PROT_READ |PROT_WRITE ,MAP_SHARED , fd,0 ); -if (oss->pcm_buf ==MAP_FAILED ) { +if (hw->buf_emul ==MAP_FAILED ) {oss_logerr (errno,"Failed to map %zu bytes of DAC\n" , - hw->samples << hw->info.shift); - } -else { + hw->size_emul); + hw->buf_emul =NULL ; + }else {int err;int trig =0 ;if (ioctl (fd,SNDCTL_DSP_SETTRIGGER , &trig) <0 ) {
@@ -568,32 +550,16 @@ static int oss_init_out(HWVoiceOut *hw, struct audsettings *as, }if (!oss->mmapped) { - err =munmap (oss->pcm_buf, hw->samples << hw->info.shift); + err =munmap (hw->buf_emul, hw->size_emul);if (err) {oss_logerr (errno,"Failed to unmap buffer %p size %zu\n" , - oss->pcm_buf, hw->samples << hw->info.shift); + hw->buf_emul, hw->size_emul); } + hw->buf_emul =NULL ; } } } -if (!oss->mmapped) { - oss->pcm_buf =audio_calloc ( -AUDIO_FUNC , - hw->samples, -1 << hw->info.shift - ); -if (!oss->pcm_buf) { -dolog ( -"Could not allocate DAC buffer (%zu samples, each %d bytes)\n" , - hw->samples, -1 << hw->info.shift - ); -oss_anal_close (&fd); -return -1 ; - } - } - oss->fd = fd; oss->dev = dev;return 0 ;
@@ -621,7 +587,7 @@ static int oss_ctl_out (HWVoiceOut *hw, int cmd, ...)return 0 ; } -audio_pcm_info_clear_buf (&hw->info, oss->pcm_buf, hw->samples); +audio_pcm_info_clear_buf (&hw->info, hw->buf_emul, hw->samples); trig =PCM_ENABLE_OUTPUT ;if (ioctl (oss->fd,SNDCTL_DSP_SETTRIGGER , &trig) <0 ) { oss_logerr (
@@ -695,13 +661,6 @@ static int oss_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque) } hw->samples = (obt.nfrags * obt.fragsize) >> hw->info.shift; - oss->pcm_buf =audio_calloc (AUDIO_FUNC , hw->samples,1 << hw->info.shift); -if (!oss->pcm_buf) { -dolog ("Could not allocate ADC buffer (%zu samples, each %d bytes)\n" , - hw->samples,1 << hw->info.shift); -oss_anal_close (&fd); -return -1 ; - } oss->fd = fd; oss->dev = dev;
@@ -713,78 +672,36 @@ static void oss_fini_in (HWVoiceIn *hw)OSSVoiceIn *oss = (OSSVoiceIn *) hw;oss_anal_close (&oss->fd); - -g_free (oss->pcm_buf); - oss->pcm_buf =NULL ; } -static int oss_run_in (HWVoiceIn *hw) +static size_t oss_read (HWVoiceIn *hw,void *buf,size_t len) {OSSVoiceIn *oss = (OSSVoiceIn *) hw; -int hwshift = hw->info.shift; -int i; -int live =audio_pcm_hw_get_live_in (hw); -int dead = hw->samples - live; -size_t read_samples =0 ; -struct { -int add; -int len; - } bufs[2 ] = { - { .add = hw->wpos, .len =0 }, - { .add =0 , .len =0 } - }; +size_t pos =0 ; -if (!dead) { -return 0 ; - } - -if (hw->wpos + dead > hw->samples) { - bufs[0 ].len = (hw->samples - hw->wpos) << hwshift; - bufs[1 ].len = (dead - (hw->samples - hw->wpos)) << hwshift; - } -else { - bufs[0 ].len = dead << hwshift; - } - -for (i =0 ; i <2 ; ++i) { +while (len) {ssize_t nread; -if (bufs[i].len) { -void *p =advance (oss->pcm_buf, bufs[i].add << hwshift); - nread =read (oss->fd, p, bufs[i].len); +void *dst =advance (buf, pos); + nread =read (oss->fd, dst, len); -if (nread >0 ) { -if (nread & hw->info.align) { -dolog ("warning: Misaligned read %zd (requested %d), " -"alignment %d\n" , nread, bufs[i].add << hwshift, - hw->info.align +1 ); - } - read_samples += nread >> hwshift; - hw->conv (hw->conv_buf + bufs[i].add, p, nread >> hwshift); - } - -if (bufs[i].len - nread) { -if (nread ==-1 ) { -switch (errno) { -case EINTR : -case EAGAIN : -break ; -default : -oss_logerr ( - errno, -"Failed to read %d bytes of audio (to %p)\n" , - bufs[i].len, p - ); -break ; - } - } +if (nread ==-1 ) { +switch (errno) { +case EINTR : +case EAGAIN : +break ; +default : +oss_logerr (errno,"Failed to read %zu bytes of audio (to %p)\n" , + len, dst);break ; } } + + pos += nread; + len -= nread; } - hw->wpos = (hw->wpos + read_samples) % hw->samples; -return read_samples; +return pos; }static int oss_ctl_in (HWVoiceIn *hw,int cmd, ...)
@@ -837,12 +754,14 @@ static void oss_audio_fini (void *opaque)static struct audio_pcm_ops oss_pcm_ops = { .init_out = oss_init_out, .fini_out = oss_fini_out, - .run_out = oss_run_out, + .write = oss_write, + .get_buffer_out = oss_get_buffer_out, + .put_buffer_out = oss_put_buffer_out, .ctl_out = oss_ctl_out, .init_in = oss_init_in, .fini_in = oss_fini_in, - .run_in = oss_run_in, + .read = oss_read, .ctl_in = oss_ctl_in };
Signature · 1 line
2.5.0
PATCH v2 41/49 paaudio: port to the new audio backend api
In reply to Kővágó, Zoltán--- audio/Makefile.objs | 1 - audio/audio_pt_int.c | 173 ----------------------- audio/audio_pt_int.h | 22 --- audio/paaudio.c | 378 +++++++-------------------------------------------- configure | 5 - 5 files changed, 47 insertions(+), 532 deletions(-) delete mode 100644 audio/audio_pt_int.c delete mode 100644 audio/audio_pt_int.h
audio/Makefile.objs +0 -1
@@ -6,7 +6,6 @@ common-obj-$(CONFIG_COREAUDIO) += coreaudio.o common-obj-$(CONFIG_ALSA) += alsaaudio.o common-obj-$(CONFIG_DSOUND) += dsoundaudio.o common-obj-$(CONFIG_PA) += paaudio.o -common-obj-$(CONFIG_AUDIO_PT_INT) += audio_pt_int.o common-obj-$(CONFIG_AUDIO_WIN_INT) += audio_win_int.o common-obj-y += wavcapture.o
audio/audio_pt_int.c deleted +0 -173
173 lines not on this page · raw message
audio/audio_pt_int.h deleted +0 -22
@@ -1,22 +0,0 @@ -#ifndef QEMU_AUDIO_PT_INT_H -#define QEMU_AUDIO_PT_INT_H - -#include <pthread.h> - -struct audio_pt { -const char *drv; -pthread_t thread; -pthread_cond_t cond; -pthread_mutex_t mutex; -}; - -int audio_pt_init (struct audio_pt *,void *(*) (void *),void *, -const char *,const char *); -int audio_pt_fini (struct audio_pt *,const char *); -int audio_pt_lock (struct audio_pt *,const char *); -int audio_pt_unlock (struct audio_pt *,const char *); -int audio_pt_wait (struct audio_pt *,const char *); -int audio_pt_unlock_and_signal (struct audio_pt *,const char *); -int audio_pt_join (struct audio_pt *,void **,const char *); - -#endif /* audio_pt_int.h */
audio/paaudio.c +47 -331
515 lines not on this page · raw message
configure +0 -5
@@ -205,7 +205,6 @@ block_drv_ro_whitelist="" host_cc="cc" libs_softmmu="" libs_tools="" -audio_pt_int="" audio_win_int="" cc_i386=i386-pc-linux-gnu-gcc libs_qga=""
@@ -2655,7 +2654,6 @@ for drv in $audio_drv_list; do audio_drv_probe $drv pulse/mainloop.h "-lpulse" \ "pa_mainloop *m = 0; pa_mainloop_free (m); return 0;" libs_softmmu="-lpulse $libs_softmmu" - audio_pt_int="yes" ;; coreaudio)
@@ -4725,9 +4723,6 @@ for drv in $audio_drv_list; do def=CONFIG_`echo $drv | LC_ALL=C tr '[a-z]' '[A-Z]'` echo "$def=y" >> $config_host_mak done -if test "$audio_pt_int" = "yes" ; then - echo "CONFIG_AUDIO_PT_INT=y" >> $config_host_mak -fi if test "$audio_win_int" = "yes" ; then echo "CONFIG_AUDIO_WIN_INT=y" >> $config_host_mak fi
Signature · 1 line
2.5.0
PATCH v2 42/49 sdlaudio: port to the new audio backend api
In reply to Kővágó, Zoltán--- audio/sdlaudio.c | 102 ++++++++++++++++++++++--------------------------------- 1 file changed, 41 insertions(+), 61 deletions(-)
audio/sdlaudio.c +41 -61
@@ -39,9 +39,6 @@typedef struct SDLVoiceOut {HWVoiceOut hw; -int live; -int rpos; -int decr; }SDLVoiceOut ; static struct SDLAudioState {
@@ -230,16 +227,12 @@ static void sdl_callback (void *opaque, Uint8 *buf, int len)SDLVoiceOut *sdl = opaque;SDLAudioState *s = &glob_sdl;HWVoiceOut *hw = &sdl->hw; -int samples = len >> hw->info.shift;if (s->exit) {return ; } -while (samples) { -int to_mix, decr; - -/* dolog ("in callback samples=%d\n", samples); */ +while (len) {sdl_wait (s,"sdl_callback" );if (s->exit) {return ;
@@ -249,34 +242,23 @@ static void sdl_callback (void *opaque, Uint8 *buf, int len)return ; } -if (audio_bug (AUDIO_FUNC , sdl->live <0 || sdl->live > hw->samples)) { -dolog ("sdl->live=%d hw->samples=%zu\n" , - sdl->live, hw->samples); -return ; - } - -if (!sdl->live) { - goto again; - } +while (hw->pending_emul && len) { +size_t write_len; +ssize_t start = ((ssize_t ) hw->pos_emul) - hw->pending_emul; +if (start <0 ) { + start += hw->size_emul; + } +assert (start >=0 && start < hw->size_emul); -/* dolog ("in callback live=%d\n", live); */ - to_mix =MIN (samples, sdl->live); - decr = to_mix; -while (to_mix) { -int chunk =MIN (to_mix, hw->samples - hw->rpos); -struct st_sample *src = hw->mix_buf + hw->rpos; + write_len =MIN (MIN (hw->pending_emul, len), + hw->size_emul - start); -/* dolog ("in callback to_mix %d, chunk %d\n", to_mix, chunk); */ - hw->clip (buf, src, chunk); - sdl->rpos = (sdl->rpos + chunk) % hw->samples; - to_mix -= chunk; - buf += chunk << hw->info.shift; +memcpy (buf, hw->buf_emul + start, write_len); + hw->pending_emul -= write_len; + len -= write_len; + buf += write_len; } - samples -= decr; - sdl->live -= decr; - sdl->decr += decr; - again:if (sdl_unlock (s,"sdl_callback" )) {return ; }
@@ -284,37 +266,33 @@ static void sdl_callback (void *opaque, Uint8 *buf, int len)/* dolog ("done len=%d\n", len); */ } -static int sdl_run_out (HWVoiceOut *hw,int live) -{ -int decr; -SDLVoiceOut *sdl = (SDLVoiceOut *) hw; -SDLAudioState *s = &glob_sdl; - -if (sdl_lock (s,"sdl_run_out" )) { -return 0 ; - } - -if (sdl->decr > live) { -ldebug ("sdl->decr %d live %d sdl->live %d\n" , - sdl->decr, - live, - sdl->live); +#define SDL_WRAPPER_FUNC (name, ret_type, args_decl, args, fail, unlock) \ + static ret_type glue(sdl_, name)args_decl \ + { \ + SDLAudioState *s = &glob_sdl; \ + ret_type ret; \ + \ + if (sdl_lock(s, "sdl_" #name)) { \ + fail; \ + return 0;/* implicitly casts to NULL */ \ + } \ + \ + ret = glue(audio_generic_, name)args; \ + \ + unlock(s, "sdl_" #name); \ + return ret; \ } - decr =MIN (sdl->decr, live); - sdl->decr -= decr; +SDL_WRAPPER_FUNC(get_buffer_out, void *, (HWVoiceOut *hw, size_t *size), + (hw, size), *size = 0, sdl_unlock) +SDL_WRAPPER_FUNC (put_buffer_out_nowrite, size_t, + (HWVoiceOut *hw, void *buf, size_t size), (hw, buf, size), + /*nothing*/, sdl_unlock_and_post) +SDL_WRAPPER_FUNC (write, size_t, + (HWVoiceOut *hw, void *buf, size_t size), (hw, buf, size), + /* nothing */, sdl_unlock_and_post) - sdl->live = live - decr; - hw->rpos = sdl->rpos; - -if (sdl->live >0 ) { -sdl_unlock_and_post (s,"sdl_run_out" ); - } -else { -sdl_unlock (s,"sdl_run_out" ); - } -return decr; -} +#undef SDL_WRAPPER_FUNCstatic void sdl_fini_out (HWVoiceOut *hw) {
@@ -428,7 +406,9 @@ static void sdl_audio_fini (void *opaque)static struct audio_pcm_ops sdl_pcm_ops = { .init_out = sdl_init_out, .fini_out = sdl_fini_out, - .run_out = sdl_run_out, + .write = sdl_write, + .get_buffer_out = sdl_get_buffer_out, + .put_buffer_out = sdl_put_buffer_out_nowrite, .ctl_out = sdl_ctl_out, };
Signature · 1 line
2.5.0
PATCH v2 44/49 wavaudio: port to the new audio backend api
In reply to Kővágó, Zoltán--- audio/wavaudio.c | 55 +++++++++---------------------------------------------- 1 file changed, 9 insertions(+), 46 deletions(-)
audio/wavaudio.c +9 -46
@@ -33,52 +33,27 @@ typedef struct WAVVoiceOut {HWVoiceOut hw;FILE *f;int64_t old_ticks; -void *pcm_buf;int total_samples; } WAVVoiceOut; -static int wav_run_out (HWVoiceOut *hw,int live) +static size_t wav_write_out (HWVoiceOut *hw,void *buf,size_t len) {WAVVoiceOut *wav = (WAVVoiceOut *) hw; -int rpos, decr, samples; -uint8_t *dst; -struct st_sample *src;int64_t now =qemu_clock_get_ns (QEMU_CLOCK_VIRTUAL );int64_t ticks = now - wav->old_ticks;int64_t bytes =muldiv64 (ticks, hw->info.bytes_per_second,get_ticks_per_sec ()); - -if (bytes >INT_MAX ) { - samples =INT_MAX >> hw->info.shift; - } -else { - samples = bytes >> hw->info.shift; - } - + bytes =MIN (bytes, len); + bytes = bytes >> hw->info.shift << hw->info.shift; wav->old_ticks = now; - decr =MIN (live, samples); - samples = decr; - rpos = hw->rpos; -while (samples) { -int left_till_end_samples = hw->samples - rpos; -int convert_samples =MIN (samples, left_till_end_samples); - src = hw->mix_buf + rpos; - dst =advance (wav->pcm_buf, rpos << hw->info.shift); - - hw->clip (dst, src, convert_samples); -if (fwrite (dst, convert_samples << hw->info.shift,1 , wav->f) !=1 ) { -dolog ("wav_run_out: fwrite of %d bytes failed\nReaons: %s\n" , - convert_samples << hw->info.shift,strerror (errno)); - } - - rpos = (rpos + convert_samples) % hw->samples; - samples -= convert_samples; - wav->total_samples += convert_samples; +if (bytes &&fwrite (buf, bytes,1 , wav->f) !=1 ) { +dolog ("wav_write_out: fwrite of %zu bytes failed\nReaons: %s\n" , + bytes,strerror (errno)); } - hw->rpos = rpos; -return decr; + wav->total_samples += bytes >> hw->info.shift; +return bytes; }/* VICE code: Store number as little endian. */
@@ -134,13 +109,6 @@ static int wav_init_out(HWVoiceOut *hw, struct audsettings *as,audio_pcm_init_info (&hw->info, &wav_as); hw->samples =1024 ; - wav->pcm_buf =audio_calloc (AUDIO_FUNC , hw->samples,1 << hw->info.shift); -if (!wav->pcm_buf) { -dolog ("Could not allocate buffer (%zu bytes)\n" , - hw->samples << hw->info.shift); -return -1 ; - } -le_store (hdr +22 , hw->info.nchannels,2 );le_store (hdr +24 , hw->info.freq,4 );le_store (hdr +28 , hw->info.freq << (bits16 + stereo),4 );
@@ -150,8 +118,6 @@ static int wav_init_out(HWVoiceOut *hw, struct audsettings *as,if (!wav->f) {dolog ("Failed to open wave file `%s'\nReason: %s\n" , wav_path,strerror (errno)); -g_free (wav->pcm_buf); - wav->pcm_buf =NULL ;return -1 ; }
@@ -205,9 +171,6 @@ static void wav_fini_out (HWVoiceOut *hw) wav->f, strerror (errno)); } wav->f =NULL ; - -g_free (wav->pcm_buf); - wav->pcm_buf =NULL ; }static int wav_ctl_out (HWVoiceOut *hw,int cmd, ...)
@@ -231,7 +194,7 @@ static void wav_audio_fini (void *opaque)static struct audio_pcm_ops wav_pcm_ops = { .init_out = wav_init_out, .fini_out = wav_fini_out, - .run_out = wav_run_out, + .write = wav_write_out, .ctl_out = wav_ctl_out, };
Signature · 1 line
2.5.0
PATCH v2 45/49 audio: remove remains of the old backend api
In reply to Kővágó, Zoltán--- audio/audio.c | 42 ++++++------------------------------------ audio/audio_int.h | 7 ------- 2 files changed, 6 insertions(+), 43 deletions(-)
audio/audio.c +6 -36
@@ -512,7 +512,7 @@ static size_t audio_pcm_hw_find_min_in (HWVoiceIn *hw)return m; } -size_t audio_pcm_hw_get_live_in (HWVoiceIn *hw) +static size_t audio_pcm_hw_get_live_in (HWVoiceIn *hw) {size_t live = hw->total_samples_captured -audio_pcm_hw_find_min_in (hw);if (audio_bug (AUDIO_FUNC , live > hw->samples)) {
@@ -522,29 +522,7 @@ size_t audio_pcm_hw_get_live_in(HWVoiceIn *hw)return live; } -size_t audio_pcm_hw_clip_out (HWVoiceOut *hw,void *pcm_buf, -size_t live,size_t pending) -{ -size_t left = hw->samples - pending; -size_t len =MIN (left, live); -size_t clipped =0 ; - -while (len) { -struct st_sample *src = hw->mix_buf + hw->rpos; -uint8_t *dst =advance (pcm_buf, hw->rpos << hw->info.shift); -size_t samples_till_end_of_buf = hw->samples - hw->rpos; -size_t samples_to_clip =MIN (len, samples_till_end_of_buf); - - hw->clip (dst, src, samples_to_clip); - - hw->rpos = (hw->rpos + samples_to_clip) % hw->samples; - len -= samples_to_clip; - clipped += samples_to_clip; - } -return clipped; -} - -static void audio_pcm_hw_clip_out2 (HWVoiceOut *hw,void *pcm_buf,size_t len) +static void audio_pcm_hw_clip_out (HWVoiceOut *hw,void *pcm_buf,size_t len) {size_t clipped =0 ;size_t pos = hw->rpos;
@@ -1033,7 +1011,7 @@ static size_t audio_pcm_hw_run_out(HWVoiceOut *hw, size_t live)void *buf = hw->pcm_ops->get_buffer_out (hw, &size); decr =MIN (size >> hw->info.shift, live); -audio_pcm_hw_clip_out2 (hw, buf, decr); +audio_pcm_hw_clip_out (hw, buf, decr); proc = hw->pcm_ops->put_buffer_out (hw, buf, decr << hw->info.shift) >> hw->info.shift;
@@ -1096,11 +1074,7 @@ static void audio_run_out (AudioState *s) } prev_rpos = hw->rpos; -if (hw->pcm_ops->run_out) { - played = hw->pcm_ops->run_out (hw, live); - }else { - played =audio_pcm_hw_run_out (hw, live); - } + played =audio_pcm_hw_run_out (hw, live);if (audio_bug (AUDIO_FUNC , hw->rpos >= hw->samples)) {dolog ("rpos=%zu samples=%zu played=%zu\n" , hw->rpos, hw->samples, played);
@@ -1195,12 +1169,8 @@ static void audio_run_in (AudioState *s)SWVoiceIn *sw;size_t captured, min; -if (hw->pcm_ops->run_in) { - captured = hw->pcm_ops->run_in (hw); - }else { - captured =audio_pcm_hw_run_in ( - hw, hw->samples -audio_pcm_hw_get_live_in (hw)); - } + captured =audio_pcm_hw_run_in ( + hw, hw->samples -audio_pcm_hw_get_live_in (hw)); min =audio_pcm_hw_find_min_in (hw); hw->total_samples_captured += captured - min;
audio/audio_int.h +0 -7
@@ -149,7 +149,6 @@ struct audio_driver {struct audio_pcm_ops {int (*init_out)(HWVoiceOut *hw,audsettings *as,void *drv_opaque);void (*fini_out)(HWVoiceOut *hw); -int (*run_out) (HWVoiceOut *hw,int live);size_t (*write) (HWVoiceOut *hw,void *buf,size_t size);/* get a buffer that after later can be passed to put_buffer_out; optional * returns the buffer, and writes it's size to size (in bytes)
@@ -163,7 +162,6 @@ struct audio_pcm_ops {int (*init_in) (HWVoiceIn *hw,audsettings *as,void *drv_opaque);void (*fini_in) (HWVoiceIn *hw); -int (*run_in) (HWVoiceIn *hw);size_t (*read) (HWVoiceIn *hw,void *buf,size_t size);void *(*get_buffer_in)(HWVoiceIn *hw,size_t *size);void (*put_buffer_in)(HWVoiceIn *hw,void *buf,size_t size);
@@ -232,11 +230,6 @@ 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); -size_t audio_pcm_hw_get_live_in (HWVoiceIn *hw); - -size_t audio_pcm_hw_clip_out (HWVoiceOut *hw,void *pcm_buf, -size_t live,size_t pending); -int audio_bug (const char *funcname,int cond);void *audio_calloc (const char *funcname,int nmemb,size_t size);
Signature · 1 line
2.5.0
PATCH v2 46/49 audio: unify input and output mixeng buffer management
In reply to Kővágó, Zoltán--- audio/audio.c | 123 +++++++++++++++++++++++-------------------------- audio/audio_int.h | 12 +++-- audio/audio_template.h | 18 +++----- 3 files changed, 71 insertions(+), 82 deletions(-)
audio/audio.c +58 -65
@@ -515,8 +515,8 @@ static size_t audio_pcm_hw_find_min_in (HWVoiceIn *hw)static size_t audio_pcm_hw_get_live_in (HWVoiceIn *hw) {size_t live = hw->total_samples_captured -audio_pcm_hw_find_min_in (hw); -if (audio_bug (AUDIO_FUNC , live > hw->samples)) { -dolog ("live=%zu samples=%zu\n" , live, hw->samples); +if (audio_bug (AUDIO_FUNC , live > hw->conv_buf->size)) { +dolog ("live=%zu samples=%zu\n" , live, hw->conv_buf->size);return 0 ; }return live;
@@ -525,17 +525,17 @@ static size_t audio_pcm_hw_get_live_in(HWVoiceIn *hw)static void audio_pcm_hw_clip_out (HWVoiceOut *hw,void *pcm_buf,size_t len) {size_t clipped =0 ; -size_t pos = hw->rpos; +size_t pos = hw->mix_buf->pos;while (len) { -st_sample *src = hw->mix_buf + pos; +st_sample *src = hw->mix_buf->samples + pos;uint8_t *dst =advance (pcm_buf, clipped << hw->info.shift); -size_t samples_till_end_of_buf = hw->samples - pos; +size_t samples_till_end_of_buf = hw->mix_buf->size - pos;size_t samples_to_clip =MIN (len, samples_till_end_of_buf); hw->clip (dst, src, samples_to_clip); - pos = (pos + samples_to_clip) % hw->samples; + pos = (pos + samples_to_clip) % hw->mix_buf->size; len -= samples_to_clip; clipped += samples_to_clip; }
@@ -550,17 +550,17 @@ static size_t audio_pcm_sw_get_rpos_in(SWVoiceIn *sw)ssize_t live = hw->total_samples_captured - sw->total_hw_samples_acquired;ssize_t rpos; -if (audio_bug (AUDIO_FUNC , live <0 || live > hw->samples)) { -dolog ("live=%zd samples=%zu\n" , live, hw->samples); +if (audio_bug (AUDIO_FUNC , live <0 || live > hw->conv_buf->size)) { +dolog ("live=%zd samples=%zu\n" , live, hw->conv_buf->size);return 0 ; } - rpos = hw->wpos - live; + rpos = hw->conv_buf->pos - live;if (rpos >=0 ) {return rpos; }else { -return hw->samples + rpos; +return hw->conv_buf->size + rpos; } }
@@ -570,11 +570,11 @@ static size_t audio_pcm_sw_read(SWVoiceIn *sw, void *buf, size_t size)size_t samples, live, ret =0 , swlim, isamp, osamp, rpos, total =0 ;struct st_sample *src, *dst = sw->buf; - rpos =audio_pcm_sw_get_rpos_in (sw) % hw->samples; + rpos =audio_pcm_sw_get_rpos_in (sw) % hw->conv_buf->size; live = hw->total_samples_captured - sw->total_hw_samples_acquired; -if (audio_bug (AUDIO_FUNC , live > hw->samples)) { -dolog ("live_in=%zu samples=%zu\n" , live, hw->samples); +if (audio_bug (AUDIO_FUNC , live > hw->conv_buf->size)) { +dolog ("live_in=%zu samples=%zu\n" , live, hw->conv_buf->size);return 0 ; }
@@ -587,11 +587,11 @@ static size_t audio_pcm_sw_read(SWVoiceIn *sw, void *buf, size_t size) swlim =MIN (swlim, samples);while (swlim) { - src = hw->conv_buf + rpos; -if (hw->wpos > rpos) { - isamp = hw->wpos - rpos; + src = hw->conv_buf->samples + rpos; +if (hw->conv_buf->pos > rpos) { + isamp = hw->conv_buf->pos - rpos; }else { - isamp = hw->samples - rpos; + isamp = hw->conv_buf->size - rpos; }if (!isamp) {
@@ -601,7 +601,7 @@ static size_t audio_pcm_sw_read(SWVoiceIn *sw, void *buf, size_t size)st_rate_flow (sw->rate, src, dst, &isamp, &osamp); swlim -= osamp; - rpos = (rpos + isamp) % hw->samples; + rpos = (rpos + isamp) % hw->conv_buf->size; dst += osamp; ret += osamp; total += isamp;
@@ -649,8 +649,8 @@ static size_t audio_pcm_hw_get_live_out (HWVoiceOut *hw, int *nb_live)if (nb_live1) {size_t live = smin; -if (audio_bug (AUDIO_FUNC , live > hw->samples)) { -dolog ("live=%zu hw->samples=%zu\n" , live, hw->samples); +if (audio_bug (AUDIO_FUNC , live > hw->mix_buf->size)) { +dolog ("live=%zu hw->samples=%zu\n" , live, hw->mix_buf->size);return 0 ; }return live;
@@ -671,7 +671,7 @@ static size_t audio_pcm_sw_write(SWVoiceOut *sw, void *buf, size_t size)return size; } - hwsamples = sw->hw->samples; + hwsamples = sw->hw->mix_buf->size; live = sw->total_hw_samples_mixed;if (audio_bug (AUDIO_FUNC , live > hwsamples)){
@@ -686,7 +686,7 @@ static size_t audio_pcm_sw_write(SWVoiceOut *sw, void *buf, size_t size)return 0 ; } - wpos = (sw->hw->rpos + live) % hwsamples; + wpos = (sw->hw->mix_buf->pos + live) % hwsamples; samples = size >> sw->info.shift; dead = hwsamples - live;
@@ -712,7 +712,7 @@ static size_t audio_pcm_sw_write(SWVoiceOut *sw, void *buf, size_t size)st_rate_flow_mix ( sw->rate, sw->buf + pos, - sw->hw->mix_buf + wpos, + sw->hw->mix_buf->samples + wpos, &isamp, &osamp );
@@ -823,7 +823,7 @@ size_t AUD_read(SWVoiceIn *sw, void *buf, size_t size)int AUD_get_buffer_size_out (SWVoiceOut *sw) { -return sw->hw->samples << sw->hw->info.shift; +return sw->hw->mix_buf->size << sw->hw->info.shift; }void AUD_set_active_out (SWVoiceOut *sw,int on)
@@ -924,8 +924,8 @@ static size_t audio_get_avail (SWVoiceIn *sw) } live = sw->hw->total_samples_captured - sw->total_hw_samples_acquired; -if (audio_bug (AUDIO_FUNC , live > sw->hw->samples)) { -dolog ("live=%zu samples=%zu\n" , live, sw->hw->samples); +if (audio_bug (AUDIO_FUNC , live > sw->hw->conv_buf->size)) { +dolog ("live=%zu samples=%zu\n" , live, sw->hw->conv_buf->size);return 0 ; }
@@ -948,12 +948,12 @@ static size_t audio_get_free(SWVoiceOut *sw) live = sw->total_hw_samples_mixed; -if (audio_bug (AUDIO_FUNC , live > sw->hw->samples)) { -dolog ("live=%zu samples=%zu\n" , live, sw->hw->samples); +if (audio_bug (AUDIO_FUNC , live > sw->hw->mix_buf->size)) { +dolog ("live=%zu samples=%zu\n" , live, sw->hw->mix_buf->size);return 0 ; } - dead = sw->hw->samples - live; + dead = sw->hw->mix_buf->size - live;#ifdef DEBUG_OUT dolog ("%s: get_free live %d dead %d ret %" PRId64 "\n",
@@ -978,12 +978,12 @@ static void audio_capture_mix_and_clear(HWVoiceOut *hw, size_t rpos, n = samples;while (n) { -size_t till_end_of_hw = hw->samples - rpos2; +size_t till_end_of_hw = hw->mix_buf->size - rpos2;size_t to_write =MIN (till_end_of_hw, n);size_t bytes = to_write << hw->info.shift;size_t written; - sw->buf = hw->mix_buf + rpos2; + sw->buf = hw->mix_buf->samples + rpos2; written =audio_pcm_sw_write (sw,NULL , bytes);if (written - bytes) { dolog("Could not mix %zu bytes into a capture "
@@ -992,14 +992,14 @@ static void audio_capture_mix_and_clear(HWVoiceOut *hw, size_t rpos,break ; } n -= to_write; - rpos2 = (rpos2 + to_write) % hw->samples; + rpos2 = (rpos2 + to_write) % hw->mix_buf->size; } } } - n =MIN (samples, hw->samples - rpos); -mixeng_clear (hw->mix_buf + rpos, n); -mixeng_clear (hw->mix_buf, samples - n); + n =MIN (samples, hw->mix_buf->size - rpos); +mixeng_clear (hw->mix_buf->samples + rpos, n); +mixeng_clear (hw->mix_buf->samples, samples - n); }static size_t audio_pcm_hw_run_out (HWVoiceOut *hw,size_t live)
@@ -1017,7 +1017,7 @@ static size_t audio_pcm_hw_run_out(HWVoiceOut *hw, size_t live) live -= proc; clipped += proc; - hw->rpos = (hw->rpos + proc) % hw->samples; + hw->mix_buf->pos = (hw->mix_buf->pos + proc) % hw->mix_buf->size;if (proc ==0 || proc < decr) {break ;
@@ -1041,8 +1041,8 @@ static void audio_run_out (AudioState *s) live =0 ; } -if (audio_bug (AUDIO_FUNC , live > hw->samples)) { -dolog ("live=%zu samples=%zu\n" , live, hw->samples); +if (audio_bug (AUDIO_FUNC , live > hw->mix_buf->size)) { +dolog ("live=%zu samples=%zu\n" , live, hw->mix_buf->size);continue ; }
@@ -1073,12 +1073,12 @@ static void audio_run_out (AudioState *s)continue ; } - prev_rpos = hw->rpos; + prev_rpos = hw->mix_buf->pos; played =audio_pcm_hw_run_out (hw, live); -if (audio_bug (AUDIO_FUNC , hw->rpos >= hw->samples)) { +if (audio_bug (AUDIO_FUNC , hw->mix_buf->pos >= hw->mix_buf->size)) {dolog ("rpos=%zu samples=%zu played=%zu\n" , - hw->rpos, hw->samples, played); - hw->rpos =0 ; + hw->mix_buf->pos, hw->mix_buf->size, played); + hw->mix_buf->pos =0 ; }#ifdef DEBUG_OUT
@@ -1135,6 +1135,7 @@ static void audio_run_out (AudioState *s)static size_t audio_pcm_hw_run_in (HWVoiceIn *hw,size_t samples) {size_t conv =0 ; +STSampleBuffer *conv_buf = hw->conv_buf;while (samples) {size_t proc;
@@ -1148,10 +1149,10 @@ static size_t audio_pcm_hw_run_in(HWVoiceIn *hw, size_t samples) } proc =MIN (size >> hw->info.shift, - hw->samples - hw->wpos); + conv_buf->size - conv_buf->pos); - hw->conv (hw->conv_buf + hw->wpos, buf, proc); - hw->wpos = (hw->wpos + proc) % hw->samples; + hw->conv (conv_buf->samples + conv_buf->pos, buf, proc); + conv_buf->pos = (conv_buf->pos + proc) % conv_buf->size; samples -= proc; conv += proc;
@@ -1170,7 +1171,7 @@ static void audio_run_in (AudioState *s)size_t captured, min; captured =audio_pcm_hw_run_in ( - hw, hw->samples -audio_pcm_hw_get_live_in (hw)); + hw, hw->conv_buf->size -audio_pcm_hw_get_live_in (hw)); min =audio_pcm_hw_find_min_in (hw); hw->total_samples_captured += captured - min;
@@ -1201,14 +1202,14 @@ static void audio_run_capture (AudioState *s)SWVoiceOut *sw; captured = live =audio_pcm_hw_get_live_out (hw,NULL ); - rpos = hw->rpos; + rpos = hw->mix_buf->pos;while (live) { -size_t left = hw->samples - rpos; +size_t left = hw->mix_buf->size - rpos;size_t to_capture =MIN (live, left);struct st_sample *src;struct capture_callback *cb; - src = hw->mix_buf + rpos; + src = hw->mix_buf->samples + rpos; hw->clip (cap->buf, src, to_capture);mixeng_clear (src, to_capture);
@@ -1216,10 +1217,10 @@ static void audio_run_capture (AudioState *s) cb->ops.capture (cb->opaque, cap->buf, to_capture << hw->info.shift); } - rpos = (rpos + to_capture) % hw->samples; + rpos = (rpos + to_capture) % hw->mix_buf->size; live -= to_capture; } - hw->rpos = rpos; + hw->mix_buf->pos = rpos;for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {if (!sw->active && sw->empty) {
@@ -1267,7 +1268,7 @@ void *audio_generic_get_buffer_in(HWVoiceIn *hw, size_t *size)ssize_t start;if (unlikely (!hw->buf_emul)) { -size_t calc_size = hw->samples << hw->info.shift; +size_t calc_size = hw->conv_buf->size << hw->info.shift; hw->buf_emul =g_malloc (calc_size); hw->size_emul = calc_size; hw->pos_emul = hw->pending_emul =0 ;
@@ -1303,7 +1304,7 @@ void audio_generic_put_buffer_in(HWVoiceIn *hw, void *buf, size_t size)void *audio_generic_get_buffer_out (HWVoiceOut *hw,size_t *size) {if (unlikely (!hw->buf_emul)) { -size_t calc_size = hw->samples << hw->info.shift; +size_t calc_size = hw->mix_buf->size << hw->info.shift; hw->buf_emul =g_malloc (calc_size); hw->size_emul = calc_size;
@@ -1678,23 +1679,16 @@ CaptureVoiceOut *AUD_add_capture(QLIST_INIT (&hw->sw_head);QLIST_INIT (&cap->cb_head); -/* XXX find a more elegant way */ - hw->samples =4096 *4 ; - hw->mix_buf =audio_calloc (AUDIO_FUNC , hw->samples, -sizeof (struct st_sample )); -if (!hw->mix_buf) { -dolog ("Could not allocate capture mix buffer (%zu samples)\n" , - hw->samples); - goto err2; - } +audio_pcm_hw_alloc_resources_out (hw);audio_pcm_init_info (&hw->info, as); - cap->buf =audio_calloc (AUDIO_FUNC , hw->samples,1 << hw->info.shift); + cap->buf =audio_calloc (AUDIO_FUNC , hw->mix_buf->size, +1 << hw->info.shift);if (!cap->buf) {dolog ("Could not allocate capture buffer " "(%zu samples, each %d bytes)\n" , - hw->samples,1 << hw->info.shift); + hw->mix_buf->size,1 << hw->info.shift); goto err3; }
@@ -1715,7 +1709,6 @@ CaptureVoiceOut *AUD_add_capture( err3:g_free (cap->hw.mix_buf); - err2:g_free (cap); err1:g_free (cb);
audio/audio_int.h +7 -5
@@ -50,6 +50,11 @@ struct audio_pcm_info {typedef struct SWVoiceCap SWVoiceCap ; +typedef struct STSampleBuffer { +size_t pos, size; +st_sample samples[]; +}STSampleBuffer ; + typedef struct HWVoiceOut { AudioState *s; int enabled;
@@ -58,11 +63,9 @@ typedef struct HWVoiceOut {struct audio_pcm_info info;f_sample *clip; - -size_t rpos;uint64_t ts_helper; -struct st_sample *mix_buf; +STSampleBuffer *mix_buf;void *buf_emul;size_t pos_emul, pending_emul, size_emul;
@@ -82,11 +85,10 @@ typedef struct HWVoiceIn {t_sample *conv; -size_t wpos;size_t total_samples_captured;uint64_t ts_helper; -struct st_sample *conv_buf; +STSampleBuffer *conv_buf;void *buf_emul;size_t pos_emul, pending_emul, size_emul;
audio/audio_template.h +6 -12
@@ -76,16 +76,12 @@ static void glue (audio_pcm_hw_free_resources_, TYPE) (HW *hw)HWBUF =NULL ; } -static int glue (audio_pcm_hw_alloc_resources_ ,TYPE ) (HW *hw) +static void glue (audio_pcm_hw_alloc_resources_ ,TYPE )(HW *hw) { -HWBUF =audio_calloc (AUDIO_FUNC , hw->samples,sizeof (struct st_sample )); -if (!HWBUF ) { -dolog ("Could not allocate " NAME " buffer (%zu samples)\n" , - hw->samples); -return -1 ; - } +size_t samples = hw->samples; -return 0 ; +HWBUF =g_malloc0 (sizeof (STSampleBuffer) +sizeof (st_sample)*samples); +HWBUF ->size = samples; }static void glue (audio_pcm_sw_free_resources_ ,TYPE ) (SW *sw)
@@ -104,7 +100,7 @@ static int glue (audio_pcm_sw_alloc_resources_, TYPE) (SW *sw) {int samples; - samples = ((int64_t ) sw->hw->samples <<32 ) / sw->ratio; + samples = ((int64_t ) sw->HWBUF->size <<32 ) / sw->ratio; sw->buf =audio_calloc (AUDIO_FUNC , samples,sizeof (struct st_sample ));if (!sw->buf) {
@@ -280,9 +276,7 @@ static HW *glue(audio_pcm_hw_add_new_, TYPE)(AudioState *s, [hw->info.swap_endianness] [audio_bits_to_index (hw->info.bits)]; -if (glue (audio_pcm_hw_alloc_resources_,TYPE ) (hw)) { - goto err1; - } +glue (audio_pcm_hw_alloc_resources_,TYPE )(hw);QLIST_INSERT_HEAD (&s->glue (hw_head_,TYPE ), hw, entries);glue (s->nb_hw_voices_,TYPE ) -=1 ;
Signature · 1 line
2.5.0
PATCH v2 47/49 audio: remove hw->samples, buffer_size_in/out pcm_ops
In reply to Kővágó, ZoltánThis patch removes the samples member from HWVoiceIn and HWVoiceOut. Backends can specify buffer size via the newly added buffer_size_in and buffer_size_out functions in audio_pcm_ops. They are optional, if not defined qemu will fall back to some built-in constant.
---
Not sure if this is necessary. At first it seemed like a good idea to have a function so that backends can compute the size on demand when needed and things like that, but currently it's just a burden. The only good feature is that it allows a backend to not define a function and let the audio subsystem choose a default value, but the same could be achieved by specifying that hw->samples = 0 means use a default value.
So if you guys agree, I'll remove this patch. Maybe add an -audiodev parameter to change it, overriding whatever the backends supplies.
audio/alsaaudio.c | 20 ++++++++++++++++++-- audio/audio_int.h | 5 +++-- audio/audio_template.h | 16 +++++++--------- audio/coreaudio.c | 10 +++++++++- audio/dsound_template.h | 8 +++++++- audio/dsoundaudio.c | 4 ++++ audio/noaudio.c | 2 -- audio/ossaudio.c | 24 ++++++++++++++++++++---- audio/paaudio.c | 15 +++++++++++++++ audio/sdlaudio.c | 10 +++++++++- audio/spiceaudio.c | 14 ++++++++++++-- audio/wavaudio.c | 1 - 12 files changed, 104 insertions(+), 25 deletions(-)
audio/alsaaudio.c +18 -2
@@ -46,6 +46,7 @@ struct pollhlp {typedef struct ALSAVoiceOut {HWVoiceOut hw;snd_pcm_t *handle; +size_t samples;struct pollhlp pollhlp;Audiodev *dev; }ALSAVoiceOut ;
@@ -53,6 +54,7 @@ typedef struct ALSAVoiceOut {typedef struct ALSAVoiceIn {HWVoiceIn hw;snd_pcm_t *handle; +size_t samples;struct pollhlp pollhlp;Audiodev *dev; }ALSAVoiceIn ;
@@ -697,7 +699,7 @@ static int alsa_init_out(HWVoiceOut *hw, struct audsettings *as, obt_as.endianness = obt.endianness;audio_pcm_init_info (&hw->info, &obt_as); - hw->samples = obt.samples; + alsa->samples = obt.samples; alsa->pollhlp.s = hw->s; alsa->handle = handle;
@@ -705,6 +707,12 @@ static int alsa_init_out(HWVoiceOut *hw, struct audsettings *as,return 0 ; } +static size_t alsa_buffer_size_out (HWVoiceOut *hw) +{ +ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw; +return alsa->samples; +} +#define VOICE_CTL_PAUSE 0#define VOICE_CTL_PREPARE 1#define VOICE_CTL_START 2
@@ -791,7 +799,7 @@ static int alsa_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque) obt_as.endianness = obt.endianness;audio_pcm_init_info (&hw->info, &obt_as); - hw->samples = obt.samples; + alsa->samples = obt.samples; alsa->pollhlp.s = hw->s; alsa->handle = handle;
@@ -799,6 +807,12 @@ static int alsa_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque)return 0 ; } +static size_t alsa_buffer_size_in (HWVoiceIn *hw) +{ +ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw; +return alsa->samples; +} +static void alsa_fini_in (HWVoiceIn *hw) {ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;
@@ -912,11 +926,13 @@ static void alsa_audio_fini (void *opaque)static struct audio_pcm_ops alsa_pcm_ops = { .init_out = alsa_init_out, .fini_out = alsa_fini_out, + .buffer_size_out = alsa_buffer_size_out, .write = alsa_write, .ctl_out = alsa_ctl_out, .init_in = alsa_init_in, .fini_in = alsa_fini_in, + .buffer_size_in = alsa_buffer_size_in, .read = alsa_read, .ctl_in = alsa_ctl_in, };
audio/audio_int.h +3 -2
@@ -69,7 +69,6 @@ typedef struct HWVoiceOut {void *buf_emul;size_t pos_emul, pending_emul, size_emul; -size_t samples; QLIST_HEAD (sw_out_listhead, SWVoiceOut) sw_head; QLIST_HEAD (sw_cap_listhead, SWVoiceCap) cap_head;int ctl_caps;
@@ -92,7 +91,6 @@ typedef struct HWVoiceIn {void *buf_emul;size_t pos_emul, pending_emul, size_emul; -size_t samples; QLIST_HEAD (sw_in_listhead, SWVoiceIn) sw_head;int ctl_caps;struct audio_pcm_ops *pcm_ops;
@@ -152,6 +150,8 @@ struct audio_pcm_ops {int (*init_out)(HWVoiceOut *hw,audsettings *as,void *drv_opaque);void (*fini_out)(HWVoiceOut *hw);size_t (*write) (HWVoiceOut *hw,void *buf,size_t size); +/* get the optimal buffer size in samples; optional */ +size_t (*buffer_size_out)(HWVoiceOut *hw);/* get a buffer that after later can be passed to put_buffer_out; optional * returns the buffer, and writes it's size to size (in bytes) * this is unrelated to the above buffer_size_out function */
@@ -165,6 +165,7 @@ struct audio_pcm_ops {int (*init_in) (HWVoiceIn *hw,audsettings *as,void *drv_opaque);void (*fini_in) (HWVoiceIn *hw);size_t (*read) (HWVoiceIn *hw,void *buf,size_t size); +size_t (*buffer_size_in)(HWVoiceIn *hw);void *(*get_buffer_in)(HWVoiceIn *hw,size_t *size);void (*put_buffer_in)(HWVoiceIn *hw,void *buf,size_t size);int (*ctl_in) (HWVoiceIn *hw,int cmd, ...);
audio/audio_template.h +7 -9
@@ -78,7 +78,12 @@ static void glue (audio_pcm_hw_free_resources_, TYPE) (HW *hw)static void glue (audio_pcm_hw_alloc_resources_ ,TYPE )(HW *hw) { -size_t samples = hw->samples; +size_t samples; +if (hw->pcm_ops->glue (buffer_size_,TYPE )) { + samples = hw->pcm_ops->glue (buffer_size_,TYPE )(hw); + }else { + samples =1024 ;/* todo better default */ + }HWBUF =g_malloc0 (sizeof (STSampleBuffer) +sizeof (st_sample)*samples);HWBUF ->size = samples;
@@ -261,11 +266,6 @@ static HW *glue(audio_pcm_hw_add_new_, TYPE)(AudioState *s, goto err0; } -if (audio_bug (AUDIO_FUNC , hw->samples <=0 )) { -dolog ("hw->samples=%zu\n" , hw->samples); - goto err1; - } -#ifdef DAC hw->clip = mixeng_clip #else
@@ -285,9 +285,7 @@ static HW *glue(audio_pcm_hw_add_new_, TYPE)(AudioState *s,#endif return hw; - err1: -glue (hw->pcm_ops->fini_,TYPE ) (hw); - err0: +err0:g_free (hw);return NULL ; }
audio/coreaudio.c +9 -1
@@ -40,6 +40,7 @@ typedef struct coreaudioVoiceOut {AudioDeviceID outputDeviceID;UInt32 audioDevicePropertyBufferFrameSize;AudioStreamBasicDescription outputStreamBasicDescription; +size_t samples; } coreaudioVoiceOut;static void coreaudio_logstatus (OSStatus status)
@@ -366,7 +367,7 @@ static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as, "Could not get device buffer frame size\n");return -1 ; } - hw->samples = (pdo->has_buffer_count ? pdo->buffer_count :4 ) * + core->samples = (pdo->has_buffer_count ? pdo->buffer_count :4 ) * core->audioDevicePropertyBufferFrameSize;/* get StreamFormat */
@@ -435,6 +436,12 @@ static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as,return 0 ; } +static size_t coreaudio_buffer_size_out (HWVoiceOut *hw) +{ +coreaudioVoiceOut *core = (coreaudioVoiceOut *) hw; +return core->samples; +} +static void coreaudio_fini_out (HWVoiceOut *hw) {OSStatus status;
@@ -511,6 +518,7 @@ static struct audio_pcm_ops coreaudio_pcm_ops = { .init_out = coreaudio_init_out, .fini_out = coreaudio_fini_out, .write = coreaudio_write, + .buffer_size_out = coreaudio_buffer_size_out, .get_buffer_out = coreaudio_get_buffer_out, .put_buffer_out = coreaudio_put_buffer_out_nowrite, .ctl_out = coreaudio_ctl_out
audio/dsound_template.h +7 -1
@@ -254,7 +254,7 @@ static int dsound_init_out(HWVoiceOut *hw, struct audsettings *as, ); } hw->size_emul = bc.dwBufferBytes; - hw->samples = bc.dwBufferBytes >> hw->info.shift; + ds->samples = bc.dwBufferBytes >> hw->info.shift; ds->s = s;#ifdef DEBUG_DSOUND
@@ -268,6 +268,12 @@ static int dsound_init_out(HWVoiceOut *hw, struct audsettings *as,return -1 ; } +static size_t glue (dsound_buffer_size_ ,TYPE )(HWVOICE *hw) +{ +DSOUNDVOICE *ds = (DSOUNDVOICE *) hw; +return ds->samples; +} +#undef NAME#undef NAME2#undef TYPE
audio/dsoundaudio.c +4 -0
@@ -53,12 +53,14 @@ typedef struct {HWVoiceOut hw;LPDIRECTSOUNDBUFFER dsound_buffer;dsound *s; +size_t samples; } DSoundVoiceOut;typedef struct {HWVoiceIn hw;LPDIRECTSOUNDCAPTUREBUFFER dsound_capture_buffer;dsound *s; +size_t samples; }DSoundVoiceIn ;static void dsound_log_hresult (HRESULT hr)
@@ -671,6 +673,7 @@ static struct audio_pcm_ops dsound_pcm_ops = { .init_out = dsound_init_out, .fini_out = dsound_fini_out, .write = audio_generic_write, + .buffer_size_out = dsound_buffer_size_out, .get_buffer_out = dsound_get_buffer_out, .put_buffer_out = dsound_put_buffer_out, .ctl_out = dsound_ctl_out,
@@ -678,6 +681,7 @@ static struct audio_pcm_ops dsound_pcm_ops = { .init_in = dsound_init_in, .fini_in = dsound_fini_in, .read = audio_generic_read, + .buffer_size_in = dsound_buffer_size_in, .get_buffer_in = dsound_get_buffer_in, .put_buffer_in = dsound_put_buffer_in, .ctl_in = dsound_ctl_in
audio/noaudio.c +0 -2
@@ -56,7 +56,6 @@ static size_t no_write(HWVoiceOut *hw, void *buf, size_t len)static int no_init_out (HWVoiceOut *hw,struct audsettings *as,void *drv_opaque) {audio_pcm_init_info (&hw->info, as); - hw->samples =1024 ;return 0 ; }
@@ -75,7 +74,6 @@ static int no_ctl_out (HWVoiceOut *hw, int cmd, ...)static int no_init_in (HWVoiceIn *hw,struct audsettings *as,void *drv_opaque) {audio_pcm_init_info (&hw->info, as); - hw->samples =1024 ;return 0 ; }
audio/ossaudio.c +20 -4
@@ -46,6 +46,7 @@ typedef struct OSSVoiceOut {int nfrags;int fragsize;int mmapped; +size_t samples;Audiodev *dev; } OSSVoiceOut;
@@ -54,6 +55,7 @@ typedef struct OSSVoiceIn {int fd;int nfrags;int fragsize; +size_t samples;Audiodev *dev; } OSSVoiceIn;
@@ -513,11 +515,11 @@ static int oss_init_out(HWVoiceOut *hw, struct audsettings *as, obt.nfrags * obt.fragsize, hw->info.align + 1); } - hw->samples = (obt.nfrags * obt.fragsize) >> hw->info.shift; + oss->samples = (obt.nfrags * obt.fragsize) >> hw->info.shift; oss->mmapped =0 ;if (oopts->has_try_mmap && oopts->try_mmap) { - hw->size_emul = hw->samples << hw->info.shift; + hw->size_emul = oss->samples << hw->info.shift; hw->buf_emul = mmap ( NULL, hw->size_emul,
@@ -565,6 +567,12 @@ static int oss_init_out(HWVoiceOut *hw, struct audsettings *as,return 0 ; } +static size_t oss_buffer_size_out (HWVoiceOut *hw) +{ +OSSVoiceOut *oss = (OSSVoiceOut *) hw; +return oss->samples; +} +static int oss_ctl_out (HWVoiceOut *hw,int cmd, ...) {int trig;
@@ -587,7 +595,7 @@ static int oss_ctl_out (HWVoiceOut *hw, int cmd, ...)return 0 ; } -audio_pcm_info_clear_buf (&hw->info, hw->buf_emul, hw->samples); +audio_pcm_info_clear_buf (&hw->info, hw->buf_emul, oss->samples); trig =PCM_ENABLE_OUTPUT ;if (ioctl (oss->fd,SNDCTL_DSP_SETTRIGGER , &trig) <0 ) { oss_logerr (
@@ -660,13 +668,19 @@ static int oss_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque) obt.nfrags * obt.fragsize, hw->info.align + 1); } - hw->samples = (obt.nfrags * obt.fragsize) >> hw->info.shift; + oss->samples = (obt.nfrags * obt.fragsize) >> hw->info.shift; oss->fd = fd; oss->dev = dev;return 0 ; } +static size_t oss_buffer_size_in (HWVoiceIn *hw) +{ +OSSVoiceIn *oss = (OSSVoiceIn *) hw; +return oss->samples; +} +static void oss_fini_in (HWVoiceIn *hw) {OSSVoiceIn *oss = (OSSVoiceIn *) hw;
@@ -755,6 +769,7 @@ static struct audio_pcm_ops oss_pcm_ops = { .init_out = oss_init_out, .fini_out = oss_fini_out, .write = oss_write, + .buffer_size_out = oss_buffer_size_out, .get_buffer_out = oss_get_buffer_out, .put_buffer_out = oss_put_buffer_out, .ctl_out = oss_ctl_out,
@@ -762,6 +777,7 @@ static struct audio_pcm_ops oss_pcm_ops = { .init_in = oss_init_in, .fini_in = oss_fini_in, .read = oss_read, + .buffer_size_in = oss_buffer_size_in, .ctl_in = oss_ctl_in };
audio/paaudio.c +15 -0
@@ -362,6 +362,13 @@ static int qpa_init_out(HWVoiceOut *hw, struct audsettings *as,return -1 ; } +static size_t qpa_buffer_size_out (HWVoiceOut *hw) +{ +PAVoiceOut *pa = (PAVoiceOut *) hw; +return pa->samples; +} + +static int qpa_init_in (HWVoiceIn *hw,struct audsettings *as,void *drv_opaque) {int error;
@@ -403,6 +410,12 @@ static int qpa_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque)return -1 ; } +static size_t qpa_buffer_size_in (HWVoiceIn *hw) +{ +PAVoiceIn *pa = (PAVoiceIn *) hw; +return pa->samples; +} +static void qpa_simple_disconnect (PAConnection *c,pa_stream *stream) {int err;
@@ -679,11 +692,13 @@ static struct audio_pcm_ops qpa_pcm_ops = { .init_out = qpa_init_out, .fini_out = qpa_fini_out, .write = qpa_write, + .buffer_size_out = qpa_buffer_size_out, .ctl_out = qpa_ctl_out, .init_in = qpa_init_in, .fini_in = qpa_fini_in, .read = qpa_read, + .buffer_size_in = qpa_buffer_size_in, .ctl_in = qpa_ctl_in };
audio/sdlaudio.c +9 -1
@@ -39,6 +39,7 @@typedef struct SDLVoiceOut {HWVoiceOut hw; +size_t samples; }SDLVoiceOut ; static struct SDLAudioState {
@@ -335,7 +336,7 @@ static int sdl_init_out(HWVoiceOut *hw, struct audsettings *as, obt_as.endianness = endianness;audio_pcm_init_info (&hw->info, &obt_as); - hw->samples = obt.samples; + sdl->samples = obt.samples; s->initialized =1 ; s->exit =0 ;
@@ -343,6 +344,12 @@ static int sdl_init_out(HWVoiceOut *hw, struct audsettings *as,return 0 ; } +static size_t sdl_buffer_size_out (HWVoiceOut *hw) +{ +SDLVoiceOut *sdl = (SDLVoiceOut *) hw; +return sdl->samples; +} +static int sdl_ctl_out (HWVoiceOut *hw,int cmd, ...) { (void ) hw;
@@ -407,6 +414,7 @@ static struct audio_pcm_ops sdl_pcm_ops = { .init_out = sdl_init_out, .fini_out = sdl_fini_out, .write = sdl_write, + .buffer_size_out = sdl_buffer_size_out, .get_buffer_out = sdl_get_buffer_out, .put_buffer_out = sdl_put_buffer_out_nowrite, .ctl_out = sdl_ctl_out,
audio/spiceaudio.c +12 -2
@@ -131,7 +131,6 @@ static int line_out_init(HWVoiceOut *hw, struct audsettings *as, settings.endianness =AUDIO_HOST_ENDIANNESS ;audio_pcm_init_info (&hw->info, &settings); - hw->samples =LINE_OUT_SAMPLES ; out->active =0 ; out->sin.base.sif = &playback_sif.base;
@@ -142,6 +141,11 @@ static int line_out_init(HWVoiceOut *hw, struct audsettings *as,return 0 ; } +static size_t line_out_buffer_size (HWVoiceOut *hw) +{ +return LINE_OUT_SAMPLES ; +} +static void line_out_fini (HWVoiceOut *hw) {SpiceVoiceOut *out =container_of (hw, SpiceVoiceOut, hw);
@@ -246,7 +250,6 @@ static int line_in_init(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque) settings.endianness =AUDIO_HOST_ENDIANNESS ;audio_pcm_init_info (&hw->info, &settings); - hw->samples =LINE_IN_SAMPLES ; in->active =0 ; in->sin.base.sif = &record_sif.base;
@@ -257,6 +260,11 @@ static int line_in_init(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque)return 0 ; } +static size_t line_in_buffer_size (HWVoiceIn *hw) +{ +return LINE_IN_SAMPLES ; +} +static void line_in_fini (HWVoiceIn *hw) {SpiceVoiceIn *in =container_of (hw, SpiceVoiceIn, hw);
@@ -327,6 +335,7 @@ static struct audio_pcm_ops audio_callbacks = { .init_out = line_out_init, .fini_out = line_out_fini, .write = audio_generic_write, + .buffer_size_out = line_out_buffer_size, .get_buffer_out = line_out_get_buffer, .put_buffer_out = line_out_put_buffer, .ctl_out = line_out_ctl,
@@ -334,6 +343,7 @@ static struct audio_pcm_ops audio_callbacks = { .init_in = line_in_init, .fini_in = line_in_fini, .read = line_in_read, + .buffer_size_in = line_in_buffer_size, .ctl_in = line_in_ctl, };
audio/wavaudio.c +0 -1
@@ -108,7 +108,6 @@ static int wav_init_out(HWVoiceOut *hw, struct audsettings *as, wav_as.endianness =0 ;audio_pcm_init_info (&hw->info, &wav_as); - hw->samples =1024 ;le_store (hdr +22 , hw->info.nchannels,2 );le_store (hdr +24 , hw->info.freq,4 );le_store (hdr +28 , hw->info.freq << (bits16 + stereo),4 );
Signature · 1 line
2.5.0
PATCH v2 48/49 audio: common rate control code for timer based outputs
In reply to Kővágó, ZoltánThis commit removes the ad-hoc rate-limiting code from noaudio and wavaudio, and replaces them with a (slightly modified) code from spiceaudio. This way multiple write calls (for example when the circular buffer wraps around) do not cause problems.
--- audio/audio.c | 30 ++++++++++++++++++++++++++++++ audio/audio_int.h | 9 +++++++++ audio/noaudio.c | 49 ++++++++++++++++++++++--------------------------- audio/spiceaudio.c | 49 +++++++------------------------------------------ audio/wavaudio.c | 20 ++++++++++---------- 5 files changed, 78 insertions(+), 79 deletions(-)
audio/audio.c +30 -0
@@ -1958,3 +1958,33 @@ const char *audio_get_id(QEMUSoundCard *card)return "" ; } } + +void audio_rate_start (RateCtl *rate) +{ +memset (rate,0 ,sizeof (RateCtl)); + rate->start_ticks =qemu_clock_get_ns (QEMU_CLOCK_VIRTUAL ); +} + +size_t audio_rate_get_bytes (struct audio_pcm_info *info,RateCtl *rate, +size_t bytes_avail) +{ +int64_t now; +int64_t ticks; +int64_t bytes; +int64_t samples; +size_t ret; + + now =qemu_clock_get_ns (QEMU_CLOCK_VIRTUAL ); + ticks = now - rate->start_ticks; + bytes =muldiv64 (ticks, info->bytes_per_second,get_ticks_per_sec ()); + samples = (bytes - rate->bytes_sent) >> info->shift; +if (samples <0 || samples >65536 ) { +AUD_log (NULL ,"Resetting rate control (%" PRId64" samples)" , samples); +audio_rate_start (rate); + samples =0 ; + } + + ret =MIN (samples << info->shift, bytes_avail); + rate->bytes_sent += ret; +return ret; +}
audio/audio_int.h +9 -0
@@ -238,6 +238,15 @@ void *audio_calloc (const char *funcname, int nmemb, size_t size);void audio_run (AudioState *s,const char *msg); +typedef struct RateCtl { +int64_t start_ticks; +int64_t bytes_sent; +}RateCtl ; + +void audio_rate_start (RateCtl *rate); +size_t audio_rate_get_bytes (struct audio_pcm_info *info,RateCtl *rate, +size_t bytes_avail); +#define VOICE_ENABLE 1#define VOICE_DISABLE 2#define VOICE_VOLUME 3
audio/noaudio.c +22 -27
93 lines not on this page · raw message
audio/spiceaudio.c +7 -42
100 lines not on this page · raw message
audio/wavaudio.c +10 -10
@@ -32,20 +32,15 @@typedef struct WAVVoiceOut {HWVoiceOut hw;FILE *f; -int64_t old_ticks; +RateCtl rate;int total_samples; }WAVVoiceOut ;static size_t wav_write_out (HWVoiceOut *hw,void *buf,size_t len) {WAVVoiceOut *wav = (WAVVoiceOut *) hw; -int64_t now =qemu_clock_get_ns (QEMU_CLOCK_VIRTUAL ); -int64_t ticks = now - wav->old_ticks; -int64_t bytes = -muldiv64 (ticks, hw->info.bytes_per_second,get_ticks_per_sec ()); - bytes =MIN (bytes, len); - bytes = bytes >> hw->info.shift << hw->info.shift; - wav->old_ticks = now; +int64_t bytes =audio_rate_get_bytes (&hw->info, &wav->rate, len); +assert (bytes >> hw->info.shift << hw->info.shift == bytes);if (bytes &&fwrite (buf, bytes,1 , wav->f) !=1 ) { dolog("wav_write_out: fwrite of %zu bytes failed\nReaons: %s\n",
@@ -125,6 +120,8 @@ static int wav_init_out(HWVoiceOut *hw, struct audsettings *as, strerror(errno));return -1 ; } + +audio_rate_start (&wav->rate);return 0 ; }
@@ -174,8 +171,11 @@ static void wav_fini_out (HWVoiceOut *hw)static int wav_ctl_out (HWVoiceOut *hw,int cmd, ...) { - (void ) hw; - (void ) cmd; +WAVVoiceOut *wav = (WAVVoiceOut *) hw; + +if (cmd ==VOICE_ENABLE ) { +audio_rate_start (&wav->rate); + }return 0 ; }
Signature · 1 line
2.5.0