• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 ** Copyright 2022, The Android Open-Source Project
3 **
4 ** Licensed under the Apache License, Version 2.0 (the "License");
5 ** you may not use this file except in compliance with the License.
6 ** You may obtain a copy of the License at
7 **
8 **     http://www.apache.org/licenses/LICENSE-2.0
9 **
10 ** Unless required by applicable law or agreed to in writing, software
11 ** distributed under the License is distributed on an "AS IS" BASIS,
12 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 ** See the License for the specific language governing permissions and
14 ** limitations under the License.
15 */
16 
17 // This library is used to help collect audio smoothness metrics from an
18 // implementation of an Audio Hardware Abstraction Layer (HAL). This is
19 // primarily used to count xruns and number of frames written and lost for an
20 // audio stream.
21 //
22 // To use this library, create an instance of the struct "hal_smoothness" using
23 // the "initialize()" method. The "client_flush_cb" callback method needs to be
24 // defined, which will be called when the library thinks it is time to flush
25 // metrics data, which is when "num_writes_to_logs" == "total_writes". The
26 // callback's purpose is so that the client can flush these metrics wherever
27 // it wants (ie. flushing it to a metrics server or to logcat). A
28 // "hal_smoothness_metrics" will be passed into it. After the callback has
29 // finished, all values will be set back to 0.
30 
31 #pragma once
32 
33 #include <sys/cdefs.h>
34 
35 #define HAL_SMOOTHNESS_VERSION_1 1
36 
37 __BEGIN_DECLS
38 
39 // Audio HAL smoothness metrics that can be read by the client. These metrics,
40 // get reset after every flush to the client's callback.
41 struct hal_smoothness_metrics {
42   // Count of underruns, right before a flush.
43   unsigned int underrun_count;
44 
45   // Count of overruns, right before a flush.
46   unsigned int overrun_count;
47 
48   // Count of times audio samples are written to the endpoint buffer, right
49   // before a flush.
50   unsigned int total_writes;
51 
52   // Total number of frames written, right before a flush.
53   unsigned int total_frames_written;
54 
55   // Total number of frames lost, right before a flush.
56   unsigned int total_frames_lost;
57 
58   // Smoothness value calculated by library right before calling the flush
59   // callback:
60   // -ln(total_frames_lost/(total_frames_written + total_frames_lost))
61   //
62   // If "total_frames_lost" is 0, that would imply perfect audio quality in
63   // terms of no bytes were dropped. In this case, DBL_MAX will be returned.
64   double smoothness_value;
65 
66   // Timestamp of when these metrics were flushed. It is up to the client to
67   // decide which clock and what granularity to use. However, it is recommended
68   // to use the system clock CLOCK_REALTIME.
69   unsigned long timestamp;
70 };
71 
72 // Used by the audio HAL implementor to help with collection of audio smoothness
73 // metrics.
74 struct hal_smoothness {
75   // Struct version.
76   unsigned int version;
77 
78   // Increments “underrun_count” and "total_frames_lost".
79   //
80   // returns 0 if successful and non-zero on failure.
81   int (*increment_underrun)(struct hal_smoothness *smoothness,
82                             unsigned int frames_lost);
83 
84   // Increments “overrun_count” and "total_frames_lost".
85   //
86   // returns 0 if successful and non-zero on failure.
87   int (*increment_overrun)(struct hal_smoothness *smoothness,
88                            unsigned int frames_lost);
89 
90   // Increments “total_writes” and "total_frames_written". Once “total_writes >=
91   // num_writes_to_logs”, “client_flush_cb” will be triggered and all the ints
92   // in "hal_smoothness_metrics" will be reset to 0.
93   //
94   // returns 0 if successful and non-zero on failure.
95   int (*increment_total_writes)(struct hal_smoothness *smoothness,
96                                 unsigned int frames_written,
97                                 unsigned long timestamp);
98 
99   // Manual flush. Will call "client_flush_cb" and reset "hal_smoothness_metrics".
100   int (*flush)(struct hal_smoothness *smoothness);
101 };
102 
103 // version: hal_smoothness library version.
104 //
105 // num_writes_to_log: number of writes before we flushing
106 //
107 // client_flush_cb: Client defined flush method. The library will pass in
108 // "hal_smoothness_metrics", which will be generated by the library, and
109 // "private_data", which is provided by the client.
110 //
111 // private_data: Client defined data that is passed into “client_flush_cb”
112 //
113 // returns 0 if successful and non-zero on failure.
114 int hal_smoothness_initialize(
115     struct hal_smoothness **smoothness, unsigned int version,
116     unsigned int num_writes_to_log,
117     void (*client_flush_cb)(struct hal_smoothness_metrics *, void *),
118     void *private_data);
119 
120 void hal_smoothness_free(struct hal_smoothness **smoothness);
121 
122 __END_DECLS
123