-
Notifications
You must be signed in to change notification settings - Fork 25
tinycompress: add support for new SNDRV_COMPRESS_TSTAMP64 and _AVAIL64 #29
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -36,6 +36,7 @@ struct compress_hw_data { | |
int fd; | ||
unsigned int flags; | ||
char error[COMPR_ERR_MAX]; | ||
int ioctl_version; | ||
struct compr_config *config; | ||
int running; | ||
int max_poll_wait_ms; | ||
|
@@ -88,13 +89,7 @@ static int is_compress_hw_ready(void *data) | |
|
||
static int get_compress_hw_version(struct compress_hw_data *compress) | ||
{ | ||
int version = 0; | ||
|
||
if (ioctl(compress->fd, SNDRV_COMPRESS_IOCTL_VERSION, &version)) { | ||
oops(compress, errno, "cant read version"); | ||
return -1; | ||
} | ||
return version; | ||
return compress->ioctl_version; | ||
} | ||
|
||
static bool _is_codec_type_supported(int fd, struct snd_codec *codec) | ||
|
@@ -178,6 +173,11 @@ static void *compress_hw_open_by_name(const char *name, | |
goto config_fail; | ||
} | ||
|
||
if (ioctl(compress->fd, SNDRV_COMPRESS_IOCTL_VERSION, &compress->ioctl_version)) { | ||
oops(&bad_compress, errno, "cannot read version"); | ||
goto codec_fail; | ||
} | ||
|
||
if (ioctl(compress->fd, SNDRV_COMPRESS_GET_CAPS, &caps)) { | ||
oops(compress, errno, "cannot get device caps"); | ||
goto codec_fail; | ||
|
@@ -224,25 +224,49 @@ static void compress_hw_close(void *data) | |
free(compress); | ||
} | ||
|
||
static void compress_hw_avail64_from_32(struct snd_compr_avail64 *avail64, | ||
const struct snd_compr_avail *avail32) { | ||
avail64->avail = avail32->avail; | ||
|
||
avail64->tstamp.byte_offset = avail32->tstamp.byte_offset; | ||
avail64->tstamp.copied_total = avail32->tstamp.copied_total; | ||
avail64->tstamp.pcm_frames = avail32->tstamp.pcm_frames; | ||
avail64->tstamp.pcm_io_frames = avail32->tstamp.pcm_io_frames; | ||
avail64->tstamp.sampling_rate = avail32->tstamp.sampling_rate; | ||
} | ||
|
||
static int compress_hw_get_hpointer(void *data, | ||
unsigned int *avail, struct timespec *tstamp) | ||
{ | ||
struct compress_hw_data *compress = (struct compress_hw_data *)data; | ||
struct snd_compr_avail kavail; | ||
struct snd_compr_avail kavail32; | ||
struct snd_compr_avail64 kavail64; | ||
__u64 time; | ||
|
||
if (!is_compress_hw_ready(compress)) | ||
return oops(compress, ENODEV, "device not ready"); | ||
|
||
if (ioctl(compress->fd, SNDRV_COMPRESS_AVAIL, &kavail)) | ||
return oops(compress, errno, "cannot get avail"); | ||
if (0 == kavail.tstamp.sampling_rate) | ||
const int version = get_compress_hw_version(compress); | ||
if (version <= 0) | ||
return -1; | ||
|
||
if (version < SNDRV_PROTOCOL_VERSION(0, 4, 0)) { | ||
/* SNDRV_COMPRESS_AVAIL64 not supported, fallback to SNDRV_COMPRESS_AVAIL */ | ||
if (ioctl(compress->fd, SNDRV_COMPRESS_AVAIL, &kavail32)) | ||
return oops(compress, errno, "cannot get avail"); | ||
compress_hw_avail64_from_32(&kavail64, &kavail32); | ||
} else { | ||
if (ioctl(compress->fd, SNDRV_COMPRESS_AVAIL64, &kavail64)) | ||
return oops(compress, errno, "cannot get avail64"); | ||
} | ||
|
||
if (0 == kavail64.tstamp.sampling_rate) | ||
return oops(compress, ENODATA, "sample rate unknown"); | ||
*avail = (unsigned int)kavail.avail; | ||
time = kavail.tstamp.pcm_io_frames / kavail.tstamp.sampling_rate; | ||
*avail = (unsigned int)kavail64.avail; | ||
time = kavail64.tstamp.pcm_io_frames / kavail64.tstamp.sampling_rate; | ||
tstamp->tv_sec = time; | ||
time = kavail.tstamp.pcm_io_frames % kavail.tstamp.sampling_rate; | ||
tstamp->tv_nsec = time * 1000000000 / kavail.tstamp.sampling_rate; | ||
time = kavail64.tstamp.pcm_io_frames % kavail64.tstamp.sampling_rate; | ||
tstamp->tv_nsec = time * 1000000000 / kavail64.tstamp.sampling_rate; | ||
return 0; | ||
} | ||
|
||
|
@@ -263,6 +287,23 @@ static int compress_hw_get_tstamp(void *data, | |
return 0; | ||
} | ||
|
||
static int compress_hw_get_tstamp64(void *data, | ||
unsigned long long *samples, unsigned int *sampling_rate) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would prefer to use forced 64-bit type like __u64 instead long long. But it's probably for the discussion. The other exported functions do not force 32-bit types. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I retained the C standard types for consistency with the existing API as you mentioned. Long long is guaranteed to be at least 64 bits wide so it won't cause any truncation issues. |
||
{ | ||
struct compress_hw_data *compress = (struct compress_hw_data *)data; | ||
struct snd_compr_tstamp64 ktstamp; | ||
|
||
if (!is_compress_hw_ready(compress)) | ||
return oops(compress, ENODEV, "device not ready"); | ||
|
||
if (ioctl(compress->fd, SNDRV_COMPRESS_TSTAMP64, &ktstamp)) | ||
return oops(compress, errno, "cannot get tstamp64"); | ||
|
||
*samples = ktstamp.pcm_io_frames; | ||
*sampling_rate = ktstamp.sampling_rate; | ||
return 0; | ||
} | ||
|
||
static int compress_hw_write(void *data, const void *buf, size_t size) | ||
{ | ||
struct compress_hw_data *compress = (struct compress_hw_data *)data; | ||
|
@@ -603,6 +644,7 @@ struct compress_ops compress_hw_ops = { | |
.close = compress_hw_close, | ||
.get_hpointer = compress_hw_get_hpointer, | ||
.get_tstamp = compress_hw_get_tstamp, | ||
.get_tstamp64 = compress_hw_get_tstamp64, | ||
.write = compress_hw_write, | ||
.read = compress_hw_read, | ||
.start = compress_hw_start, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I dont see compress_hw_get_tstamp() updated. compress_hw_write() uses AVAIL ioctl, that should be updated too...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the comment!
Correct, I added a parallel
compress_hw_get_tstamp64
to get the 64 bit struct.On the other hand,
compress_hw_get_tstamp
has been unchanged, still returning the 32 bit structure via ioctlSNDRV_COMPRESS_TSTAMP
which will stay supported in the kernel forever.There is no benefit in using AVAIL64 here since only the
avail
field of the structure is being used (was already 64 bit). The only difference between AVAIL and AVAIL64 return value is thetstamp
field which is unused incompress_hw_write