blob: 9032e91c2093ab7a54e2520e1969600f3114581b [file] [log] [blame]
/*
** Copyright 2022, The Android Open-Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
// This library is used to help collect audio smoothness metrics from an
// implementation of an Audio Hardware Abstraction Layer (HAL). This is
// primarily used to count xruns and number of frames written and lost for an
// audio stream.
//
// To use this library, create an instance of the struct "hal_smoothness" using
// the "initialize()" method. The "client_flush_cb" callback method needs to be
// defined, which will be called when the library thinks it is time to flush
// metrics data, which is when "num_writes_to_logs" == "total_writes". The
// callback's purpose is so that the client can flush these metrics wherever
// it wants (ie. flushing it to a metrics server or to logcat). A
// "hal_smoothness_metrics" will be passed into it. After the callback has
// finished, all values will be set back to 0.
#pragma once
#include <sys/cdefs.h>
#define HAL_SMOOTHNESS_VERSION_1 1
__BEGIN_DECLS
// Audio HAL smoothness metrics that can be read by the client. These metrics,
// get reset after every flush to the client's callback.
struct hal_smoothness_metrics {
// Count of underruns, right before a flush.
unsigned int underrun_count;
// Count of overruns, right before a flush.
unsigned int overrun_count;
// Count of times audio samples are written to the endpoint buffer, right
// before a flush.
unsigned int total_writes;
// Total number of frames written, right before a flush.
unsigned int total_frames_written;
// Total number of frames lost, right before a flush.
unsigned int total_frames_lost;
// Smoothness value calculated by library right before calling the flush
// callback:
// -ln(total_frames_lost/(total_frames_written + total_frames_lost))
//
// If "total_frames_lost" is 0, that would imply perfect audio quality in
// terms of no bytes were dropped. In this case, DBL_MAX will be returned.
double smoothness_value;
// Timestamp of when these metrics were flushed. It is up to the client to
// decide which clock and what granularity to use. However, it is recommended
// to use the system clock CLOCK_REALTIME.
unsigned long timestamp;
};
// Used by the audio HAL implementor to help with collection of audio smoothness
// metrics.
struct hal_smoothness {
// Struct version.
unsigned int version;
// Increments “underrun_count” and "total_frames_lost".
//
// returns 0 if successful and non-zero on failure.
int (*increment_underrun)(struct hal_smoothness *smoothness,
unsigned int frames_lost);
// Increments “overrun_count” and "total_frames_lost".
//
// returns 0 if successful and non-zero on failure.
int (*increment_overrun)(struct hal_smoothness *smoothness,
unsigned int frames_lost);
// Increments “total_writes” and "total_frames_written". Once “total_writes >=
// num_writes_to_logs”, “client_flush_cb” will be triggered and all the ints
// in "hal_smoothness_metrics" will be reset to 0.
//
// returns 0 if successful and non-zero on failure.
int (*increment_total_writes)(struct hal_smoothness *smoothness,
unsigned int frames_written,
unsigned long timestamp);
// Manual flush. Will call "client_flush_cb" and reset "hal_smoothness_metrics".
int (*flush)(struct hal_smoothness *smoothness);
};
// version: hal_smoothness library version.
//
// num_writes_to_log: number of writes before we flushing
//
// client_flush_cb: Client defined flush method. The library will pass in
// "hal_smoothness_metrics", which will be generated by the library, and
// "private_data", which is provided by the client.
//
// private_data: Client defined data that is passed into “client_flush_cb”
//
// returns 0 if successful and non-zero on failure.
int hal_smoothness_initialize(
struct hal_smoothness **smoothness, unsigned int version,
unsigned int num_writes_to_log,
void (*client_flush_cb)(struct hal_smoothness_metrics *, void *),
void *private_data);
void hal_smoothness_free(struct hal_smoothness **smoothness);
__END_DECLS