docs: Multiple clarifications to documentation

See !1817
This commit is contained in:
Demi Marie Obenour 2024-01-12 11:55:28 +01:00 committed by Wim Taymans
parent d8ab51a9fc
commit 0f533c6d64
10 changed files with 171 additions and 28 deletions

View file

@ -120,8 +120,7 @@ struct spa_io_clock {
struct spa_fraction rate; /**< rate for position/duration/delay/xrun */
uint64_t position; /**< current position */
uint64_t duration; /**< duration of current cycle */
int64_t delay; /**< delay between position and hardware,
* positive for capture, negative for playback */
int64_t delay; /**< delay between position and hardware */
double rate_diff; /**< rate difference between clock and monotonic time */
uint64_t next_nsec; /**< estimated next wakeup time in nanoseconds */

View file

@ -66,19 +66,57 @@ struct spa_loop_methods {
#define SPA_VERSION_LOOP_METHODS 0
uint32_t version;
/** add a source to the loop */
/** Add a source to the loop. Must be called from the loop's own thread.
*
* \param[in] object The callbacks data.
* \param[in] source The source.
* \return 0 on success, negative errno-style value on failure.
*/
int (*add_source) (void *object,
struct spa_source *source);
/** update the source io mask */
/** Update the source io mask. Must be called from the loop's own thread.
*
* \param[in] object The callbacks data.
* \param[in] source The source.
* \return 0 on success, negative errno-style value on failure.
*/
int (*update_source) (void *object,
struct spa_source *source);
/** remove a source from the loop */
/** Remove a source from the loop. Must be called from the loop's own thread.
*
* \param[in] object The callbacks data.
* \param[in] source The source.
* \return 0 on success, negative errno-style value on failure.
*/
int (*remove_source) (void *object,
struct spa_source *source);
/** invoke a function in the context of this loop */
/** Invoke a function in the context of this loop.
* May be called from the loop's thread, but otherwise
* can only be called by a single thread at a time.
* If called from the loop's thread, all callbacks previously queued with
* invoke() will be run synchronously, which might cause unexpected
* reentrancy problems.
*
* \param[in] object The callbacks data.
* \param func The function to be invoked.
* \param seq An opaque sequence number. This will be made
* available to func.
* \param[in] data Data that will be copied into the internal ring buffer and made
* available to func. Because this data is copied, it is okay to
* pass a pointer to a local variable, but do not pass a pointer to
* an object that has identity.
* \param size The size of data to copy.
* \param block If \true, do not return until func has been called. Otherwise,
* returns immediately. Passing \true does not risk a deadlock because
* the data thread is never allowed to wait on any other thread.
* \param user_data An opaque pointer passed to func.
* \return `-EPIPE` if the internal ring buffer filled up,
* if block is \false, 0 if seq was SPA_ID_INVALID or
* seq with the ASYNC flag set
* or the return value of func otherwise. */
int (*invoke) (void *object,
spa_invoke_func_t func,
uint32_t seq,

View file

@ -32,15 +32,17 @@ struct pw_array {
size_t extend; /**< number of bytes to extend with */
};
/** Initialize an array. The new array is empty. */
#define PW_ARRAY_INIT(extend) ((struct pw_array) { NULL, 0, 0, (extend) })
/** Return the length of an array. */
#define pw_array_get_len_s(a,s) ((a)->size / (s))
#define pw_array_get_unchecked_s(a,idx,s,t) SPA_PTROFF((a)->data,(idx)*(s),t)
#define pw_array_check_index_s(a,idx,s) ((idx) < pw_array_get_len_s(a,s))
/** Get the number of items of type \a t in array */
#define pw_array_get_len(a,t) pw_array_get_len_s(a,sizeof(t))
/** Get the item with index \a idx and type \a t from array */
/** Get the item with index \a idx and type \a t from array. No bounds check is done. */
#define pw_array_get_unchecked(a,idx,t) pw_array_get_unchecked_s(a,idx,sizeof(t),t)
/** Check if an item with index \a idx and type \a t exist in array */
#define pw_array_check_index(a,idx,t) pw_array_check_index_s(a,idx,sizeof(t))
@ -110,7 +112,8 @@ static inline int pw_array_ensure_size(struct pw_array *arr, size_t size)
}
/** Add \a ref size bytes to \a arr. A pointer to memory that can
* hold at least \a size bytes is returned */
* hold at least \a size bytes is returned or NULL when an error occured
* and errno will be set.*/
static inline void *pw_array_add(struct pw_array *arr, size_t size)
{
void *p;

View file

@ -71,10 +71,17 @@ struct pw_context_events {
void (*driver_removed) (void *data, struct pw_impl_node *node);
};
/** Make a new context object for a given main_loop. Ownership of the properties is taken */
struct pw_context * pw_context_new(struct pw_loop *main_loop, /**< a main loop to run in */
struct pw_properties *props, /**< extra properties */
size_t user_data_size /**< extra user data size */);
/** Make a new context object for a given main_loop. Ownership of the properties is taken, even
* if the function returns NULL.
*
* \param main_loop A main loop to run in. This must stay alive unil pw_context_destroy() is called.
* \param props extra properties
* \param user_data_size extra user data size
* \return The context object on success, or NULL on failure, in which case errno is set.
* */
struct pw_context * pw_context_new(struct pw_loop *main_loop,
struct pw_properties *props,
size_t user_data_size);
/** destroy a context object, all resources except the main_loop will be destroyed */
void pw_context_destroy(struct pw_context *context);
@ -119,16 +126,17 @@ int pw_context_conf_section_match_rules(struct pw_context *context, const char *
/** Get the context support objects */
const struct spa_support *pw_context_get_support(struct pw_context *context, uint32_t *n_support);
/** get the context main loop */
/** Get the context main loop. Returns the value passed to pw_context_new(). */
struct pw_loop *pw_context_get_main_loop(struct pw_context *context);
/** get the context data loop. Since 0.3.56 */
/** Get the context data loop. This loop runs on the realtime thread.
* Since 0.3.56 */
struct pw_data_loop *pw_context_get_data_loop(struct pw_context *context);
/** Get the work queue from the context: Since 0.3.26 */
struct pw_work_queue *pw_context_get_work_queue(struct pw_context *context);
/** Get the memmory pool from the context: Since 0.3.74 */
/** Get the memory pool from the context: Since 0.3.74 */
struct pw_mempool *pw_context_get_mempool(struct pw_context *context);
/** Iterate the globals of the context. The callback should return
@ -139,7 +147,10 @@ int pw_context_for_each_global(struct pw_context *context,
int (*callback) (void *data, struct pw_global *global),
void *data);
/** Find a context global by id */
/** Find a context global by id.
*
* \return The global on success, or NULL on failure. If id is \ref PW_ID_CORE,
* this function will always return a non-NULL value. */
struct pw_global *pw_context_find_global(struct pw_context *context, /**< the context */
uint32_t id /**< the global id */);
@ -149,6 +160,7 @@ int pw_context_add_spa_lib(struct pw_context *context, const char *factory_regex
/** find the library name for a spa factory */
const char * pw_context_find_spa_lib(struct pw_context *context, const char *factory_name);
/** Load a SPA handle from a context. On failure returns NULL and sets errno. */
struct spa_handle *pw_context_load_spa_handle(struct pw_context *context,
const char *factory_name,
const struct spa_dict *info);
@ -169,9 +181,21 @@ int pw_context_register_export_type(struct pw_context *context, struct pw_export
/** find information about registered export type */
const struct pw_export_type *pw_context_find_export_type(struct pw_context *context, const char *type);
/** add an object to the context */
/** add an object to the context
*
* \param context The context.
* \param type The type of the object, usually a `TYPE_INTERFACE_` value.
* \param value The object value. Must last as long as the context and must
* be of the type corresponding to the type.
* \return A negative number on failure (out of memory).
* */
int pw_context_set_object(struct pw_context *context, const char *type, void *value);
/** get an object from the context */
/** get an object from the context
*
* \param context The context.
* \param type The string corresponding to the object's interface.
* \return The object, or NULL if the object does not exist.
* */
void *pw_context_get_object(struct pw_context *context, const char *type);
/**

View file

@ -45,7 +45,8 @@ struct pw_control_events {
/** Get the control parent port or NULL when not set */
struct pw_impl_port *pw_control_get_port(struct pw_control *control);
/** Add an event listener on the control */
/** Add an event listener on the control. May be called multiple times.
* Each listener must be removed, but they may be removed in any order. */
void pw_control_add_listener(struct pw_control *control,
struct spa_hook *listener,
const struct pw_control_events *events,

View file

@ -69,11 +69,13 @@ struct pw_core_info {
#include <pipewire/properties.h>
#include <pipewire/proxy.h>
/** Update an existing \ref pw_core_info with \a update with reset */
/** Update an existing \ref pw_core_info with \a update with reset. When info is NULL,
* a new one will be allocated. Returns NULL on failure. */
struct pw_core_info *
pw_core_info_update(struct pw_core_info *info,
const struct pw_core_info *update);
/** Update an existing \ref pw_core_info with \a update */
/** Update an existing \ref pw_core_info with \a update. When info is NULL, a new one
* will be allocated. Returns NULL on failure */
struct pw_core_info *
pw_core_info_merge(struct pw_core_info *info,
const struct pw_core_info *update, bool reset);
@ -164,6 +166,9 @@ struct pw_core_events {
* global ID. It is emitted before the global becomes visible in the
* registry.
*
* The bound_props event is an enhanced version of this event that
* also contains the extra global properties.
*
* \param id bound object ID
* \param global_id the global id bound to
*/
@ -192,6 +197,19 @@ struct pw_core_events {
*/
void (*remove_mem) (void *data, uint32_t id);
/**
* Notify an object binding
*
* This event is emitted when a local object ID is bound to a
* global ID. It is emitted before the global becomes visible in the
* registry.
*
* This is an enhanced version of the bound_id event.
*
* \param id bound object ID
* \param global_id the global id bound to
* \param props The properties of the new global object.
*/
void (*bound_props) (void *data, uint32_t id, uint32_t global_id, const struct spa_dict *props);
};

View file

@ -67,13 +67,38 @@ int pw_data_loop_start(struct pw_data_loop *loop);
/** Stop the processing thread */
int pw_data_loop_stop(struct pw_data_loop *loop);
/** Check if the current thread is the processing thread */
/** Check if the current thread is the processing thread.
* May be called from any thread. */
bool pw_data_loop_in_thread(struct pw_data_loop *loop);
/** Get the thread object */
struct spa_thread *pw_data_loop_get_thread(struct pw_data_loop *loop);
/** invoke func in the context of the thread or in the caller thread when
* the loop is not running. Since 0.3.3 */
* the loop is not running. May be called from the loop's thread, but otherwise
* can only be called by a single thread at a time.
* If called from the loop's thread, all callbacks previously queued with
* pw_data_loop_invoke() will be run synchronously, which might cause
* unexpected reentrancy problems.
*
* \param[in] loop The loop to invoke func on.
* \param func The function to be invoked.
* \param seq A sequence number, opaque to PipeWire. This will be made
* available to func.
* \param[in] data Data that will be copied into the internal ring buffer and made
* available to func. Because this data is copied, it is okay to
* pass a pointer to a local variable, but do not pass a pointer to
* an object that has identity.
* \param size The size of data to copy.
* \param block If \true, do not return until func has been called. Otherwise,
* returns immediately. Passing \true does not risk a deadlock because
* the data thread is never allowed to wait on any other thread.
* \param user_data An opaque pointer passed to func.
* \return `-EPIPE` if the internal ring buffer filled up,
* if block is \false, 0 is returned when seq is SPA_ID_INVALID or the
* sequence number with the ASYNC bit set otherwise. When block is \true,
* the return value of func is returned.
*
* Since 0.3.3 */
int pw_data_loop_invoke(struct pw_data_loop *loop,
spa_invoke_func_t func, uint32_t seq, const void *data, size_t size,
bool block, void *user_data);

View file

@ -45,9 +45,10 @@ struct pw_impl_module_events {
#define PW_VERSION_IMPL_MODULE_EVENTS 0
uint32_t version;
/** The module is destroyed */
/** The module is destroyed. This is the time to unregister and
* destroy any objects created by the module. */
void (*destroy) (void *data);
/** The module is freed */
/** The module is freed. This will be called after destroy() returns. */
void (*free) (void *data);
/** The module is initialized */
void (*initialized) (void *data);

View file

@ -17,6 +17,8 @@ extern "C" {
* PipeWire loop object provides an implementation of
* the spa loop interfaces. It can be used to implement various
* event loops.
*
* The members of \ref pw_loop are read-only.
*/
/**

View file

@ -58,11 +58,15 @@ extern "C" {
* \li PW_DIRECTION_INPUT for a stream that *consumes* data. This can be a
* stream that captures from a Source or a when the stream is used to
* implement a Sink.
* implement a Sink. An application will use a \ref PW_DIRECTION_INPUT
* stream to record data. A virtual sound card will use a
* \ref PW_DIRECTION_INPUT stream to implement audio playback.
*
* \li PW_DIRECTION_OUTPUT for a stream that *produces* data. This can be a
* stream that plays to a Sink or when the stream is used to implement
* a Source.
* a Source. An application will use a \ref PW_DIRECTION_OUTPUT
* stream to produce data. A virtual sound card or camera will use a
* \ref PW_DIRECTION_OUTPUT stream to implement audio or video recording.
*
* \subsection ssec_stream_target Stream target
*
@ -141,6 +145,18 @@ extern "C" {
* The process event is emitted when PipeWire has emptied a buffer that
* can now be refilled.
*
* \section sec_stream_driving Driving the graph
*
* Starting in 0.3.34, it is possible for a stream to drive the graph.
* This allows interrupt-driven scheduling for drivers implemented as
* PipeWire streams, without having to reimplement the stream as a SPA
* plugin.
*
* A stream cannot drive the graph unless it is in the
* \ref PW_STREAM_STATE_STREAMING state and \ref pw_stream_is_driving() returns
* true. It must then use pw_stream_trigger_process() to start the graph
* cycle.
*
* \section sec_stream_disconnect Disconnect
*
* Use \ref pw_stream_disconnect() to disconnect a stream after use.
@ -528,7 +544,23 @@ int pw_stream_flush(struct pw_stream *stream, bool drain);
bool pw_stream_is_driving(struct pw_stream *stream);
/** Trigger a push/pull on the stream. One iteration of the graph will
* scheduled and process() will be called. Since 0.3.34 */
* be scheduled. If it successfully finishes, process() will be called.
* It is possible for the graph iteration to not finish, so
* pw_stream_trigger_process() needs to be called again even if process()
* is not called.
*
* If there is a deadline after which the stream will have xrun,
* pw_stream_trigger_process() should be called then, whether or not
* process() has been called. Sound hardware will xrun if there is
* any delay in audio processing, so the ALSA plugin triggers the
* graph every quantum to ensure audio keeps flowing. Drivers that
* do not have a deadline, such as the freewheel driver, should
* use a timeout to ensure that forward progress keeps being made.
* A reasonable choice of deadline is three times the quantum: if
* the graph is taking 3x longer than normal, it is likely that it
* is hung and should be retriggered.
*
* Since 0.3.34 */
int pw_stream_trigger_process(struct pw_stream *stream);
/**