diff --git a/include/tinycompress/compress_ops.h b/include/tinycompress/compress_ops.h index 290a831..7a4ffc9 100644 --- a/include/tinycompress/compress_ops.h +++ b/include/tinycompress/compress_ops.h @@ -8,6 +8,8 @@ #include "sound/compress_offload.h" #include "tinycompress.h" +#define COMPRESS_OPS_V2 0xadcc0002 /* version 2 magic */ + /* * struct compress_ops: * ops structure containing ops corresponding to exposed @@ -16,14 +18,13 @@ * done in compress_hw.c */ struct compress_ops { + unsigned int magic; /* version of this structure */ void *(*open_by_name)(const char *name, unsigned int flags, struct compr_config *config); void (*close)(void *compress_data); int (*get_hpointer)(void *compress_data, - unsigned int *avail, struct timespec *tstamp); + unsigned long long *avail, struct timespec *tstamp); int (*get_tstamp)(void *compress_data, - unsigned int *samples, unsigned int *sampling_rate); - int (*get_tstamp64)(void *compress_data, unsigned long long *samples, unsigned int *sampling_rate); int (*write)(void *compress_data, const void *buf, size_t size); int (*read)(void *compress_data, void *buf, size_t size); diff --git a/include/tinycompress/tinycompress.h b/include/tinycompress/tinycompress.h index 8d9677b..f954f25 100644 --- a/include/tinycompress/tinycompress.h +++ b/include/tinycompress/tinycompress.h @@ -139,6 +139,18 @@ int compress_get_hpointer(struct compress *compress, unsigned int *avail, struct timespec *tstamp); +/* + * compress_get_hpointe64r: get the hw timestamp + * return 0 on success, negative on error + * + * @compress: compress stream on which query is made + * @avail: buffer availble for write/read, in bytes + * @tstamp: hw time + */ +int compress_get_hpointer64(struct compress *compress, + unsigned long long *avail, struct timespec *tstamp); + + /* * compress_get_tstamp: get the raw hw timestamp * return 0 on success, negative on error diff --git a/src/lib/compress.c b/src/lib/compress.c index cf0b295..d9ec77a 100644 --- a/src/lib/compress.c +++ b/src/lib/compress.c @@ -58,6 +58,8 @@ #include #include #include +#include +#include #include #include "tinycompress/tinycompress.h" #include "tinycompress/compress_ops.h" @@ -136,7 +138,7 @@ static int populate_compress_plugin_ops(struct compress *compress, const char *n return ret; } - compress->ops = dlsym(dl_hdl, "compress_plugin_ops"); + compress->ops = dlsym(dl_hdl, "compress_plugin_mops"); err = dlerror(); if (err) { fprintf(stderr, "%s: dlsym to ops failed, err = '%s'\n", @@ -144,6 +146,12 @@ static int populate_compress_plugin_ops(struct compress *compress, const char *n dlclose(dl_hdl); return ret; } + if (compress->ops->magic != COMPRESS_OPS_V2) { + fprintf(stderr, "%s: dlsym to ops failed, bad magic (%08x)\n", + __func__, compress->ops->magic); + dlclose(dl_hdl); + return -ENXIO; + } compress->dl_hdl = dl_hdl; return 0; } @@ -195,6 +203,21 @@ void compress_close(struct compress *compress) int compress_get_hpointer(struct compress *compress, unsigned int *avail, struct timespec *tstamp) +{ + unsigned long long _avail; + int ret; + + ret = compress->ops->get_hpointer(compress->data, &_avail, tstamp); + if (ret >= 0) { + if (_avail > UINT_MAX) + _avail = UINT_MAX; + *avail = (unsigned int)_avail; + } + return ret; +} + +int compress_get_hpointer64(struct compress *compress, + unsigned long long *avail, struct timespec *tstamp) { return compress->ops->get_hpointer(compress->data, avail, tstamp); } @@ -202,13 +225,19 @@ int compress_get_hpointer(struct compress *compress, int compress_get_tstamp(struct compress *compress, unsigned int *samples, unsigned int *sampling_rate) { - return compress->ops->get_tstamp(compress->data, samples, sampling_rate); + unsigned long long _samples; + int ret; + + ret = compress->ops->get_tstamp(compress->data, &_samples, sampling_rate); + if (ret >= 0) + *samples = (unsigned int)_samples; + return ret; } int compress_get_tstamp64(struct compress *compress, unsigned long long *samples, unsigned int *sampling_rate) { - return compress->ops->get_tstamp64(compress->data, samples, sampling_rate); + return compress->ops->get_tstamp(compress->data, samples, sampling_rate); } int compress_write(struct compress *compress, const void *buf, unsigned int size) diff --git a/src/lib/compress_hw.c b/src/lib/compress_hw.c index 02314cd..1519d71 100644 --- a/src/lib/compress_hw.c +++ b/src/lib/compress_hw.c @@ -225,18 +225,19 @@ static void compress_hw_close(void *data) } 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; + 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) + unsigned long long *avail, struct timespec *tstamp) { struct compress_hw_data *compress = (struct compress_hw_data *)data; struct snd_compr_avail kavail32; @@ -262,7 +263,7 @@ static int compress_hw_get_hpointer(void *data, if (0 == kavail64.tstamp.sampling_rate) return oops(compress, ENODATA, "sample rate unknown"); - *avail = (unsigned int)kavail64.avail; + *avail = kavail64.avail; time = kavail64.tstamp.pcm_io_frames / kavail64.tstamp.sampling_rate; tstamp->tv_sec = time; time = kavail64.tstamp.pcm_io_frames % kavail64.tstamp.sampling_rate; @@ -270,15 +271,11 @@ static int compress_hw_get_hpointer(void *data, return 0; } -static int compress_hw_get_tstamp(void *data, - unsigned int *samples, unsigned int *sampling_rate) +static int compress_hw_get_tstamp_32(struct compress_hw_data *compress, + unsigned long long *samples, unsigned int *sampling_rate) { - struct compress_hw_data *compress = (struct compress_hw_data *)data; struct snd_compr_tstamp ktstamp; - if (!is_compress_hw_ready(compress)) - return oops(compress, ENODEV, "device not ready"); - if (ioctl(compress->fd, SNDRV_COMPRESS_TSTAMP, &ktstamp)) return oops(compress, errno, "cannot get tstamp"); @@ -287,15 +284,11 @@ static int compress_hw_get_tstamp(void *data, return 0; } -static int compress_hw_get_tstamp64(void *data, +static int compress_hw_get_tstamp_64(struct compress_hw_data *compress, unsigned long long *samples, unsigned int *sampling_rate) { - 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"); @@ -304,6 +297,20 @@ static int compress_hw_get_tstamp64(void *data, return 0; } +static int compress_hw_get_tstamp(void *data, + unsigned long long *samples, unsigned int *sampling_rate) +{ + struct compress_hw_data *compress = (struct compress_hw_data *)data; + + if (!is_compress_hw_ready(compress)) + return oops(compress, ENODEV, "device not ready"); + + if (get_compress_hw_version(compress) >= SNDRV_PROTOCOL_VERSION(0, 4, 0)) + return compress_hw_get_tstamp_64(compress, samples, sampling_rate); + else + return compress_hw_get_tstamp_32(compress, samples, sampling_rate); +} + static int compress_hw_write(void *data, const void *buf, size_t size) { struct compress_hw_data *compress = (struct compress_hw_data *)data; @@ -640,11 +647,11 @@ static int compress_hw_set_codec_params(void *data, struct snd_codec *codec) } struct compress_ops compress_hw_ops = { + .magic = COMPRESS_OPS_V2, .open_by_name = compress_hw_open_by_name, .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,