Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/third_party/pipewire/pipewire/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 20 kB image not shown  

Quelle  stream.h   Sprache: C

 
/* PipeWire
 *
 * Copyright © 2018 Wim Taymans
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */


#ifndef PIPEWIRE_STREAM_H
#define PIPEWIRE_STREAM_H

#ifdef __cplusplus
extern "C" {
#endif

/** \page page_streams Streams
 *
 * \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.
 *
 * \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.
 *
 * \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 the port_path
 * argument while 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 event is emitted or the stream is destroyed.
 *
 * When the buffer has been processed, call \ref pw_stream_queue_buffer()
 * to let PipeWire reuse the buffer.
 *
 * \subsection ssec_produce Produce data
 *
 * \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().
 *
 * The process event is emitted when PipeWire has emptied a buffer that
 * can now be refilled.
 *
 * \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
 *
 */

/** \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 also \ref page_streams and \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>

/** \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 field are added in the future */

struct pw_buffer {
 struct spa_buffer *buffer; /**< the spa buffer */
 void *user_data;  /**< user data attached to the buffer */
 uint64_t size;   /**< This field is set by the user and the sum of
  *  all queued buffer is returned in the time info.
  *  For audio, it is advised to use the number of
  *  samples 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 samples
  *  required by the resampler. This field is 0
  *  when no suggestion is provided. Since 0.3.49 */

};

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:
 *
 *    struct timespec ts;
 *    clock_gettime(CLOCK_MONOTONIC, &ts);
 *    int64_t diff = SPA_TIMESPEC_TO_NSEC(&ts) - pw_time.now;
 *    int64_t elapsed = (pw_time.rate.denom * diff) / (pw_time.rate.num * SPA_NSEC_PER_SEC);
 *
 * 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.
 *
 * 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 or bytes (below expressed
 * as app.rate).
 *
 * pw_time.buffered is format dependent, for audio/raw it contains the number of samples
 * 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:
 *
 *  (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)
 *
 * The current extrapolated time (in ms) in the source or sink can be calculated as:
 *
 *  (pw_time.ticks + elapsed) * 1000 * pw_time.rate.num / pw_time.rate.denom
 *
 *
 *           stream time domain           graph time domain
 *         /-----------------------\/-----------------------------\
 *
 * queue     +-+ +-+  +-----------+                 +--------+
 * ---->     | | | |->| converter | ->   graph  ->  | kernel | -> speaker
 * <----     +-+ +-+  +-----------+                 +--------+
 * dequeue   buffers                \-------------------/\--------/
 *                                     graph              internal
 *                                    latency             latency
 *         \--------/\-------------/\-----------------------------/
 *           queued      buffered            delay
 */

struct pw_time {
 int64_t now;   /**< the monotonic time in nanoseconds. This is the time
  *  when this time report was updated. It is usually
  *  updated every graph cycle. You can use the current
  *  monotonic time to calculate the elapsed time between
  *  this report and the current state 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 samples 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 */
};

#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 */
 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 */
 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 */
 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. */

};

/** Create a new unconneced \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 */
       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);

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,   /**< the target object id to connect to or
  *  PW_ID_ANY to let the manager
  *  select a target. */

    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(3, 4);

/** Complete the negotiation process with result code \a res
 *
 * This function should be called after notification of the format.

 * When \a res indicates success, \a params contain the parameters for the
 * allocation state.  */

int
pw_stream_update_params(struct pw_stream *stream, /**< a \ref pw_stream */
   const struct spa_pod **params, /**< an array of params. The params should
  *  ideally contain parameters for doing
  *  buffer allocation. */

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

/** 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 */
int pw_stream_get_time_n(struct pw_stream *stream, struct pw_time *time, size_t size);

/** 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. */

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. */

struct pw_buffer *pw_stream_dequeue_buffer(struct pw_stream *stream);

/** Submit a buffer for playback or recycle a buffer for capture. */
int pw_stream_queue_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 */

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);

/** Trigger a push/pull on the stream. One iteration of the graph will
 * scheduled and process() will be called. Since 0.3.34 */

int pw_stream_trigger_process(struct pw_stream *stream);

/**
 * \}
 */


#ifdef __cplusplus
}
#endif

#endif /* PIPEWIRE_STREAM_H */

Messung V0.5
C=96 H=93 G=94

¤ Dauer der Verarbeitung: 0.6 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

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.