Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/third_party/pipewire/pipewire/   (Firefox Browser Version 153.0.1©)  Datei vom 27.6.2026 mit Größe 29 kB image not shown  

Quelle  stream.h

  Sprache: C
 

/* PipeWire */
/* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */
/* SPDX-License-Identifier: MIT */

#ifndef PIPEWIRE_STREAM_H
#define PIPEWIRE_STREAM_H

#ifdef __cplusplus
extern "C" {
#endif

/** \page page_streams Streams
 *
 * \see \ref pw_stream
 *
 * \section sec_overview Overview
 *
 * \ref pw_stream "Streams" are used to exchange data with the
 * PipeWire server. A stream is a wrapper around a proxy for a pw_client_node
 * with an adapter. This means the stream will automatically do conversion
 * to the type required by the server.
 *
 * Streams can be used to:
 *
 * \li Consume a stream from PipeWire. This is a PW_DIRECTION_INPUT stream.
 * \li Produce a stream to PipeWire. This is a PW_DIRECTION_OUTPUT stream
 *
 * You can connect the stream port to a specific server port or let PipeWire
 * choose a port for you.
 *
 * For more complicated nodes such as filters or ports with multiple
 * inputs and/or outputs you will need to use the pw_filter or make
 * a pw_node yourself and export it with \ref pw_core_export.
 *
 * Streams can also be used to:
 *
 * \li Implement a Sink in PipeWire. This is a PW_DIRECTION_INPUT stream.
 * \li Implement a Source in PipeWire. This is a PW_DIRECTION_OUTPUT stream
 *
 * In this case, the PW_KEY_MEDIA_CLASS property needs to be set to
 * "Audio/Sink" or "Audio/Source" respectively.
 *
 * \section sec_create Create
 *
 * Make a new stream with \ref pw_stream_new(). You will need to specify
 * a name for the stream and extra properties. The basic set of properties
 * each stream must provide is filled in automatically.
 *
 * Once the stream is created, the state_changed event should be used to
 * track the state of the stream.
 *
 * \section sec_connect Connect
 *
 * The stream is initially unconnected. To connect the stream, use
 * \ref pw_stream_connect(). Pass the desired direction as an argument.
 *
 * The direction is:

 * \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. 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. 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
 *
 * To make the newly connected stream automatically connect to an existing
 * PipeWire node, use the \ref PW_STREAM_FLAG_AUTOCONNECT and set the
 * PW_KEY_OBJECT_SERIAL or the PW_KEY_NODE_NAME value of the target node
 * in the PW_KEY_TARGET_OBJECT property before connecting.
 *
 * \subsection ssec_stream_formats Stream formats
 *
 * An array of possible formats that this stream can consume or provide
 * must be specified.
 *
 * \section sec_format Format negotiation
 *
 * After connecting the stream, the server will want to configure some
 * parameters on the stream. You will be notified of these changes
 * with the param_changed event.
 *
 * When a format param change is emitted, the client should now prepare
 * itself to deal with the format and complete the negotiation procedure
 * with a call to \ref pw_stream_update_params().
 *
 * As arguments to \ref pw_stream_update_params() an array of spa_param
 * structures must be given. They contain parameters such as buffer size,
 * number of buffers, required metadata and other parameters for the
 * media buffers.
 *
 * \section sec_buffers Buffer negotiation
 *
 * After completing the format negotiation, PipeWire will allocate and
 * notify the stream of the buffers that will be used to exchange data
 * between client and server.
 *
 * With the add_buffer event, a stream will be notified of a new buffer
 * that can be used for data transport. You can attach user_data to these
 * buffers. The buffers can only be used with the stream that emitted
 * the add_buffer event.
 *
 * After the buffers are negotiated, the stream will transition to the
 * \ref PW_STREAM_STATE_PAUSED state.
 *
 * \section sec_streaming Streaming
 *
 * From the \ref PW_STREAM_STATE_PAUSED state, the stream can be set to
 * the \ref PW_STREAM_STATE_STREAMING state by the PipeWire server when
 * data transport is started.
 *
 * Depending on how the stream was connected it will need to Produce or
 * Consume data for/from PipeWire as explained in the following
 * subsections.
 *
 * \subsection ssec_consume Consume data
 *
 * The process event is emitted for each new buffer that can be
 * consumed.
 *
 * \ref pw_stream_dequeue_buffer() should be used to get the data and
 * metadata of the buffer.
 *
 * The buffer is owned by the stream and stays alive until the
 * remove_buffer callback has returned or the stream is destroyed.
 *
 * When the buffer has been processed, call \ref pw_stream_queue_buffer()
 * to let PipeWire reuse the buffer.
 *
 * Although not strictly required, it is recommended to call \ref
 * pw_stream_dequeue_buffer() and pw_stream_queue_buffer() from the
 * process() callback to minimize the amount of buffering and
 * maximize the amount of buffer reuse in the stream.
 *
 * It is also possible to dequeue the buffer from the process event,
 * then process and queue the buffer from a helper thread. It is also
 * possible to dequeue, process and queue a buffer from a helper thread
 * after receiving the process event.
 *
 * \subsection ssec_produce Produce data
 *
 * The process event is emitted when a new buffer should be queued.
 *
 * When the PW_STREAM_FLAG_RT_PROCESS flag was given, this function will be
 * called from a realtime thread and it is not safe to call non-reatime
 * functions such as doing file operations, blocking operations or any of
 * the PipeWire functions that are not explicitly marked as being RT safe.
 *
 * \ref pw_stream_dequeue_buffer() gives an empty buffer that can be filled.
 *
 * The buffer is owned by the stream and stays alive until the
 * remove_buffer event is emitted or the stream is destroyed.
 *
 * Filled buffers should be queued with \ref pw_stream_queue_buffer().
 *
 * Although not strictly required, it is recommended to call \ref
 * pw_stream_dequeue_buffer() and pw_stream_queue_buffer() from the
 * process() callback to minimize the amount of buffering and
 * maximize the amount of buffer reuse in the stream.
 *
 * Buffers that are queued after the process event completes will be delayed
 * to the next processing cycle.
 *
 * \section sec_stream_timing Obtaining timing information
 *
 * With \ref pw_stream_get_time_n() and pw_stream_get_nsec() on can get accurate
 * timing information of the data and the graph in the \ref pw_time. See
 * the documentation of these functions.
 *
 * \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.
 *
 * \ref pw_stream_trigger_process() will result in a process event, where a buffer
 * should be dequeued, and queued again. This is the recommended behaviour that
 * minimizes buffering and maximized buffer reuse.
 *
 * Producers of data that drive the graph can also dequeue a buffer in a helper
 * thread, fill it with data and then call \ref pw_stream_trigger_process() to
 * start the graph cycle. In the process event they will then queue the filled
 * buffer and dequeue a new empty buffer to fill again in the helper thread,
 *
 * Consumers of data that drive the graph (pull based scheduling) will use
 * \ref pw_stream_trigger_process() to start the graph and will dequeue, process
 * and queue the buffers in the process event.
 *
 * \section sec_stream_process_requests Request processing
 *
 * A stream that is not driving the graph can request a new graph cycle by doing
 * \ref pw_stream_trigger_process(). This will result in a RequestProcess command
 * in the driver stream. If the driver supports this, it can then perform
 * \ref pw_stream_trigger_process() to start the actual graph cycle.
 *
 * \section sec_stream_disconnect Disconnect
 *
 * Use \ref pw_stream_disconnect() to disconnect a stream after use.
 *
 * \section sec_stream_configuration Configuration
 *
 * \subsection ssec_config_properties Stream Properties
 *
 * \subsection ssec_config_rules Stream Rules
 *
 * \section sec_stream_environment Environment Variables
 *
 * The environment variable PIPEWIRE_AUTOCONNECT can be used to override the
 * flag and force apps to autoconnect or not.
 *
 */

/** \defgroup pw_stream Stream
 *
 * \brief PipeWire stream objects
 *
 * The stream object provides a convenient way to send and
 * receive data streams from/to PipeWire.
 *
 * \see \ref page_streams, \ref api_pw_core
 */


/**
 * \addtogroup pw_stream
 * \{
 */

struct pw_stream;

#include <spa/buffer/buffer.h>
#include <spa/param/param.h>
#include <spa/pod/command.h>
#include <spa/pod/event.h>

/** \enum pw_stream_state The state of a stream */
enum pw_stream_state {
 PW_STREAM_STATE_ERROR = -1,  /**< the stream is in error */
 PW_STREAM_STATE_UNCONNECTED = 0/**< unconnected */
 PW_STREAM_STATE_CONNECTING = 1,  /**< connection is in progress */
 PW_STREAM_STATE_PAUSED = 2,  /**< paused */
 PW_STREAM_STATE_STREAMING = 3  /**< streaming */
};

/** a buffer structure obtained from pw_stream_dequeue_buffer(). The size of this
  * structure can grow as more fields are added in the future */

struct pw_buffer {
 struct spa_buffer *buffer; /**< the spa buffer */
 void *user_data;  /**< user data attached to the buffer. The user of
       *  the stream can set custom data associated with the
       *  buffer, typically in the add_buffer event. Any
       *  cleanup should be performed in the remove_buffer
       *  event. The user data is returned unmodified each
  *  time a buffer is dequeued. */

 uint64_t size;   /**< This field is set by the user and the sum of
       *  all queued buffers is returned in the time info.
       *  For audio, it is advised to use the number of
  *  frames in the buffer for this field. */

 uint64_t requested;  /**< For playback streams, this field contains the
       *  suggested amount of data to provide. For audio
       *  streams this will be the amount of frames
       *  required by the resampler. This field is 0
  *  when no suggestion is provided. Since 0.3.49 */

 uint64_t time;   /**< For capture streams, this field contains the
       *  cycle time in nanoseconds when this buffer was
       *  queued in the stream. It can be compared against
       *  the pw_time values or pw_stream_get_nsec()
  *  Since 1.0.5 */

};

struct pw_stream_control {
 const char *name;  /**< name of the control */
 uint32_t flags;   /**< extra flags (unused) */
 float def;   /**< default value */
 float min;   /**< min value */
 float max;   /**< max value */
 float *values;   /**< array of values */
 uint32_t n_values;  /**< number of values in array */
 uint32_t max_values;  /**< max values that can be set on this control */
};

/** A time structure.
 *
 * Use pw_stream_get_time_n() to get an updated time snapshot of the stream.
 * The time snapshot can give information about the time in the driver of the
 * graph, the delay to the edge of the graph and the internal queuing in the
 * stream.
 *
 * pw_time.ticks gives a monotonic increasing counter of the time in the graph
 * driver. I can be used to generate a timetime to schedule samples as well
 * as detect discontinuities in the timeline caused by xruns.
 *
 * pw_time.delay is expressed as pw_time.rate, the time domain of the graph. This
 * value, and pw_time.ticks, were captured at pw_time.now and can be extrapolated
 * to the current time like this:
 *
 *\code{.c}
 *    uint64_t now = pw_stream_get_nsec(stream);
 *    int64_t diff = now - pw_time.now;
 *    int64_t elapsed = (pw_time.rate.denom * diff) / (pw_time.rate.num * SPA_NSEC_PER_SEC);
 *\endcode
 *
 * pw_time.delay contains the total delay that a signal will travel through the
 * graph. This includes the delay caused by filters in the graph as well as delays
 * caused by the hardware. The delay is usually quite stable and should only change when
 * the topology, quantum or samplerate of the graph changes.
 *
 * The delay requires the application to send the stream early relative to other synchronized
 * streams in order to arrive at the edge of the graph in time. This is usually done by
 * delaying the other streams with the given delay.
 *
 * Note that the delay can be negative. A negative delay means that this stream should be
 * delayed with the (positive) delay relative to other streams.
 *
 * pw_time.queued and pw_time.buffered is expressed in the time domain of the stream,
 * or the format that is used for the buffers of this stream.
 *
 * pw_time.queued is the sum of all the pw_buffer.size fields of the buffers that are
 * currently queued in the stream but not yet processed. The application can choose
 * the units of this value, for example, time, samples, frames or bytes (below
 * expressed as app.rate).
 *
 * pw_time.buffered is format dependent, for audio/raw it contains the number of frames
 * that are buffered inside the resampler/converter.
 *
 * The total delay of data in a stream is the sum of the queued and buffered data
 * (not yet processed data) and the delay to the edge of the graph, usually a
 * playback or capture device.
 *
 * For an audio playback stream, if you were to queue a buffer, the total delay
 * in milliseconds for the first sample in the newly queued buffer to be played
 * by the hardware can be calculated as:
 *
 *\code{.unparsed}
 *  (pw_time.buffered * 1000 / stream.samplerate) +
 *    (pw_time.queued * 1000 / app.rate) +
 *     ((pw_time.delay - elapsed) * 1000 * pw_time.rate.num / pw_time.rate.denom)
 *\endcode
 *
 * The current extrapolated time (in ms) in the source or sink can be calculated as:
 *
 *\code{.unparsed}
 *  (pw_time.ticks + elapsed) * 1000 * pw_time.rate.num / pw_time.rate.denom
 *\endcode
 *
 * Below is an overview of the different timing values:
 *
 *\code{.unparsed}
 *           stream time domain           graph time domain
 *         /-----------------------\/-----------------------------\
 *
 * queue     +-+ +-+  +-----------+                 +--------+
 * ---->     | | | |->| converter | ->   graph  ->  | kernel | -> speaker
 * <----     +-+ +-+  +-----------+                 +--------+
 * dequeue   buffers                \-------------------/\--------/
 *                                     graph              internal
 *                                    latency             latency
 *         \--------/\-------------/\-----------------------------/
 *           queued      buffered            delay
 *\endcode
 */

struct pw_time {
 int64_t now;   /**< the time in nanoseconds. This is the time when this
       *  time report was updated. It is usually updated every
       *  graph cycle. You can use pw_stream_get_nsec() to
       *  calculate the elapsed time between this report and
       *  the current time and calculate updated ticks and delay
  *  values. */

 struct spa_fraction rate; /**< the rate of \a ticks and delay. This is usually
  *  expressed in 1/<samplerate>. */

 uint64_t ticks;   /**< the ticks at \a now. This is the current time that
       *  the remote end is reading/writing. This is monotonicaly
  *  increasing. */

 int64_t delay;   /**< delay to device. This is the time it will take for
       *  the next output sample of the stream to be presented by
       *  the playback device or the time a sample traveled
       *  from the capture device. This delay includes the
       *  delay introduced by all filters on the path between
       *  the stream and the device. The delay is normally
       *  constant in a graph and can change when the topology
       *  of the graph or the quantum changes. This delay does
  *  not include the delay caused by queued buffers. */

 uint64_t queued;  /**< data queued in the stream, this is the sum
       *  of the size fields in the pw_buffer that are
  *  currently queued */

 uint64_t buffered;  /**< for audio/raw streams, this contains the extra
       *  number of frames buffered in the resampler.
  *  Since 0.3.50. */

 uint32_t queued_buffers; /**< the number of buffers that are queued. Since 0.3.50 */
 uint32_t avail_buffers;  /**< the number of buffers that can be dequeued. Since 0.3.50 */
 uint64_t size;   /**< for audio/raw playback streams, this contains the number of
       *  samples requested by the resampler for the current
       *  quantum. for audio/raw capture streams this will be the number
  *  of samples available for the current quantum. Since 1.1.0 */

};

#include <pipewire/port.h>

/** Events for a stream. These events are always called from the mainloop
 * unless explicitly documented otherwise. */

struct pw_stream_events {
#define PW_VERSION_STREAM_EVENTS 2
 uint32_t version;

 void (*destroy) (void *data);
 /** when the stream state changes. Since 1.4 this also sets errno when the
 * new state is PW_STREAM_STATE_ERROR */

 void (*state_changed) (void *data, enum pw_stream_state old,
    enum pw_stream_state state, const char *error);

 /** Notify information about a control.  */
 void (*control_info) (void *data, uint32_t id, const struct pw_stream_control *control);

 /** when io changed on the stream. */
 void (*io_changed) (void *data, uint32_t id, void *area, uint32_t size);
 /** when a parameter changed */
 void (*param_changed) (void *data, uint32_t id, const struct spa_pod *param);

        /** when a new buffer was created for this stream */
        void (*add_buffer) (void *data, struct pw_buffer *buffer);
        /** when a buffer was destroyed for this stream */
        void (*remove_buffer) (void *data, struct pw_buffer *buffer);

        /** when a buffer can be queued (for playback streams) or
         *  dequeued (for capture streams). This is normally called from the
  *  mainloop but can also be called directly from the realtime data
 *  thread if the user is prepared to deal with this. */

        void (*process) (void *data);

 /** The stream is drained */
        void (*drained) (void *data);

 /** A command notify, Since 0.3.39:1 */
 void (*command) (void *data, const struct spa_command *command);

 /** a trigger_process completed. Since version 0.3.40:2.
  *  This is normally called from the mainloop but since 1.1.0 it
  *  can also be called directly from the realtime data
 *  thread if the user is prepared to deal with this. */

 void (*trigger_done) (void *data);
};

/** Convert a stream state to a readable string */
const char * pw_stream_state_as_string(enum pw_stream_state state);

/** \enum pw_stream_flags Extra flags that can be used in \ref pw_stream_connect() */
enum pw_stream_flags {
 PW_STREAM_FLAG_NONE = 0,   /**< no flags */
 PW_STREAM_FLAG_AUTOCONNECT = (1 << 0), /**< try to automatically connect
  *  this stream */

 PW_STREAM_FLAG_INACTIVE  = (1 << 1), /**< start the stream inactive,
         *  pw_stream_set_active() needs to be
  *  called explicitly */

 PW_STREAM_FLAG_MAP_BUFFERS = (1 << 2), /**< mmap the buffers except DmaBuf that is not
  *  explicitly marked as mappable. */

 PW_STREAM_FLAG_DRIVER  = (1 << 3), /**< be a driver */
 PW_STREAM_FLAG_RT_PROCESS = (1 << 4), /**< call process from the realtime
         *  thread. You MUST use RT safe functions
  *  in the process callback. */

 PW_STREAM_FLAG_NO_CONVERT = (1 << 5), /**< don't convert format */
 PW_STREAM_FLAG_EXCLUSIVE = (1 << 6), /**< require exclusive access to the
  *  device */

 PW_STREAM_FLAG_DONT_RECONNECT = (1 << 7), /**< don't try to reconnect this stream
  *  when the sink/source is removed */

 PW_STREAM_FLAG_ALLOC_BUFFERS = (1 << 8), /**< the application will allocate buffer
         *  memory. In the add_buffer event, the
  *  data of the buffer should be set */

 PW_STREAM_FLAG_TRIGGER  = (1 << 9), /**< the output stream will not be scheduled
         *  automatically but _trigger_process()
         *  needs to be called. This can be used
         *  when the output of the stream depends
  *  on input from other streams. */

 PW_STREAM_FLAG_ASYNC  = (1 << 10), /**< Buffers will not be dequeued/queued from
         *  the realtime process() function. This is
         *  assumed when RT_PROCESS is unset but can
         *  also be the case when the process() function
         *  does a trigger_process() that will then
         *  dequeue/queue a buffer from another process()
  *  function. since 0.3.73 */

 PW_STREAM_FLAG_EARLY_PROCESS = (1 << 11), /**< Call process as soon as there is a buffer
         *  to dequeue. This is only relevant for
         *  playback and when not using RT_PROCESS. It
         *  can be used to keep the maximum number of
  *  buffers queued. Since 0.3.81 */

 PW_STREAM_FLAG_RT_TRIGGER_DONE = (1 << 12), /**< Call trigger_done from the realtime
         *  thread. You MUST use RT safe functions
  *  in the trigger_done callback. Since 1.1.0 */

};

/** Create a new unconnected \ref pw_stream
 * \return a newly allocated \ref pw_stream */

struct pw_stream *
pw_stream_new(struct pw_core *core,  /**< a \ref pw_core */
       const char *name,   /**< a stream media name */
       struct pw_properties *props /**< stream properties, ownership is taken */);

struct pw_stream *
pw_stream_new_simple(struct pw_loop *loop, /**< a \ref pw_loop to use as the main loop */
       const char *name,  /**< a stream media name */
       struct pw_properties *props,/**< stream properties, ownership is taken */
       const struct pw_stream_events *events, /**< stream events */
       void *data     /**< data passed to events */);

/** Destroy a stream */
void pw_stream_destroy(struct pw_stream *stream);

void pw_stream_add_listener(struct pw_stream *stream,
       struct spa_hook *listener,
       const struct pw_stream_events *events,
       void *data);

/** Get the current stream state. Since 1.4 this also sets errno when the
 * state is PW_STREAM_STATE_ERROR */

enum pw_stream_state pw_stream_get_state(struct pw_stream *stream, const char **error);

const char *pw_stream_get_name(struct pw_stream *stream);

struct pw_core *pw_stream_get_core(struct pw_stream *stream);

const struct pw_properties *pw_stream_get_properties(struct pw_stream *stream);

int pw_stream_update_properties(struct pw_stream *stream, const struct spa_dict *dict);

/** Connect a stream for input or output on \a port_path.
 * \return 0 on success < 0 on error.
 *
 * You should connect to the process event and use pw_stream_dequeue_buffer()
 * to get the latest metadata and data. */

int
pw_stream_connect(struct pw_stream *stream,  /**< a \ref pw_stream */
    enum pw_direction direction,  /**< the stream direction */
    uint32_t target_id,   /**< should have the value PW_ID_ANY.
         * To select a specific target
         * node, specify the
         * PW_KEY_OBJECT_SERIAL or the
         * PW_KEY_NODE_NAME value of the target
         * node in the PW_KEY_TARGET_OBJECT
         * property of the stream.
         * Specifying target nodes by
         * their id is deprecated.
  */

    enum pw_stream_flags flags,  /**< stream flags */
    const struct spa_pod **params, /**< an array with params. The params
         *  should ideally contain supported
  *  formats. */

    uint32_t n_params   /**< number of items in \a params */);

/** Get the node ID of the stream.
 * \return node ID. */

uint32_t
pw_stream_get_node_id(struct pw_stream *stream);

/** Disconnect \a stream  */
int pw_stream_disconnect(struct pw_stream *stream);

/** Set the stream in error state */
int pw_stream_set_error(struct pw_stream *stream, /**< a \ref pw_stream */
   int res,   /**< a result code */
   const char *error,  /**< an error message */
   ...) SPA_PRINTF_FUNC(34);

/** Update the param exposed on the stream. */
int
pw_stream_update_params(struct pw_stream *stream, /**< a \ref pw_stream */
   const struct spa_pod **params, /**< an array of params. */
   uint32_t n_params  /**< number of elements in \a params */);

/**
 * Set a parameter on the stream. This is like pw_stream_set_control() but with
 * a complete spa_pod param. It can also be called from the param_changed event handler
 * to intercept and modify the param for the adapter. Since 0.3.70 */

int pw_stream_set_param(struct pw_stream *stream, /**< a \ref pw_stream */
   uint32_t id,   /**< the id of the param */
   const struct spa_pod *param /**< the params to set */);

/** Get control values */
const struct pw_stream_control *pw_stream_get_control(struct pw_stream *stream, uint32_t id);

/** Set control values */
int pw_stream_set_control(struct pw_stream *stream, uint32_t id, uint32_t n_values, float *values, ...);

/** Query the time on the stream, RT safe */
int pw_stream_get_time_n(struct pw_stream *stream, struct pw_time *time, size_t size);

/** Get the current time in nanoseconds. This value can be compared with
 * the \ref pw_time.now value. RT safe. Since 1.1.0 */

uint64_t pw_stream_get_nsec(struct pw_stream *stream);

/** Get the data loop that is doing the processing of this stream. This loop
 * is assigned after pw_stream_connect().  * Since 1.1.0 */

struct pw_loop *pw_stream_get_data_loop(struct pw_stream *stream);

/** Query the time on the stream, deprecated since 0.3.50,
 * use pw_stream_get_time_n() to get the fields added since 0.3.50. RT safe. */

SPA_DEPRECATED
int pw_stream_get_time(struct pw_stream *stream, struct pw_time *time);

/** Get a buffer that can be filled for playback streams or consumed
 * for capture streams. RT safe. */

struct pw_buffer *pw_stream_dequeue_buffer(struct pw_stream *stream);

/** Submit a buffer for playback or recycle a buffer for capture. RT safe. */
int pw_stream_queue_buffer(struct pw_stream *stream, struct pw_buffer *buffer);

/** Return a buffer to the queue without using it. This makes the buffer
 * immediately available to dequeue again. RT safe. */

int pw_stream_return_buffer(struct pw_stream *stream, struct pw_buffer *buffer);

/** Activate or deactivate the stream */
int pw_stream_set_active(struct pw_stream *stream, bool active);

/** Flush a stream. When \a drain is true, the drained callback will
 * be called when all data is played or recorded. The stream can be resumed
 * after the drain by setting it active again with
 * \ref pw_stream_set_active(). A flush without a drain is mostly useful afer
 * a state change to PAUSED, to flush any remaining data from the queues and
 * the converters. RT safe. */

int pw_stream_flush(struct pw_stream *stream, bool drain);

/** Check if the stream is driving. The stream needs to have the
 * PW_STREAM_FLAG_DRIVER set. When the stream is driving,
 * pw_stream_trigger_process() needs to be called when data is
 * available (output) or needed (input). Since 0.3.34 */

bool pw_stream_is_driving(struct pw_stream *stream);

/** Check if the graph is using lazy scheduling. If the stream is
 * driving according to \ref pw_stream_is_driving(), then it should
 * consider taking into account the RequestProcess commands when
 * driving the graph.
 *
 * If the stream is not driving, it should send out RequestProcess
 * events with \ref pw_stream_emit_event() or indirectly with
 * \ref pw_stream_trigger_process() to suggest a new graph cycle
 * to the driver.
 *
 * It is not a requirement that all RequestProcess events/commands
 * need to start a graph cycle.
 * Since 1.4.0 */

bool pw_stream_is_lazy(struct pw_stream *stream);

/** Trigger a push/pull on the stream. One iteration of the graph will
 * be scheduled when the stream is driving according to
 * \ref pw_stream_is_driving(). If it successfully finishes, process()
 * will be called and the trigger_done event will be emitted. It is
 * possible for the graph iteration to not finish, so
 * pw_stream_trigger_process() needs to be called again even if process()
 * and trigger_done 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()/trigger_done 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.
 *
 * Streams that are not drivers according to \ref pw_stream_is_driving()
 * can also call this method. The result is that a RequestProcess event
 * is sent to the driver. If the graph is lazy scheduling according to
 * \ref pw_stream_is_lazy(), this might result in a graph cycle by the
 * driver. If the graph is not lazy scheduling and the stream is not a
 * driver, this method will have no effect.
 *
 * RT safe.
 *
 * Since 0.3.34 */

int pw_stream_trigger_process(struct pw_stream *stream);

/** Emit an event from this stream. RT safe.
 * Since 1.2.6 */

int pw_stream_emit_event(struct pw_stream *stream, const struct spa_event *event);

/** Adjust the rate of the stream.
 * When the stream is using an adaptive resampler, adjust the resampler rate.
 * When there is no resampler, -ENOTSUP is returned. Activating the adaptive
 * resampler will add a small amount of delay to the samples, you can deactivate
 * it again by setting a value <= 0.0. RT safe.
 * Since 1.4.0 */

int pw_stream_set_rate(struct pw_stream *stream, double rate);

/**
 * \}
 */


#ifdef __cplusplus
}
#endif

#endif /* PIPEWIRE_STREAM_H */

Messung V0.5 in Prozent
C=91 H=84 G=87

¤ Dauer der Verarbeitung: 0.24 Sekunden  (vorverarbeitet am  2026-08-25) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.