audio(4): Rework AUDIO_GETOOFFS.
- Count .samples/.deltablks in blocks. It makes .deltablks integer wrap around safe. - Remove suspicious one block offset from .offset. I added the offset because it was observed so on NetBSD7. But according to manpage, it should not be. And it looks fine without the offset. - Related to that, remove a comment in AUDIO_WSEEK. Limit the user-visible buffer to usrbuf only.
This commit is contained in:
parent
aee3ae2609
commit
784ec6245f
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: audio.c,v 1.126 2022/04/20 06:05:22 isaki Exp $ */
|
||||
/* $NetBSD: audio.c,v 1.127 2022/04/20 07:11:13 isaki Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2008 The NetBSD Foundation, Inc.
|
||||
|
@ -181,7 +181,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.126 2022/04/20 06:05:22 isaki Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.127 2022/04/20 07:11:13 isaki Exp $");
|
||||
|
||||
#ifdef _KERNEL_OPT
|
||||
#include "audio.h"
|
||||
|
@ -2985,7 +2985,7 @@ audio_ioctl(dev_t dev, struct audio_softc *sc, u_long cmd, void *addr, int flag,
|
|||
audio_encoding_t *ae;
|
||||
audio_format_query_t *query;
|
||||
u_int stamp;
|
||||
u_int offs;
|
||||
u_int offset;
|
||||
int val;
|
||||
int index;
|
||||
int error;
|
||||
|
@ -3104,28 +3104,23 @@ audio_ioctl(dev_t dev, struct audio_softc *sc, u_long cmd, void *addr, int flag,
|
|||
}
|
||||
mutex_enter(sc->sc_lock);
|
||||
mutex_enter(sc->sc_intr_lock);
|
||||
/* figure out where next DMA will start */
|
||||
stamp = track->usrbuf_stamp;
|
||||
offs = track->usrbuf.head;
|
||||
/* figure out where next transfer will start */
|
||||
stamp = track->stamp;
|
||||
offset = track->usrbuf.head;
|
||||
mutex_exit(sc->sc_intr_lock);
|
||||
mutex_exit(sc->sc_lock);
|
||||
|
||||
ao->samples = stamp;
|
||||
ao->deltablks = (stamp / track->usrbuf_blksize) -
|
||||
(track->usrbuf_stamp_last / track->usrbuf_blksize);
|
||||
track->usrbuf_stamp_last = stamp;
|
||||
offs = rounddown(offs, track->usrbuf_blksize)
|
||||
+ track->usrbuf_blksize;
|
||||
if (offs >= track->usrbuf.capacity)
|
||||
offs -= track->usrbuf.capacity;
|
||||
ao->offset = offs;
|
||||
|
||||
/* samples will overflow soon but is as per spec. */
|
||||
ao->samples = stamp * track->usrbuf_blksize;
|
||||
ao->deltablks = stamp - track->last_stamp;
|
||||
ao->offset = offset;
|
||||
TRACET(2, track, "%s samples=%u deltablks=%u offset=%u",
|
||||
pre, ao->samples, ao->deltablks, ao->offset);
|
||||
|
||||
track->last_stamp = stamp;
|
||||
break;
|
||||
|
||||
case AUDIO_WSEEK:
|
||||
/* XXX return value does not include outbuf one. */
|
||||
track = file->ptrack;
|
||||
if (track) {
|
||||
val = track->usrbuf.used;
|
||||
|
@ -4964,8 +4959,6 @@ audio_track_play(audio_track_t *track)
|
|||
count = uimin(usrbuf->used, track->usrbuf_blksize) / framesize;
|
||||
bytes = count * framesize;
|
||||
|
||||
track->usrbuf_stamp += bytes;
|
||||
|
||||
if (usrbuf->head + bytes < usrbuf->capacity) {
|
||||
memcpy((uint8_t *)input->mem + auring_tail(input) * framesize,
|
||||
(uint8_t *)usrbuf->mem + usrbuf->head,
|
||||
|
@ -5060,6 +5053,8 @@ audio_track_play(audio_track_t *track)
|
|||
track->outputcounter += track->outbuf.used - track_count_0;
|
||||
}
|
||||
|
||||
track->stamp++;
|
||||
|
||||
#if defined(AUDIO_DEBUG)
|
||||
if (audiodebug >= 3) {
|
||||
struct audio_track_debugbuf m;
|
||||
|
@ -6311,6 +6306,8 @@ audio_track_clear(struct audio_softc *sc, audio_track_t *track)
|
|||
track->outbuf.used = 0;
|
||||
|
||||
/* Clear counters. */
|
||||
track->stamp = 0;
|
||||
track->last_stamp = 0;
|
||||
track->dropframes = 0;
|
||||
|
||||
audio_track_lock_exit(track);
|
||||
|
@ -7773,7 +7770,7 @@ audiogetinfo(struct audio_softc *sc, struct audio_info *ai, int need_mixerinfo,
|
|||
|
||||
if (ptrack) {
|
||||
pi->seek = ptrack->usrbuf.used;
|
||||
pi->samples = ptrack->usrbuf_stamp;
|
||||
pi->samples = ptrack->stamp * ptrack->usrbuf_blksize;
|
||||
pi->eof = ptrack->eofcounter;
|
||||
pi->error = (ptrack->dropframes != 0) ? 1 : 0;
|
||||
pi->open = 1;
|
||||
|
@ -7784,7 +7781,7 @@ audiogetinfo(struct audio_softc *sc, struct audio_info *ai, int need_mixerinfo,
|
|||
|
||||
if (rtrack) {
|
||||
ri->seek = audio_track_readablebytes(rtrack);
|
||||
ri->samples = rtrack->usrbuf_stamp;
|
||||
ri->samples = rtrack->stamp * rtrack->usrbuf_blksize;
|
||||
ri->eof = 0;
|
||||
ri->error = (rtrack->dropframes != 0) ? 1 : 0;
|
||||
ri->open = 1;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: audiodef.h,v 1.17 2022/04/20 06:05:22 isaki Exp $ */
|
||||
/* $NetBSD: audiodef.h,v 1.18 2022/04/20 07:11:13 isaki Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2017 Tetsuya Isaki. All rights reserved.
|
||||
|
@ -121,8 +121,6 @@ struct audio_track {
|
|||
u_int usrbuf_blksize; /* usrbuf block size in bytes */
|
||||
struct uvm_object *uobj;
|
||||
bool mmapped; /* device is mmap()-ed */
|
||||
u_int usrbuf_stamp; /* transferred bytes from/to stage */
|
||||
u_int usrbuf_stamp_last; /* last stamp */
|
||||
u_int usrbuf_usedhigh;/* high water mark in bytes */
|
||||
u_int usrbuf_usedlow; /* low water mark in bytes */
|
||||
|
||||
|
@ -162,6 +160,13 @@ struct audio_track {
|
|||
u_int volume;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* For AUDIO_GET[IO]OFFS.
|
||||
* No locks are required for these.
|
||||
*/
|
||||
u_int stamp; /* number of transferred blocks */
|
||||
u_int last_stamp;
|
||||
|
||||
audio_trackmixer_t *mixer; /* connected track mixer */
|
||||
|
||||
/* Sequence number picked up by track mixer. */
|
||||
|
|
Loading…
Reference in New Issue