mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-31 22:25:38 -04:00
video: add video format
start working on v4l2 source
This commit is contained in:
parent
3c029cba53
commit
beedb65f00
25 changed files with 1878 additions and 43 deletions
|
|
@ -296,12 +296,12 @@ static void
|
|||
on_linked (PinosPort *port, PinosPort *peer, gpointer user_data)
|
||||
{
|
||||
PinosNode *node = user_data;
|
||||
gint n_peers;
|
||||
guint n_links;
|
||||
|
||||
g_debug ("port %p: linked", port);
|
||||
|
||||
n_peers = pinos_port_get_n_links (port);
|
||||
if (n_peers == 1)
|
||||
pinos_port_get_links (port, &n_links);
|
||||
if (n_links == 1)
|
||||
pinos_node_report_busy (node);
|
||||
}
|
||||
|
||||
|
|
@ -309,11 +309,11 @@ static void
|
|||
on_unlinked (PinosPort *port, PinosPort *peer, gpointer user_data)
|
||||
{
|
||||
PinosNode *node = user_data;
|
||||
gint n_peers;
|
||||
guint n_links;
|
||||
|
||||
g_debug ("port %p: unlinked", port);
|
||||
n_peers = pinos_port_get_n_links (port);
|
||||
if (n_peers == 0)
|
||||
pinos_port_get_links (port, &n_links);
|
||||
if (n_links == 1)
|
||||
pinos_node_report_idle (node);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,9 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
#include <spa/format.h>
|
||||
#include <spa/audio/raw.h>
|
||||
|
||||
typedef struct _SpaAudioRawFormat SpaAudioRawFormat;
|
||||
|
||||
typedef enum {
|
||||
SPA_PROP_ID_AUDIO_FORMAT = SPA_PROP_ID_MEDIA_CUSTOM_START,
|
||||
|
|
@ -36,6 +39,16 @@ typedef enum {
|
|||
SPA_PROP_ID_AUDIO_RAW_INFO,
|
||||
} SpaPropIdAudio;
|
||||
|
||||
struct _SpaAudioRawFormat {
|
||||
SpaFormat format;
|
||||
uint32_t unset_mask;
|
||||
SpaAudioRawInfo info;
|
||||
};
|
||||
|
||||
SpaResult spa_audio_raw_format_init (SpaAudioRawFormat *format);
|
||||
SpaResult spa_audio_raw_format_parse (const SpaFormat *format,
|
||||
SpaAudioRawFormat *rawformat);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
|
|
|||
|
|
@ -25,12 +25,9 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
typedef struct _SpaAudioRawInfo SpaAudioRawInfo;
|
||||
typedef struct _SpaAudioRawFormat SpaAudioRawFormat;
|
||||
|
||||
#include <endian.h>
|
||||
|
||||
#include <spa/audio/format.h>
|
||||
|
||||
#if __BYTE_ORDER == __BIG_ENDIAN
|
||||
#define _SPA_AUDIO_FORMAT_NE(fmt) SPA_AUDIO_FORMAT_ ## fmt ## BE
|
||||
#define _SPA_AUDIO_FORMAT_OE(fmt) SPA_AUDIO_FORMAT_ ## fmt ## LE
|
||||
|
|
@ -141,16 +138,6 @@ struct _SpaAudioRawInfo {
|
|||
uint32_t channel_mask;
|
||||
};
|
||||
|
||||
struct _SpaAudioRawFormat {
|
||||
SpaFormat format;
|
||||
uint32_t unset_mask;
|
||||
SpaAudioRawInfo info;
|
||||
};
|
||||
|
||||
SpaResult spa_audio_raw_format_init (SpaAudioRawFormat *format);
|
||||
SpaResult spa_audio_raw_format_parse (const SpaFormat *format,
|
||||
SpaAudioRawFormat *rawformat);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ typedef struct {
|
|||
* SpaDataType:
|
||||
* @SPA_DATA_TYPE_INVALID: invalid data type, is ignored
|
||||
* @SPA_DATA_TYPE_MEMPTR: data and size point to memory
|
||||
* @SPA_DATA_TYPE_FD: data points to SpaDataFd
|
||||
* @SPA_DATA_TYPE_FD: data points to an int file descriptor
|
||||
*/
|
||||
typedef enum {
|
||||
SPA_DATA_TYPE_INVALID = 0,
|
||||
|
|
@ -90,29 +90,21 @@ typedef enum {
|
|||
SPA_DATA_TYPE_FD,
|
||||
} SpaDataType;
|
||||
|
||||
/**
|
||||
* SpaDataFd
|
||||
* fd: a file descriptor
|
||||
* offset: offset in the data referenced by @fd
|
||||
* @size: size of data referenced by fd
|
||||
*/
|
||||
typedef struct {
|
||||
int fd;
|
||||
unsigned int offset;
|
||||
size_t size;
|
||||
} SpaDataFD;
|
||||
|
||||
/**
|
||||
* SpaData:
|
||||
* @id: user id
|
||||
* @type: the type of data
|
||||
* @data: pointer to data
|
||||
* @data: pointer to data or fd
|
||||
* @offset: offset of data
|
||||
* @size: size of data
|
||||
* @stride: stride of data
|
||||
*/
|
||||
typedef struct {
|
||||
SpaDataType type;
|
||||
void *data;
|
||||
unsigned int offset;
|
||||
size_t size;
|
||||
size_t stride;
|
||||
} SpaData;
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ typedef struct _SpaFormat SpaFormat;
|
|||
typedef enum {
|
||||
SPA_MEDIA_TYPE_INVALID = 0,
|
||||
SPA_MEDIA_TYPE_AUDIO = 1,
|
||||
SPA_MEDIA_TYPE_VIDEO = 2,
|
||||
} SpaMediaType;
|
||||
|
||||
typedef enum {
|
||||
|
|
|
|||
|
|
@ -53,6 +53,11 @@ typedef enum {
|
|||
SPA_PROP_TYPE_STRUCT,
|
||||
} SpaPropType;
|
||||
|
||||
typedef struct {
|
||||
int32_t num;
|
||||
int32_t denom;
|
||||
} SpaFraction;
|
||||
|
||||
/**
|
||||
* SpaPropFlags:
|
||||
* @SPA_PROP_FLAG_NONE: no flags
|
||||
|
|
@ -74,10 +79,8 @@ typedef enum {
|
|||
/* SpaPropRangeType:
|
||||
* @SPA_PROP_RANGE_TYPE_NONE: no range specified, full range of type applies
|
||||
* @SPA_PROP_RANGE_TYPE_MIN_MAX: range contains 2 values, min and max
|
||||
* @SPA_PROP_RANGE_TYPE_ENUM: range contains enum of possible values with
|
||||
* NULL-terminated name
|
||||
* @SPA_PROP_RANGE_TYPE_FLAGS: range contains flags of possible values with
|
||||
* NULL-terminated name
|
||||
* @SPA_PROP_RANGE_TYPE_ENUM: range contains enum of possible values
|
||||
* @SPA_PROP_RANGE_TYPE_FLAGS: range contains flags of possible values
|
||||
*/
|
||||
typedef enum {
|
||||
SPA_PROP_RANGE_TYPE_NONE = 0,
|
||||
|
|
|
|||
58
spa/include/spa/video/chroma.h
Normal file
58
spa/include/spa/video/chroma.h
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
/* Simple Plugin API
|
||||
* Copyright (C) 2016 Wim Taymans <wim.taymans@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __SPA_VIDEO_CHROMA_H__
|
||||
#define __SPA_VIDEO_CHROMA_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* SpaVideoChromaSite:
|
||||
* @SPA_VIDEO_CHROMA_SITE_UNKNOWN: unknown cositing
|
||||
* @SPA_VIDEO_CHROMA_SITE_NONE: no cositing
|
||||
* @SPA_VIDEO_CHROMA_SITE_H_COSITED: chroma is horizontally cosited
|
||||
* @SPA_VIDEO_CHROMA_SITE_V_COSITED: chroma is vertically cosited
|
||||
* @SPA_VIDEO_CHROMA_SITE_ALT_LINE: choma samples are sited on alternate lines
|
||||
* @SPA_VIDEO_CHROMA_SITE_COSITED: chroma samples cosited with luma samples
|
||||
* @SPA_VIDEO_CHROMA_SITE_JPEG: jpeg style cositing, also for mpeg1 and mjpeg
|
||||
* @SPA_VIDEO_CHROMA_SITE_MPEG2: mpeg2 style cositing
|
||||
* @SPA_VIDEO_CHROMA_SITE_DV: DV style cositing
|
||||
*
|
||||
* Various Chroma sitings.
|
||||
*/
|
||||
typedef enum {
|
||||
SPA_VIDEO_CHROMA_SITE_UNKNOWN = 0,
|
||||
SPA_VIDEO_CHROMA_SITE_NONE = (1 << 0),
|
||||
SPA_VIDEO_CHROMA_SITE_H_COSITED = (1 << 1),
|
||||
SPA_VIDEO_CHROMA_SITE_V_COSITED = (1 << 2),
|
||||
SPA_VIDEO_CHROMA_SITE_ALT_LINE = (1 << 3),
|
||||
/* some common chroma cositing */
|
||||
SPA_VIDEO_CHROMA_SITE_COSITED = (SPA_VIDEO_CHROMA_SITE_H_COSITED | SPA_VIDEO_CHROMA_SITE_V_COSITED),
|
||||
SPA_VIDEO_CHROMA_SITE_JPEG = (SPA_VIDEO_CHROMA_SITE_NONE),
|
||||
SPA_VIDEO_CHROMA_SITE_MPEG2 = (SPA_VIDEO_CHROMA_SITE_H_COSITED),
|
||||
SPA_VIDEO_CHROMA_SITE_DV = (SPA_VIDEO_CHROMA_SITE_COSITED | SPA_VIDEO_CHROMA_SITE_ALT_LINE),
|
||||
} SpaVideoChromaSite;
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* __SPA_VIDEO_CHROMA_H__ */
|
||||
157
spa/include/spa/video/color.h
Normal file
157
spa/include/spa/video/color.h
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
/* Simple Plugin API
|
||||
* Copyright (C) 2016 Wim Taymans <wim.taymans@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __SPA_VIDEO_COLOR_H__
|
||||
#define __SPA_VIDEO_COLOR_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* SpaVideoColorRange:
|
||||
* @SPA_VIDEO_COLOR_RANGE_UNKNOWN: unknown range
|
||||
* @SPA_VIDEO_COLOR_RANGE_0_255: [0..255] for 8 bit components
|
||||
* @SPA_VIDEO_COLOR_RANGE_16_235: [16..235] for 8 bit components. Chroma has
|
||||
* [16..240] range.
|
||||
*
|
||||
* Possible color range values. These constants are defined for 8 bit color
|
||||
* values and can be scaled for other bit depths.
|
||||
*/
|
||||
typedef enum {
|
||||
SPA_VIDEO_COLOR_RANGE_UNKNOWN = 0,
|
||||
SPA_VIDEO_COLOR_RANGE_0_255,
|
||||
SPA_VIDEO_COLOR_RANGE_16_235
|
||||
} SpaVideoColorRange;
|
||||
|
||||
/**
|
||||
* SpaVideoColorMatrix:
|
||||
* @SPA_VIDEO_COLOR_MATRIX_UNKNOWN: unknown matrix
|
||||
* @SPA_VIDEO_COLOR_MATRIX_RGB: identity matrix
|
||||
* @SPA_VIDEO_COLOR_MATRIX_FCC: FCC color matrix
|
||||
* @SPA_VIDEO_COLOR_MATRIX_BT709: ITU-R BT.709 color matrix
|
||||
* @SPA_VIDEO_COLOR_MATRIX_BT601: ITU-R BT.601 color matrix
|
||||
* @SPA_VIDEO_COLOR_MATRIX_SMPTE240M: SMPTE 240M color matrix
|
||||
* @SPA_VIDEO_COLOR_MATRIX_BT2020: ITU-R BT.2020 color matrix. Since: 1.6.
|
||||
*
|
||||
* The color matrix is used to convert between Y'PbPr and
|
||||
* non-linear RGB (R'G'B')
|
||||
*/
|
||||
typedef enum {
|
||||
SPA_VIDEO_COLOR_MATRIX_UNKNOWN = 0,
|
||||
SPA_VIDEO_COLOR_MATRIX_RGB,
|
||||
SPA_VIDEO_COLOR_MATRIX_FCC,
|
||||
SPA_VIDEO_COLOR_MATRIX_BT709,
|
||||
SPA_VIDEO_COLOR_MATRIX_BT601,
|
||||
SPA_VIDEO_COLOR_MATRIX_SMPTE240M,
|
||||
SPA_VIDEO_COLOR_MATRIX_BT2020
|
||||
} SpaVideoColorMatrix;
|
||||
|
||||
/**
|
||||
* SpaVideoTransferFunction:
|
||||
* @SPA_VIDEO_TRANSFER_UNKNOWN: unknown transfer function
|
||||
* @SPA_VIDEO_TRANSFER_GAMMA10: linear RGB, gamma 1.0 curve
|
||||
* @SPA_VIDEO_TRANSFER_GAMMA18: Gamma 1.8 curve
|
||||
* @SPA_VIDEO_TRANSFER_GAMMA20: Gamma 2.0 curve
|
||||
* @SPA_VIDEO_TRANSFER_GAMMA22: Gamma 2.2 curve
|
||||
* @SPA_VIDEO_TRANSFER_BT709: Gamma 2.2 curve with a linear segment in the lower
|
||||
* range
|
||||
* @SPA_VIDEO_TRANSFER_SMPTE240M: Gamma 2.2 curve with a linear segment in the
|
||||
* lower range
|
||||
* @SPA_VIDEO_TRANSFER_SRGB: Gamma 2.4 curve with a linear segment in the lower
|
||||
* range
|
||||
* @SPA_VIDEO_TRANSFER_GAMMA28: Gamma 2.8 curve
|
||||
* @SPA_VIDEO_TRANSFER_LOG100: Logarithmic transfer characteristic
|
||||
* 100:1 range
|
||||
* @SPA_VIDEO_TRANSFER_LOG316: Logarithmic transfer characteristic
|
||||
* 316.22777:1 range
|
||||
* @SPA_VIDEO_TRANSFER_BT2020_12: Gamma 2.2 curve with a linear segment in the lower
|
||||
* range. Used for BT.2020 with 12 bits per
|
||||
* component. Since: 1.6.
|
||||
* @SPA_VIDEO_TRANSFER_ADOBERGB: Gamma 2.19921875. Since: 1.8
|
||||
*
|
||||
* The video transfer function defines the formula for converting between
|
||||
* non-linear RGB (R'G'B') and linear RGB
|
||||
*/
|
||||
typedef enum {
|
||||
SPA_VIDEO_TRANSFER_UNKNOWN = 0,
|
||||
SPA_VIDEO_TRANSFER_GAMMA10,
|
||||
SPA_VIDEO_TRANSFER_GAMMA18,
|
||||
SPA_VIDEO_TRANSFER_GAMMA20,
|
||||
SPA_VIDEO_TRANSFER_GAMMA22,
|
||||
SPA_VIDEO_TRANSFER_BT709,
|
||||
SPA_VIDEO_TRANSFER_SMPTE240M,
|
||||
SPA_VIDEO_TRANSFER_SRGB,
|
||||
SPA_VIDEO_TRANSFER_GAMMA28,
|
||||
SPA_VIDEO_TRANSFER_LOG100,
|
||||
SPA_VIDEO_TRANSFER_LOG316,
|
||||
SPA_VIDEO_TRANSFER_BT2020_12,
|
||||
SPA_VIDEO_TRANSFER_ADOBERGB
|
||||
} SpaVideoTransferFunction;
|
||||
|
||||
/**
|
||||
* SpaVideoColorPrimaries:
|
||||
* @SPA_VIDEO_COLOR_PRIMARIES_UNKNOWN: unknown color primaries
|
||||
* @SPA_VIDEO_COLOR_PRIMARIES_BT709: BT709 primaries
|
||||
* @SPA_VIDEO_COLOR_PRIMARIES_BT470M: BT470M primaries
|
||||
* @SPA_VIDEO_COLOR_PRIMARIES_BT470BG: BT470BG primaries
|
||||
* @SPA_VIDEO_COLOR_PRIMARIES_SMPTE170M: SMPTE170M primaries
|
||||
* @SPA_VIDEO_COLOR_PRIMARIES_SMPTE240M: SMPTE240M primaries
|
||||
* @SPA_VIDEO_COLOR_PRIMARIES_FILM: Generic film
|
||||
* @SPA_VIDEO_COLOR_PRIMARIES_BT2020: BT2020 primaries. Since: 1.6.
|
||||
* @SPA_VIDEO_COLOR_PRIMARIES_ADOBERGB: Adobe RGB primaries. Since: 1.8
|
||||
*
|
||||
* The color primaries define the how to transform linear RGB values to and from
|
||||
* the CIE XYZ colorspace.
|
||||
*/
|
||||
typedef enum {
|
||||
SPA_VIDEO_COLOR_PRIMARIES_UNKNOWN = 0,
|
||||
SPA_VIDEO_COLOR_PRIMARIES_BT709,
|
||||
SPA_VIDEO_COLOR_PRIMARIES_BT470M,
|
||||
SPA_VIDEO_COLOR_PRIMARIES_BT470BG,
|
||||
SPA_VIDEO_COLOR_PRIMARIES_SMPTE170M,
|
||||
SPA_VIDEO_COLOR_PRIMARIES_SMPTE240M,
|
||||
SPA_VIDEO_COLOR_PRIMARIES_FILM,
|
||||
SPA_VIDEO_COLOR_PRIMARIES_BT2020,
|
||||
SPA_VIDEO_COLOR_PRIMARIES_ADOBERGB
|
||||
} SpaVideoColorPrimaries;
|
||||
|
||||
/**
|
||||
* SpaVideoColorimetry:
|
||||
* @range: the color range. This is the valid range for the samples.
|
||||
* It is used to convert the samples to Y'PbPr values.
|
||||
* @matrix: the color matrix. Used to convert between Y'PbPr and
|
||||
* non-linear RGB (R'G'B')
|
||||
* @transfer: the transfer function. used to convert between R'G'B' and RGB
|
||||
* @primaries: color primaries. used to convert between R'G'B' and CIE XYZ
|
||||
*
|
||||
* Structure describing the color info.
|
||||
*/
|
||||
typedef struct {
|
||||
SpaVideoColorRange range;
|
||||
SpaVideoColorMatrix matrix;
|
||||
SpaVideoTransferFunction transfer;
|
||||
SpaVideoColorPrimaries primaries;
|
||||
} SpaVideoColorimetry;
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* __SPA_VIDEO_COLOR_H__ */
|
||||
66
spa/include/spa/video/format.h
Normal file
66
spa/include/spa/video/format.h
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
/* Simple Plugin API
|
||||
* Copyright (C) 2016 Wim Taymans <wim.taymans@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __SPA_VIDEO_FORMAT_H__
|
||||
#define __SPA_VIDEO_FORMAT_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <spa/format.h>
|
||||
#include <spa/video/raw.h>
|
||||
|
||||
typedef struct _SpaVideoRawFormat SpaVideoRawFormat;
|
||||
|
||||
typedef enum {
|
||||
SPA_PROP_ID_VIDEO_FORMAT = SPA_PROP_ID_MEDIA_CUSTOM_START,
|
||||
SPA_PROP_ID_VIDEO_WIDTH,
|
||||
SPA_PROP_ID_VIDEO_HEIGHT,
|
||||
SPA_PROP_ID_VIDEO_FRAMERATE,
|
||||
SPA_PROP_ID_VIDEO_MAX_FRAMERATE,
|
||||
SPA_PROP_ID_VIDEO_VIEWS,
|
||||
SPA_PROP_ID_VIDEO_INTERLACE_MODE,
|
||||
SPA_PROP_ID_VIDEO_PIXEL_ASPECT_RATIO,
|
||||
SPA_PROP_ID_VIDEO_MULTIVIEW_MODE,
|
||||
SPA_PROP_ID_VIDEO_MULTIVIEW_FLAGS,
|
||||
SPA_PROP_ID_VIDEO_CHROMA_SITE,
|
||||
SPA_PROP_ID_VIDEO_COLOR_RANGE,
|
||||
SPA_PROP_ID_VIDEO_COLOR_MATRIX,
|
||||
SPA_PROP_ID_VIDEO_TRANSFER_FUNCTION,
|
||||
SPA_PROP_ID_VIDEO_COLOR_PRIMARIES,
|
||||
SPA_PROP_ID_VIDEO_RAW_INFO,
|
||||
} SpaPropIdVideo;
|
||||
|
||||
struct _SpaVideoRawFormat {
|
||||
SpaFormat format;
|
||||
uint32_t unset_mask;
|
||||
SpaVideoRawInfo info;
|
||||
};
|
||||
|
||||
SpaResult spa_video_raw_format_init (SpaVideoRawFormat *format);
|
||||
SpaResult spa_video_raw_format_parse (const SpaFormat *format,
|
||||
SpaVideoRawFormat *rawformat);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* __SPA_VIDEO_FORMAT */
|
||||
136
spa/include/spa/video/multiview.h
Normal file
136
spa/include/spa/video/multiview.h
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
/* Simple Plugin API
|
||||
* Copyright (C) 2016 Wim Taymans <wim.taymans@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __SPA_VIDEO_MULTIVIEW_H__
|
||||
#define __SPA_VIDEO_MULTIVIEW_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* SpaVideoMultiviewMode:
|
||||
* @SPA_VIDEO_MULTIVIEW_MODE_NONE: A special value indicating
|
||||
* no multiview information. Used in SpaVideoInfo and other places to
|
||||
* indicate that no specific multiview handling has been requested or
|
||||
* provided. This value is never carried on caps.
|
||||
* @SPA_VIDEO_MULTIVIEW_MODE_MONO: All frames are monoscopic.
|
||||
* @SPA_VIDEO_MULTIVIEW_MODE_LEFT: All frames represent a left-eye view.
|
||||
* @SPA_VIDEO_MULTIVIEW_MODE_RIGHT: All frames represent a right-eye view.
|
||||
* @SPA_VIDEO_MULTIVIEW_MODE_SIDE_BY_SIDE: Left and right eye views are
|
||||
* provided in the left and right half of the frame respectively.
|
||||
* @SPA_VIDEO_MULTIVIEW_MODE_SIDE_BY_SIDE_QUINCUNX: Left and right eye
|
||||
* views are provided in the left and right half of the frame, but
|
||||
* have been sampled using quincunx method, with half-pixel offset
|
||||
* between the 2 views.
|
||||
* @SPA_VIDEO_MULTIVIEW_MODE_COLUMN_INTERLEAVED: Alternating vertical
|
||||
* columns of pixels represent the left and right eye view respectively.
|
||||
* @SPA_VIDEO_MULTIVIEW_MODE_ROW_INTERLEAVED: Alternating horizontal
|
||||
* rows of pixels represent the left and right eye view respectively.
|
||||
* @SPA_VIDEO_MULTIVIEW_MODE_TOP_BOTTOM: The top half of the frame
|
||||
* contains the left eye, and the bottom half the right eye.
|
||||
* @SPA_VIDEO_MULTIVIEW_MODE_CHECKERBOARD: Pixels are arranged with
|
||||
* alternating pixels representing left and right eye views in a
|
||||
* checkerboard fashion.
|
||||
* @SPA_VIDEO_MULTIVIEW_MODE_FRAME_BY_FRAME: Left and right eye views
|
||||
* are provided in separate frames alternately.
|
||||
* @SPA_VIDEO_MULTIVIEW_MODE_MULTIVIEW_FRAME_BY_FRAME: Multiple
|
||||
* independent views are provided in separate frames in sequence.
|
||||
* This method only applies to raw video buffers at the moment.
|
||||
* Specific view identification is via the #SpaVideoMultiviewMeta
|
||||
* and #SpaVideoMeta(s) on raw video buffers.
|
||||
* @SPA_VIDEO_MULTIVIEW_MODE_SEPARATED: Multiple views are
|
||||
* provided as separate #SpaMemory framebuffers attached to each
|
||||
* #SpaBuffer, described by the #SpaVideoMultiviewMeta
|
||||
* and #SpaVideoMeta(s)
|
||||
*
|
||||
* All possible stereoscopic 3D and multiview representations.
|
||||
* In conjunction with #SpaVideoMultiviewFlags, describes how
|
||||
* multiview content is being transported in the stream.
|
||||
*/
|
||||
typedef enum {
|
||||
SPA_VIDEO_MULTIVIEW_MODE_NONE = -1,
|
||||
SPA_VIDEO_MULTIVIEW_MODE_MONO = 0,
|
||||
/* Single view modes */
|
||||
SPA_VIDEO_MULTIVIEW_MODE_LEFT,
|
||||
SPA_VIDEO_MULTIVIEW_MODE_RIGHT,
|
||||
/* Stereo view modes */
|
||||
SPA_VIDEO_MULTIVIEW_MODE_SIDE_BY_SIDE,
|
||||
SPA_VIDEO_MULTIVIEW_MODE_SIDE_BY_SIDE_QUINCUNX,
|
||||
SPA_VIDEO_MULTIVIEW_MODE_COLUMN_INTERLEAVED,
|
||||
SPA_VIDEO_MULTIVIEW_MODE_ROW_INTERLEAVED,
|
||||
SPA_VIDEO_MULTIVIEW_MODE_TOP_BOTTOM,
|
||||
SPA_VIDEO_MULTIVIEW_MODE_CHECKERBOARD,
|
||||
/* Padding for new frame packing modes */
|
||||
|
||||
SPA_VIDEO_MULTIVIEW_MODE_FRAME_BY_FRAME = 32,
|
||||
/* Multivew mode(s) */
|
||||
SPA_VIDEO_MULTIVIEW_MODE_MULTIVIEW_FRAME_BY_FRAME,
|
||||
SPA_VIDEO_MULTIVIEW_MODE_SEPARATED
|
||||
/* future expansion for annotated modes */
|
||||
} SpaVideoMultiviewMode;
|
||||
|
||||
/**
|
||||
* SpaVideoMultiviewFlags:
|
||||
* @SPA_VIDEO_MULTIVIEW_FLAGS_NONE: No flags
|
||||
* @SPA_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST: For stereo streams, the
|
||||
* normal arrangement of left and right views is reversed.
|
||||
* @SPA_VIDEO_MULTIVIEW_FLAGS_LEFT_FLIPPED: The left view is vertically
|
||||
* mirrored.
|
||||
* @SPA_VIDEO_MULTIVIEW_FLAGS_LEFT_FLOPPED: The left view is horizontally
|
||||
* mirrored.
|
||||
* @SPA_VIDEO_MULTIVIEW_FLAGS_RIGHT_FLIPPED: The right view is
|
||||
* vertically mirrored.
|
||||
* @SPA_VIDEO_MULTIVIEW_FLAGS_RIGHT_FLOPPED: The right view is
|
||||
* horizontally mirrored.
|
||||
* @SPA_VIDEO_MULTIVIEW_FLAGS_HALF_ASPECT: For frame-packed
|
||||
* multiview modes, indicates that the individual
|
||||
* views have been encoded with half the true width or height
|
||||
* and should be scaled back up for display. This flag
|
||||
* is used for overriding input layout interpretation
|
||||
* by adjusting pixel-aspect-ratio.
|
||||
* For side-by-side, column interleaved or checkerboard packings, the
|
||||
* pixel width will be doubled. For row interleaved and top-bottom
|
||||
* encodings, pixel height will be doubled.
|
||||
* @SPA_VIDEO_MULTIVIEW_FLAGS_MIXED_MONO: The video stream contains both
|
||||
* mono and multiview portions, signalled on each buffer by the
|
||||
* absence or presence of the @SPA_VIDEO_BUFFER_FLAG_MULTIPLE_VIEW
|
||||
* buffer flag.
|
||||
*
|
||||
* SpaVideoMultiviewFlags are used to indicate extra properties of a
|
||||
* stereo/multiview stream beyond the frame layout and buffer mapping
|
||||
* that is conveyed in the #SpaMultiviewMode.
|
||||
*/
|
||||
typedef enum {
|
||||
SPA_VIDEO_MULTIVIEW_FLAGS_NONE = 0,
|
||||
SPA_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST = (1 << 0),
|
||||
SPA_VIDEO_MULTIVIEW_FLAGS_LEFT_FLIPPED = (1 << 1),
|
||||
SPA_VIDEO_MULTIVIEW_FLAGS_LEFT_FLOPPED = (1 << 2),
|
||||
SPA_VIDEO_MULTIVIEW_FLAGS_RIGHT_FLIPPED = (1 << 3),
|
||||
SPA_VIDEO_MULTIVIEW_FLAGS_RIGHT_FLOPPED = (1 << 4),
|
||||
SPA_VIDEO_MULTIVIEW_FLAGS_HALF_ASPECT = (1 << 14),
|
||||
SPA_VIDEO_MULTIVIEW_FLAGS_MIXED_MONO = (1 << 15)
|
||||
} SpaVideoMultiviewFlags;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* __SPA_VIDEO_MULTIVIEW_H__ */
|
||||
191
spa/include/spa/video/raw.h
Normal file
191
spa/include/spa/video/raw.h
Normal file
|
|
@ -0,0 +1,191 @@
|
|||
/* Simple Plugin API
|
||||
* Copyright (C) 2016 Wim Taymans <wim.taymans@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __SPA_VIDEO_RAW_H__
|
||||
#define __SPA_VIDEO_RAW_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct _SpaVideoRawInfo SpaVideoRawInfo;
|
||||
|
||||
#include <spa/props.h>
|
||||
#include <spa/video/chroma.h>
|
||||
#include <spa/video/color.h>
|
||||
#include <spa/video/multiview.h>
|
||||
|
||||
#include <endian.h>
|
||||
|
||||
#define SPA_VIDEO_MAX_PLANES 4
|
||||
#define SPA_VIDEO_MAX_COMPONENTS 4
|
||||
|
||||
typedef enum {
|
||||
SPA_VIDEO_FORMAT_UNKNOWN,
|
||||
SPA_VIDEO_FORMAT_ENCODED,
|
||||
SPA_VIDEO_FORMAT_I420,
|
||||
SPA_VIDEO_FORMAT_YV12,
|
||||
SPA_VIDEO_FORMAT_YUY2,
|
||||
SPA_VIDEO_FORMAT_UYVY,
|
||||
SPA_VIDEO_FORMAT_AYUV,
|
||||
SPA_VIDEO_FORMAT_RGBx,
|
||||
SPA_VIDEO_FORMAT_BGRx,
|
||||
SPA_VIDEO_FORMAT_xRGB,
|
||||
SPA_VIDEO_FORMAT_xBGR,
|
||||
SPA_VIDEO_FORMAT_RGBA,
|
||||
SPA_VIDEO_FORMAT_BGRA,
|
||||
SPA_VIDEO_FORMAT_ARGB,
|
||||
SPA_VIDEO_FORMAT_ABGR,
|
||||
SPA_VIDEO_FORMAT_RGB,
|
||||
SPA_VIDEO_FORMAT_BGR,
|
||||
SPA_VIDEO_FORMAT_Y41B,
|
||||
SPA_VIDEO_FORMAT_Y42B,
|
||||
SPA_VIDEO_FORMAT_YVYU,
|
||||
SPA_VIDEO_FORMAT_Y444,
|
||||
SPA_VIDEO_FORMAT_v210,
|
||||
SPA_VIDEO_FORMAT_v216,
|
||||
SPA_VIDEO_FORMAT_NV12,
|
||||
SPA_VIDEO_FORMAT_NV21,
|
||||
SPA_VIDEO_FORMAT_GRAY8,
|
||||
SPA_VIDEO_FORMAT_GRAY16_BE,
|
||||
SPA_VIDEO_FORMAT_GRAY16_LE,
|
||||
SPA_VIDEO_FORMAT_v308,
|
||||
SPA_VIDEO_FORMAT_RGB16,
|
||||
SPA_VIDEO_FORMAT_BGR16,
|
||||
SPA_VIDEO_FORMAT_RGB15,
|
||||
SPA_VIDEO_FORMAT_BGR15,
|
||||
SPA_VIDEO_FORMAT_UYVP,
|
||||
SPA_VIDEO_FORMAT_A420,
|
||||
SPA_VIDEO_FORMAT_RGB8P,
|
||||
SPA_VIDEO_FORMAT_YUV9,
|
||||
SPA_VIDEO_FORMAT_YVU9,
|
||||
SPA_VIDEO_FORMAT_IYU1,
|
||||
SPA_VIDEO_FORMAT_ARGB64,
|
||||
SPA_VIDEO_FORMAT_AYUV64,
|
||||
SPA_VIDEO_FORMAT_r210,
|
||||
SPA_VIDEO_FORMAT_I420_10BE,
|
||||
SPA_VIDEO_FORMAT_I420_10LE,
|
||||
SPA_VIDEO_FORMAT_I422_10BE,
|
||||
SPA_VIDEO_FORMAT_I422_10LE,
|
||||
SPA_VIDEO_FORMAT_Y444_10BE,
|
||||
SPA_VIDEO_FORMAT_Y444_10LE,
|
||||
SPA_VIDEO_FORMAT_GBR,
|
||||
SPA_VIDEO_FORMAT_GBR_10BE,
|
||||
SPA_VIDEO_FORMAT_GBR_10LE,
|
||||
SPA_VIDEO_FORMAT_NV16,
|
||||
SPA_VIDEO_FORMAT_NV24,
|
||||
SPA_VIDEO_FORMAT_NV12_64Z32,
|
||||
SPA_VIDEO_FORMAT_A420_10BE,
|
||||
SPA_VIDEO_FORMAT_A420_10LE,
|
||||
SPA_VIDEO_FORMAT_A422_10BE,
|
||||
SPA_VIDEO_FORMAT_A422_10LE,
|
||||
SPA_VIDEO_FORMAT_A444_10BE,
|
||||
SPA_VIDEO_FORMAT_A444_10LE,
|
||||
SPA_VIDEO_FORMAT_NV61,
|
||||
SPA_VIDEO_FORMAT_P010_10BE,
|
||||
SPA_VIDEO_FORMAT_P010_10LE,
|
||||
SPA_VIDEO_FORMAT_IYU2,
|
||||
} SpaVideoFormat;
|
||||
|
||||
|
||||
/**
|
||||
* SpaVideoFlags:
|
||||
* @SPA_VIDEO_FLAG_NONE: no flags
|
||||
* @SPA_VIDEO_FLAG_VARIABLE_FPS: a variable fps is selected, fps_n and fps_d
|
||||
* denote the maximum fps of the video
|
||||
* @SPA_VIDEO_FLAG_PREMULTIPLIED_ALPHA: Each color has been scaled by the alpha
|
||||
* value.
|
||||
*
|
||||
* Extra video flags
|
||||
*/
|
||||
typedef enum {
|
||||
SPA_VIDEO_FLAG_NONE = 0,
|
||||
SPA_VIDEO_FLAG_VARIABLE_FPS = (1 << 0),
|
||||
SPA_VIDEO_FLAG_PREMULTIPLIED_ALPHA = (1 << 1)
|
||||
} SpaVideoFlags;
|
||||
|
||||
/**
|
||||
* SpaVideoInterlaceMode:
|
||||
* @SPA_VIDEO_INTERLACE_MODE_PROGRESSIVE: all frames are progressive
|
||||
* @SPA_VIDEO_INTERLACE_MODE_INTERLEAVED: 2 fields are interleaved in one video
|
||||
* frame. Extra buffer flags describe the field order.
|
||||
* @SPA_VIDEO_INTERLACE_MODE_MIXED: frames contains both interlaced and
|
||||
* progressive video, the buffer flags describe the frame and fields.
|
||||
* @SPA_VIDEO_INTERLACE_MODE_FIELDS: 2 fields are stored in one buffer, use the
|
||||
* frame ID to get access to the required field. For multiview (the
|
||||
* 'views' property > 1) the fields of view N can be found at frame ID
|
||||
* (N * 2) and (N * 2) + 1.
|
||||
* Each field has only half the amount of lines as noted in the
|
||||
* height property. This mode requires multiple SpaVideoMeta metadata
|
||||
* to describe the fields.
|
||||
*
|
||||
* The possible values of the #SpaVideoInterlaceMode describing the interlace
|
||||
* mode of the stream.
|
||||
*/
|
||||
typedef enum {
|
||||
SPA_VIDEO_INTERLACE_MODE_PROGRESSIVE = 0,
|
||||
SPA_VIDEO_INTERLACE_MODE_INTERLEAVED,
|
||||
SPA_VIDEO_INTERLACE_MODE_MIXED,
|
||||
SPA_VIDEO_INTERLACE_MODE_FIELDS
|
||||
} SpaVideoInterlaceMode;
|
||||
|
||||
/**
|
||||
* SpaVideoRawInfo:
|
||||
* @format: the format
|
||||
* @width: the width of the video
|
||||
* @height: the height of the video
|
||||
* @framerate: the framerate of the video 0/1 means variable rate
|
||||
* @max_framerate: the maximum framerate of the video. This is only valid when
|
||||
* @framerate is 0/1
|
||||
* @views: the number of views in this video
|
||||
* @interlace_mode: the interlace mode
|
||||
* @pixel_aspect_ratio: The pixel aspect ratio
|
||||
* @multiview_mode: multiview mode
|
||||
* @multiview_flags: multiview flags
|
||||
* @chroma_site: the chroma siting
|
||||
* @color_range: the color range. This is the valid range for the samples.
|
||||
* It is used to convert the samples to Y'PbPr values.
|
||||
* @color_matrix: the color matrix. Used to convert between Y'PbPr and
|
||||
* non-linear RGB (R'G'B')
|
||||
* @transfer_function: the transfer function. used to convert between R'G'B' and RGB
|
||||
* @color_primaries: color primaries. used to convert between R'G'B' and CIE XYZ
|
||||
*/
|
||||
struct _SpaVideoRawInfo {
|
||||
SpaVideoFormat format;
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
SpaFraction framerate;
|
||||
SpaFraction max_framerate;
|
||||
unsigned int views;
|
||||
SpaVideoInterlaceMode interlace_mode;
|
||||
SpaFraction pixel_aspect_ratio;
|
||||
SpaVideoMultiviewMode multiview_mode;
|
||||
SpaVideoMultiviewFlags multiview_flags;
|
||||
SpaVideoChromaSite chroma_site;
|
||||
SpaVideoColorRange color_range;
|
||||
SpaVideoColorMatrix color_matrix;
|
||||
SpaVideoTransferFunction transfer_function;
|
||||
SpaVideoColorPrimaries color_primaries;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* __SPA_VIDEO_RAW_H__ */
|
||||
|
|
@ -23,6 +23,7 @@
|
|||
#include <string.h>
|
||||
|
||||
#include <spa/audio/raw.h>
|
||||
#include <spa/audio/format.h>
|
||||
|
||||
static const uint32_t format_values[] = {
|
||||
SPA_AUDIO_FORMAT_S8,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
spalib_sources = ['audio-raw.c',
|
||||
'props.c',
|
||||
'ringbuffer.c']
|
||||
'ringbuffer.c',
|
||||
'video-raw.c']
|
||||
|
||||
spalib = shared_library('spa-lib',
|
||||
spalib_sources,
|
||||
|
|
|
|||
530
spa/lib/video-raw.c
Normal file
530
spa/lib/video-raw.c
Normal file
|
|
@ -0,0 +1,530 @@
|
|||
/* Simple Plugin API
|
||||
* Copyright (C) 2016 Wim Taymans <wim.taymans@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <spa/video/raw.h>
|
||||
#include <spa/video/format.h>
|
||||
|
||||
static const SpaVideoRawInfo default_info = {
|
||||
SPA_VIDEO_FORMAT_UNKNOWN,
|
||||
320,
|
||||
240,
|
||||
{ 0, 1 },
|
||||
{ 0, 1 },
|
||||
1,
|
||||
SPA_VIDEO_INTERLACE_MODE_PROGRESSIVE,
|
||||
{ 1, 1},
|
||||
SPA_VIDEO_MULTIVIEW_MODE_MONO,
|
||||
SPA_VIDEO_MULTIVIEW_FLAGS_NONE,
|
||||
SPA_VIDEO_CHROMA_SITE_UNKNOWN,
|
||||
SPA_VIDEO_COLOR_RANGE_UNKNOWN,
|
||||
SPA_VIDEO_COLOR_MATRIX_UNKNOWN,
|
||||
SPA_VIDEO_TRANSFER_UNKNOWN,
|
||||
SPA_VIDEO_COLOR_PRIMARIES_UNKNOWN
|
||||
};
|
||||
|
||||
static const uint32_t format_values[] = {
|
||||
SPA_VIDEO_FORMAT_UNKNOWN,
|
||||
SPA_VIDEO_FORMAT_ENCODED,
|
||||
SPA_VIDEO_FORMAT_I420,
|
||||
SPA_VIDEO_FORMAT_YV12,
|
||||
SPA_VIDEO_FORMAT_YUY2,
|
||||
SPA_VIDEO_FORMAT_UYVY,
|
||||
SPA_VIDEO_FORMAT_AYUV,
|
||||
SPA_VIDEO_FORMAT_RGBx,
|
||||
SPA_VIDEO_FORMAT_BGRx,
|
||||
SPA_VIDEO_FORMAT_xRGB,
|
||||
SPA_VIDEO_FORMAT_xBGR,
|
||||
SPA_VIDEO_FORMAT_RGBA,
|
||||
SPA_VIDEO_FORMAT_BGRA,
|
||||
SPA_VIDEO_FORMAT_ARGB,
|
||||
SPA_VIDEO_FORMAT_ABGR,
|
||||
SPA_VIDEO_FORMAT_RGB,
|
||||
SPA_VIDEO_FORMAT_BGR,
|
||||
SPA_VIDEO_FORMAT_Y41B,
|
||||
SPA_VIDEO_FORMAT_Y42B,
|
||||
SPA_VIDEO_FORMAT_YVYU,
|
||||
SPA_VIDEO_FORMAT_Y444,
|
||||
SPA_VIDEO_FORMAT_v210,
|
||||
SPA_VIDEO_FORMAT_v216,
|
||||
SPA_VIDEO_FORMAT_NV12,
|
||||
SPA_VIDEO_FORMAT_NV21,
|
||||
SPA_VIDEO_FORMAT_GRAY8,
|
||||
SPA_VIDEO_FORMAT_GRAY16_BE,
|
||||
SPA_VIDEO_FORMAT_GRAY16_LE,
|
||||
SPA_VIDEO_FORMAT_v308,
|
||||
SPA_VIDEO_FORMAT_RGB16,
|
||||
SPA_VIDEO_FORMAT_BGR16,
|
||||
SPA_VIDEO_FORMAT_RGB15,
|
||||
SPA_VIDEO_FORMAT_BGR15,
|
||||
SPA_VIDEO_FORMAT_UYVP,
|
||||
SPA_VIDEO_FORMAT_A420,
|
||||
SPA_VIDEO_FORMAT_RGB8P,
|
||||
SPA_VIDEO_FORMAT_YUV9,
|
||||
SPA_VIDEO_FORMAT_YVU9,
|
||||
SPA_VIDEO_FORMAT_IYU1,
|
||||
SPA_VIDEO_FORMAT_ARGB64,
|
||||
SPA_VIDEO_FORMAT_AYUV64,
|
||||
SPA_VIDEO_FORMAT_r210,
|
||||
SPA_VIDEO_FORMAT_I420_10BE,
|
||||
SPA_VIDEO_FORMAT_I420_10LE,
|
||||
SPA_VIDEO_FORMAT_I422_10BE,
|
||||
SPA_VIDEO_FORMAT_I422_10LE,
|
||||
SPA_VIDEO_FORMAT_Y444_10BE,
|
||||
SPA_VIDEO_FORMAT_Y444_10LE,
|
||||
SPA_VIDEO_FORMAT_GBR,
|
||||
SPA_VIDEO_FORMAT_GBR_10BE,
|
||||
SPA_VIDEO_FORMAT_GBR_10LE,
|
||||
SPA_VIDEO_FORMAT_NV16,
|
||||
SPA_VIDEO_FORMAT_NV24,
|
||||
SPA_VIDEO_FORMAT_NV12_64Z32,
|
||||
SPA_VIDEO_FORMAT_A420_10BE,
|
||||
SPA_VIDEO_FORMAT_A420_10LE,
|
||||
SPA_VIDEO_FORMAT_A422_10BE,
|
||||
SPA_VIDEO_FORMAT_A422_10LE,
|
||||
SPA_VIDEO_FORMAT_A444_10BE,
|
||||
SPA_VIDEO_FORMAT_A444_10LE,
|
||||
SPA_VIDEO_FORMAT_NV61,
|
||||
SPA_VIDEO_FORMAT_P010_10BE,
|
||||
SPA_VIDEO_FORMAT_P010_10LE,
|
||||
SPA_VIDEO_FORMAT_IYU2,
|
||||
};
|
||||
|
||||
static const SpaPropRangeInfo format_range[] = {
|
||||
{ "UNKNOWN", "UNKNOWN,", sizeof (uint32_t), &format_values[0] },
|
||||
{ "ENCODED,", "ENCODED", sizeof (uint32_t), &format_values[1] },
|
||||
{ "S16LE", "S16LE", sizeof (uint32_t), &format_values[2] },
|
||||
{ "S16BE", "S16BE", sizeof (uint32_t), &format_values[3] },
|
||||
{ "U16LE", "U16LE", sizeof (uint32_t), &format_values[4] },
|
||||
{ "U16BE", "U16BE", sizeof (uint32_t), &format_values[5] },
|
||||
{ "S24_32LE", "S24_32LE", sizeof (uint32_t), &format_values[6] },
|
||||
{ "S24_32BE", "S24_32BE", sizeof (uint32_t), &format_values[7] },
|
||||
{ "U24_32LE", "U24_32LE", sizeof (uint32_t), &format_values[8] },
|
||||
{ "U24_32BE", "U24_32BE", sizeof (uint32_t), &format_values[9] },
|
||||
{ "S32LE", "S32LE", sizeof (uint32_t), &format_values[10] },
|
||||
{ "S32BE", "S32BE", sizeof (uint32_t), &format_values[11] },
|
||||
{ "U32LE", "U32LE", sizeof (uint32_t), &format_values[12] },
|
||||
{ "U32BE", "U32BE", sizeof (uint32_t), &format_values[13] },
|
||||
{ "S24LE", "S24LE", sizeof (uint32_t), &format_values[14] },
|
||||
{ "S24BE", "S24BE", sizeof (uint32_t), &format_values[15] },
|
||||
{ "U24LE", "U24LE", sizeof (uint32_t), &format_values[16] },
|
||||
{ "U24BE", "U24BE", sizeof (uint32_t), &format_values[17] },
|
||||
{ "S20LE", "S20LE", sizeof (uint32_t), &format_values[18] },
|
||||
{ "S20BE", "S20BE", sizeof (uint32_t), &format_values[19] },
|
||||
{ "U20LE", "U20LE", sizeof (uint32_t), &format_values[20] },
|
||||
{ "U20BE", "U20BE", sizeof (uint32_t), &format_values[21] },
|
||||
{ "S18LE", "S18LE", sizeof (uint32_t), &format_values[22] },
|
||||
{ "S18BE", "S18BE", sizeof (uint32_t), &format_values[23] },
|
||||
{ "U18LE", "U18LE", sizeof (uint32_t), &format_values[24] },
|
||||
{ "U18BE", "U18BE", sizeof (uint32_t), &format_values[25] },
|
||||
{ "F32LE", "F32LE", sizeof (uint32_t), &format_values[26] },
|
||||
{ "F32BE", "F32BE", sizeof (uint32_t), &format_values[27] },
|
||||
{ "F64LE", "F64LE", sizeof (uint32_t), &format_values[28] },
|
||||
{ "F64BE", "F64BE", sizeof (uint32_t), &format_values[29] },
|
||||
};
|
||||
|
||||
static const uint32_t interlace_modes[] = {
|
||||
SPA_VIDEO_INTERLACE_MODE_PROGRESSIVE,
|
||||
SPA_VIDEO_INTERLACE_MODE_INTERLEAVED,
|
||||
SPA_VIDEO_INTERLACE_MODE_MIXED,
|
||||
SPA_VIDEO_INTERLACE_MODE_FIELDS
|
||||
};
|
||||
|
||||
static const SpaPropRangeInfo interlace_mode_range[] = {
|
||||
{ "progressive", "Progressive video", sizeof (uint32_t), &interlace_modes[0] },
|
||||
{ "interleaved", "Interleaved video", sizeof (uint32_t), &interlace_modes[1] },
|
||||
{ "mixed", "Mixed interlaced video", sizeof (uint32_t), &interlace_modes[2] },
|
||||
{ "fields", "Fields interlaced video", sizeof (uint32_t), &interlace_modes[3] },
|
||||
};
|
||||
|
||||
|
||||
static const uint32_t multiview_modes[] = {
|
||||
SPA_VIDEO_MULTIVIEW_MODE_NONE,
|
||||
SPA_VIDEO_MULTIVIEW_MODE_MONO,
|
||||
SPA_VIDEO_MULTIVIEW_MODE_LEFT,
|
||||
SPA_VIDEO_MULTIVIEW_MODE_RIGHT,
|
||||
SPA_VIDEO_MULTIVIEW_MODE_SIDE_BY_SIDE,
|
||||
SPA_VIDEO_MULTIVIEW_MODE_SIDE_BY_SIDE_QUINCUNX,
|
||||
SPA_VIDEO_MULTIVIEW_MODE_COLUMN_INTERLEAVED,
|
||||
SPA_VIDEO_MULTIVIEW_MODE_ROW_INTERLEAVED,
|
||||
SPA_VIDEO_MULTIVIEW_MODE_TOP_BOTTOM,
|
||||
SPA_VIDEO_MULTIVIEW_MODE_CHECKERBOARD,
|
||||
SPA_VIDEO_MULTIVIEW_MODE_FRAME_BY_FRAME,
|
||||
SPA_VIDEO_MULTIVIEW_MODE_MULTIVIEW_FRAME_BY_FRAME,
|
||||
SPA_VIDEO_MULTIVIEW_MODE_SEPARATED
|
||||
};
|
||||
|
||||
static const SpaPropRangeInfo multiview_mode_range[] = {
|
||||
{ "none", "None", sizeof (uint32_t), &multiview_modes[0] },
|
||||
{ "mono", "Mono", sizeof (uint32_t), &multiview_modes[1] },
|
||||
{ "left", "Left", sizeof (uint32_t), &multiview_modes[2] },
|
||||
{ "right", "Right", sizeof (uint32_t), &multiview_modes[3] },
|
||||
{ "side-by-side", "Side by side", sizeof (uint32_t), &multiview_modes[4] },
|
||||
{ "side-by-side-quincunx", "Side by side Cuincunx", sizeof (uint32_t), &multiview_modes[5] },
|
||||
{ "column-interleaved", "Column Interleaved", sizeof (uint32_t), &multiview_modes[6] },
|
||||
{ "row-interleaved", "Row Interleaved", sizeof (uint32_t), &multiview_modes[7] },
|
||||
{ "top-bottom", "Top Bottom", sizeof (uint32_t), &multiview_modes[8] },
|
||||
{ "checkerboard", "Checkerboard", sizeof (uint32_t), &multiview_modes[9] },
|
||||
{ "frame-by-frame", "Frame by frame", sizeof (uint32_t), &multiview_modes[10] },
|
||||
{ "multiview-frame-by-frame", "Multiview Frame by frame", sizeof (uint32_t), &multiview_modes[11] },
|
||||
{ "separated", "Separated", sizeof (uint32_t), &multiview_modes[12] },
|
||||
};
|
||||
|
||||
static const uint32_t multiview_flags[] = {
|
||||
SPA_VIDEO_MULTIVIEW_FLAGS_NONE,
|
||||
SPA_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST,
|
||||
SPA_VIDEO_MULTIVIEW_FLAGS_LEFT_FLIPPED,
|
||||
SPA_VIDEO_MULTIVIEW_FLAGS_LEFT_FLOPPED,
|
||||
SPA_VIDEO_MULTIVIEW_FLAGS_RIGHT_FLIPPED,
|
||||
SPA_VIDEO_MULTIVIEW_FLAGS_RIGHT_FLOPPED,
|
||||
SPA_VIDEO_MULTIVIEW_FLAGS_HALF_ASPECT,
|
||||
SPA_VIDEO_MULTIVIEW_FLAGS_MIXED_MONO,
|
||||
};
|
||||
|
||||
static const SpaPropRangeInfo multiview_flags_range[] = {
|
||||
{ "none", "None", sizeof (uint32_t), &multiview_flags[0] },
|
||||
{ "right-view-first", "Right view first", sizeof (uint32_t), &multiview_flags[1] },
|
||||
{ "left-flipped", "Left flipped", sizeof (uint32_t), &multiview_flags[2] },
|
||||
{ "left-flopped", "Left flopped", sizeof (uint32_t), &multiview_flags[3] },
|
||||
{ "right-flipped", "Right flipped", sizeof (uint32_t), &multiview_flags[4] },
|
||||
{ "right-flopped", "Right flopped", sizeof (uint32_t), &multiview_flags[5] },
|
||||
{ "half-aspect", "Half aspect", sizeof (uint32_t), &multiview_flags[6] },
|
||||
{ "mixed-mono", "Mixed mono", sizeof (uint32_t), &multiview_flags[7] },
|
||||
};
|
||||
|
||||
static const uint32_t chroma_sites[] = {
|
||||
SPA_VIDEO_CHROMA_SITE_UNKNOWN,
|
||||
SPA_VIDEO_CHROMA_SITE_NONE,
|
||||
SPA_VIDEO_CHROMA_SITE_H_COSITED,
|
||||
SPA_VIDEO_CHROMA_SITE_V_COSITED,
|
||||
SPA_VIDEO_CHROMA_SITE_ALT_LINE,
|
||||
};
|
||||
|
||||
static const SpaPropRangeInfo chroma_site_range[] = {
|
||||
{ "unknown", "Unknown", sizeof (uint32_t), &chroma_sites[0] },
|
||||
{ "none", "None", sizeof (uint32_t), &chroma_sites[1] },
|
||||
{ "h-cosited", "H-cosited", sizeof (uint32_t), &chroma_sites[2] },
|
||||
{ "v-cosited", "V-cosited", sizeof (uint32_t), &chroma_sites[3] },
|
||||
{ "alt-line", "Alt line", sizeof (uint32_t), &chroma_sites[4] }
|
||||
};
|
||||
|
||||
static const uint32_t color_ranges[] = {
|
||||
SPA_VIDEO_COLOR_RANGE_UNKNOWN,
|
||||
SPA_VIDEO_COLOR_RANGE_0_255,
|
||||
SPA_VIDEO_COLOR_RANGE_16_235
|
||||
};
|
||||
|
||||
static const SpaPropRangeInfo color_range_range[] = {
|
||||
{ "unknown", "Unknown color range", sizeof (uint32_t), &color_ranges[0] },
|
||||
{ "0_255", "0-255", sizeof (uint32_t), &color_ranges[1] },
|
||||
{ "16_235", "16-235", sizeof (uint32_t), &color_ranges[2] },
|
||||
};
|
||||
|
||||
static const uint32_t color_matrices[] = {
|
||||
SPA_VIDEO_COLOR_MATRIX_UNKNOWN,
|
||||
SPA_VIDEO_COLOR_MATRIX_RGB,
|
||||
SPA_VIDEO_COLOR_MATRIX_FCC,
|
||||
SPA_VIDEO_COLOR_MATRIX_BT709,
|
||||
SPA_VIDEO_COLOR_MATRIX_BT601,
|
||||
SPA_VIDEO_COLOR_MATRIX_SMPTE240M,
|
||||
SPA_VIDEO_COLOR_MATRIX_BT2020
|
||||
};
|
||||
|
||||
static const SpaPropRangeInfo color_matrix_range[] = {
|
||||
{ "unknown", "Unknown color matrix", sizeof (uint32_t), &color_matrices[0] },
|
||||
{ "rgb", "identity matrix", sizeof (uint32_t), &color_matrices[1] },
|
||||
{ "fcc", "FCC color matrix", sizeof (uint32_t), &color_matrices[2] },
|
||||
{ "bt709", "ITU-R BT.709 color matrix", sizeof (uint32_t), &color_matrices[3] },
|
||||
{ "bt601", "ITU-R BT.601 color matrix", sizeof (uint32_t), &color_matrices[4] },
|
||||
{ "smpte240m", "SMPTE 240M color matrix", sizeof (uint32_t), &color_matrices[5] },
|
||||
{ "bt2020", "ITU-R BT.2020 color matrix", sizeof (uint32_t), &color_matrices[6] },
|
||||
};
|
||||
|
||||
static const uint32_t transfer_functions[] = {
|
||||
SPA_VIDEO_TRANSFER_UNKNOWN,
|
||||
SPA_VIDEO_TRANSFER_GAMMA10,
|
||||
SPA_VIDEO_TRANSFER_GAMMA18,
|
||||
SPA_VIDEO_TRANSFER_GAMMA20,
|
||||
SPA_VIDEO_TRANSFER_GAMMA22,
|
||||
SPA_VIDEO_TRANSFER_BT709,
|
||||
SPA_VIDEO_TRANSFER_SMPTE240M,
|
||||
SPA_VIDEO_TRANSFER_SRGB,
|
||||
SPA_VIDEO_TRANSFER_GAMMA28,
|
||||
SPA_VIDEO_TRANSFER_LOG100,
|
||||
SPA_VIDEO_TRANSFER_LOG316,
|
||||
SPA_VIDEO_TRANSFER_BT2020_12,
|
||||
SPA_VIDEO_TRANSFER_ADOBERGB
|
||||
};
|
||||
|
||||
static const SpaPropRangeInfo transfer_function_range[] = {
|
||||
{ "unknown", "Unknown transfer function", sizeof (uint32_t), &transfer_functions[0] },
|
||||
{ "gamma10", "linear RGB, gamma 1.0 curve", sizeof (uint32_t), &transfer_functions[1] },
|
||||
{ "gamma18", "gamma 1.8 curve", sizeof (uint32_t), &transfer_functions[2] },
|
||||
{ "gamma20", "gamma 2.0 curve", sizeof (uint32_t), &transfer_functions[3] },
|
||||
{ "gamma22", "gamma 2.2 curve", sizeof (uint32_t), &transfer_functions[4] },
|
||||
{ "bt709", "Gamma 2.2 curve with a linear segment", sizeof (uint32_t), &transfer_functions[5] },
|
||||
{ "smpte240m", "Gamma 2.2 curve with a linear segment", sizeof (uint32_t), &transfer_functions[6] },
|
||||
{ "srgb", "Gamma 2.4 curve with a linear segment", sizeof (uint32_t), &transfer_functions[7] },
|
||||
{ "gamma28", "Gamma 2.8 curve", sizeof (uint32_t), &transfer_functions[8] },
|
||||
{ "log100", "Logarithmic transfer characteristic 100:1 range", sizeof (uint32_t), &transfer_functions[9] },
|
||||
{ "log316", "Logarithmic transfer characteristic 316.22777:1 range", sizeof (uint32_t), &transfer_functions[10] },
|
||||
{ "bt2020_12", "Gamma 2.2 curve with a linear segment", sizeof (uint32_t), &transfer_functions[11] },
|
||||
{ "adobergb", "Gamma 2.19921875", sizeof (uint32_t), &transfer_functions[12] },
|
||||
};
|
||||
|
||||
static const uint32_t color_primaries[] = {
|
||||
SPA_VIDEO_COLOR_PRIMARIES_UNKNOWN,
|
||||
SPA_VIDEO_COLOR_PRIMARIES_BT709,
|
||||
SPA_VIDEO_COLOR_PRIMARIES_BT470M,
|
||||
SPA_VIDEO_COLOR_PRIMARIES_BT470BG,
|
||||
SPA_VIDEO_COLOR_PRIMARIES_SMPTE170M,
|
||||
SPA_VIDEO_COLOR_PRIMARIES_SMPTE240M,
|
||||
SPA_VIDEO_COLOR_PRIMARIES_FILM,
|
||||
SPA_VIDEO_COLOR_PRIMARIES_BT2020,
|
||||
SPA_VIDEO_COLOR_PRIMARIES_ADOBERGB
|
||||
};
|
||||
|
||||
static const SpaPropRangeInfo color_primaries_range[] = {
|
||||
{ "unknown", "Unknown color primaries", sizeof (uint32_t), &color_primaries[0] },
|
||||
{ "bt709", "BT709 primaries", sizeof (uint32_t), &color_primaries[1] },
|
||||
{ "bt470M", "BT470M primaries", sizeof (uint32_t), &color_primaries[2] },
|
||||
{ "bt470BG", "BT470BG primaries", sizeof (uint32_t), &color_primaries[3] },
|
||||
{ "smpte170m", "SMPTE170M primaries", sizeof (uint32_t), &color_primaries[4] },
|
||||
{ "smpte240m", "SMPTE240M primaries", sizeof (uint32_t), &color_primaries[5] },
|
||||
{ "film", "Generic film primaries", sizeof (uint32_t), &color_primaries[6] },
|
||||
{ "bt2020", "BT2020 primaries", sizeof (uint32_t), &color_primaries[7] },
|
||||
{ "adobergb", "Adobe RGB primaries", sizeof (uint32_t), &color_primaries[8] },
|
||||
};
|
||||
|
||||
static const uint32_t min_uint32 = 1;
|
||||
static const uint32_t max_uint32 = UINT32_MAX;
|
||||
|
||||
static const SpaPropRangeInfo uint32_range[] = {
|
||||
{ "min", "Minimum value", sizeof (uint32_t), &min_uint32 },
|
||||
{ "max", "Maximum value", sizeof (uint32_t), &max_uint32 },
|
||||
};
|
||||
|
||||
static const SpaFraction min_framerate = { 0, 1 };
|
||||
static const SpaFraction max_framerate = { UINT32_MAX, 1 };
|
||||
|
||||
static const SpaPropRangeInfo framerate_range[] = {
|
||||
{ "min", "Minimum value", sizeof (SpaFraction), &min_framerate },
|
||||
{ "max", "Maximum value", sizeof (SpaFraction), &max_framerate },
|
||||
};
|
||||
|
||||
static const SpaPropInfo raw_format_prop_info[] =
|
||||
{
|
||||
{ SPA_PROP_ID_VIDEO_FORMAT, "format", "The media format",
|
||||
SPA_PROP_FLAG_READWRITE,
|
||||
SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
|
||||
sizeof (uint32_t), &default_info.format,
|
||||
SPA_PROP_RANGE_TYPE_ENUM, SPA_N_ELEMENTS (format_range), format_range,
|
||||
NULL,
|
||||
offsetof (SpaVideoRawFormat, info.format),
|
||||
offsetof (SpaVideoRawFormat, unset_mask), 1 << 0,
|
||||
NULL },
|
||||
{ SPA_PROP_ID_VIDEO_WIDTH, "width", "Video width",
|
||||
SPA_PROP_FLAG_READWRITE,
|
||||
SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
|
||||
sizeof (uint32_t), &default_info.width,
|
||||
SPA_PROP_RANGE_TYPE_MIN_MAX, 2, uint32_range,
|
||||
NULL,
|
||||
offsetof (SpaVideoRawFormat, info.width),
|
||||
offsetof (SpaVideoRawFormat, unset_mask), 1 << 1,
|
||||
NULL },
|
||||
{ SPA_PROP_ID_VIDEO_HEIGHT, "height", "Video height",
|
||||
SPA_PROP_FLAG_READWRITE,
|
||||
SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
|
||||
sizeof (uint32_t), &default_info.height,
|
||||
SPA_PROP_RANGE_TYPE_MIN_MAX, 2, uint32_range,
|
||||
NULL,
|
||||
offsetof (SpaVideoRawFormat, info.height),
|
||||
offsetof (SpaVideoRawFormat, unset_mask), 1 << 2,
|
||||
NULL },
|
||||
{ SPA_PROP_ID_VIDEO_FRAMERATE, "framerate", "Video framerate",
|
||||
SPA_PROP_FLAG_READWRITE,
|
||||
SPA_PROP_TYPE_FRACTION, sizeof (SpaFraction),
|
||||
sizeof (SpaFraction), &default_info.framerate,
|
||||
SPA_PROP_RANGE_TYPE_MIN_MAX, 2, framerate_range,
|
||||
NULL,
|
||||
offsetof (SpaVideoRawFormat, info.framerate),
|
||||
offsetof (SpaVideoRawFormat, unset_mask), 1 << 3,
|
||||
NULL },
|
||||
{ SPA_PROP_ID_VIDEO_MAX_FRAMERATE, "max-framerate", "Video max framerate",
|
||||
SPA_PROP_FLAG_READWRITE,
|
||||
SPA_PROP_TYPE_FRACTION, sizeof (SpaFraction),
|
||||
sizeof (SpaFraction), &default_info.max_framerate,
|
||||
SPA_PROP_RANGE_TYPE_MIN_MAX, 2, framerate_range,
|
||||
NULL,
|
||||
offsetof (SpaVideoRawFormat, info.max_framerate),
|
||||
offsetof (SpaVideoRawFormat, unset_mask), 1 << 4,
|
||||
NULL },
|
||||
{ SPA_PROP_ID_VIDEO_VIEWS, "views", "Video number of views",
|
||||
SPA_PROP_FLAG_READWRITE,
|
||||
SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
|
||||
sizeof (uint32_t), &default_info.views,
|
||||
SPA_PROP_RANGE_TYPE_MIN_MAX, 2, uint32_range,
|
||||
NULL,
|
||||
offsetof (SpaVideoRawFormat, info.views),
|
||||
offsetof (SpaVideoRawFormat, unset_mask), 1 << 5,
|
||||
NULL },
|
||||
{ SPA_PROP_ID_VIDEO_INTERLACE_MODE, "interlace-mode", "Interlace mode",
|
||||
SPA_PROP_FLAG_READWRITE,
|
||||
SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
|
||||
sizeof (uint32_t), &default_info.interlace_mode,
|
||||
SPA_PROP_RANGE_TYPE_ENUM, SPA_N_ELEMENTS (interlace_mode_range), interlace_mode_range,
|
||||
NULL,
|
||||
offsetof (SpaVideoRawFormat, info.interlace_mode),
|
||||
offsetof (SpaVideoRawFormat, unset_mask), 1 << 6,
|
||||
NULL },
|
||||
{ SPA_PROP_ID_VIDEO_PIXEL_ASPECT_RATIO, "pixel-aspect-ratio", "Video pixel aspect ratio",
|
||||
SPA_PROP_FLAG_READWRITE,
|
||||
SPA_PROP_TYPE_FRACTION, sizeof (SpaFraction),
|
||||
sizeof (SpaFraction), &default_info.pixel_aspect_ratio,
|
||||
SPA_PROP_RANGE_TYPE_MIN_MAX, 2, framerate_range,
|
||||
NULL,
|
||||
offsetof (SpaVideoRawFormat, info.pixel_aspect_ratio),
|
||||
offsetof (SpaVideoRawFormat, unset_mask), 1 << 7,
|
||||
NULL },
|
||||
{ SPA_PROP_ID_VIDEO_MULTIVIEW_MODE, "multiview-mode", "Multiview mode",
|
||||
SPA_PROP_FLAG_READWRITE,
|
||||
SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
|
||||
sizeof (uint32_t), &default_info.multiview_mode,
|
||||
SPA_PROP_RANGE_TYPE_ENUM, SPA_N_ELEMENTS (multiview_mode_range), multiview_mode_range,
|
||||
NULL,
|
||||
offsetof (SpaVideoRawFormat, info.multiview_mode),
|
||||
offsetof (SpaVideoRawFormat, unset_mask), 1 << 8,
|
||||
NULL },
|
||||
{ SPA_PROP_ID_VIDEO_MULTIVIEW_FLAGS, "multiview-flags", "Multiview flags",
|
||||
SPA_PROP_FLAG_READWRITE,
|
||||
SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
|
||||
sizeof (uint32_t), &default_info.multiview_flags,
|
||||
SPA_PROP_RANGE_TYPE_FLAGS, SPA_N_ELEMENTS (multiview_flags_range), multiview_flags_range,
|
||||
NULL,
|
||||
offsetof (SpaVideoRawFormat, info.multiview_flags),
|
||||
offsetof (SpaVideoRawFormat, unset_mask), 1 << 9,
|
||||
NULL },
|
||||
{ SPA_PROP_ID_VIDEO_CHROMA_SITE, "chroma-site", "Chroma site",
|
||||
SPA_PROP_FLAG_READWRITE,
|
||||
SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
|
||||
sizeof (uint32_t), &default_info.chroma_site,
|
||||
SPA_PROP_RANGE_TYPE_FLAGS, SPA_N_ELEMENTS (chroma_site_range), chroma_site_range,
|
||||
NULL,
|
||||
offsetof (SpaVideoRawFormat, info.chroma_site),
|
||||
offsetof (SpaVideoRawFormat, unset_mask), 1 << 10,
|
||||
NULL },
|
||||
{ SPA_PROP_ID_VIDEO_COLOR_RANGE, "color-range", "Color range",
|
||||
SPA_PROP_FLAG_READWRITE,
|
||||
SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
|
||||
sizeof (uint32_t), &default_info.color_range,
|
||||
SPA_PROP_RANGE_TYPE_ENUM, SPA_N_ELEMENTS (color_range_range), color_range_range,
|
||||
NULL,
|
||||
offsetof (SpaVideoRawFormat, info.color_range),
|
||||
offsetof (SpaVideoRawFormat, unset_mask), 1 << 11,
|
||||
NULL },
|
||||
{ SPA_PROP_ID_VIDEO_COLOR_MATRIX, "color-matrix", "Color matrix",
|
||||
SPA_PROP_FLAG_READWRITE,
|
||||
SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
|
||||
sizeof (uint32_t), &default_info.color_matrix,
|
||||
SPA_PROP_RANGE_TYPE_ENUM, SPA_N_ELEMENTS (color_matrix_range), color_matrix_range,
|
||||
NULL,
|
||||
offsetof (SpaVideoRawFormat, info.color_matrix),
|
||||
offsetof (SpaVideoRawFormat, unset_mask), 1 << 12,
|
||||
NULL },
|
||||
{ SPA_PROP_ID_VIDEO_TRANSFER_FUNCTION, "transfer-function", "Transfer function",
|
||||
SPA_PROP_FLAG_READWRITE,
|
||||
SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
|
||||
sizeof (uint32_t), &default_info.transfer_function,
|
||||
SPA_PROP_RANGE_TYPE_ENUM, SPA_N_ELEMENTS (transfer_function_range), transfer_function_range,
|
||||
NULL,
|
||||
offsetof (SpaVideoRawFormat, info.transfer_function),
|
||||
offsetof (SpaVideoRawFormat, unset_mask), 1 << 13,
|
||||
NULL },
|
||||
{ SPA_PROP_ID_VIDEO_COLOR_PRIMARIES, "color-primaries", "Color primaries",
|
||||
SPA_PROP_FLAG_READWRITE,
|
||||
SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
|
||||
sizeof (uint32_t), &default_info.color_primaries,
|
||||
SPA_PROP_RANGE_TYPE_ENUM, SPA_N_ELEMENTS (color_primaries_range), color_primaries_range,
|
||||
NULL,
|
||||
offsetof (SpaVideoRawFormat, info.color_primaries),
|
||||
offsetof (SpaVideoRawFormat, unset_mask), 1 << 14,
|
||||
NULL },
|
||||
{ SPA_PROP_ID_VIDEO_RAW_INFO, "info", "the SpaVideoRawInfo structure",
|
||||
SPA_PROP_FLAG_READWRITE,
|
||||
SPA_PROP_TYPE_STRUCT, sizeof (SpaVideoRawInfo),
|
||||
0, NULL,
|
||||
SPA_PROP_RANGE_TYPE_NONE, 0, NULL,
|
||||
NULL,
|
||||
offsetof (SpaVideoRawFormat, info),
|
||||
offsetof (SpaVideoRawFormat, unset_mask), ~0,
|
||||
NULL },
|
||||
};
|
||||
|
||||
SpaResult
|
||||
spa_video_raw_format_init (SpaVideoRawFormat *format)
|
||||
{
|
||||
format->format.media_type = SPA_MEDIA_TYPE_VIDEO;
|
||||
format->format.media_subtype = SPA_MEDIA_SUBTYPE_RAW;
|
||||
format->format.props.n_prop_info = SPA_N_ELEMENTS (raw_format_prop_info);
|
||||
format->format.props.prop_info = raw_format_prop_info;
|
||||
format->format.props.set_prop = spa_props_generic_set_prop;
|
||||
format->format.props.get_prop = spa_props_generic_get_prop;
|
||||
format->unset_mask = (1 << 0) | (1 << 2) | (1 << 3) | (1 << 4);
|
||||
format->info = default_info;
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
SpaResult
|
||||
spa_video_raw_format_parse (const SpaFormat *format,
|
||||
SpaVideoRawFormat *rawformat)
|
||||
{
|
||||
SpaPropValue value;
|
||||
const SpaProps *props;
|
||||
SpaResult res;
|
||||
|
||||
if ((void *)format == (void *)rawformat)
|
||||
return SPA_RESULT_OK;
|
||||
|
||||
if (format->media_type != SPA_MEDIA_TYPE_VIDEO ||
|
||||
format->media_subtype != SPA_MEDIA_SUBTYPE_RAW)
|
||||
return SPA_RESULT_INVALID_MEDIA_TYPE;
|
||||
|
||||
spa_video_raw_format_init (rawformat);
|
||||
|
||||
props = &format->props;
|
||||
if ((res = props->get_prop (props, SPA_PROP_ID_VIDEO_RAW_INFO, &value)) < 0)
|
||||
goto fallback;
|
||||
|
||||
if (value.type != SPA_PROP_TYPE_STRUCT || value.size != sizeof (SpaVideoRawInfo))
|
||||
goto fallback;
|
||||
|
||||
memcpy (&rawformat->info, value.value, sizeof (SpaVideoRawInfo));
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
|
||||
fallback:
|
||||
res = spa_props_copy (props, &rawformat->format.props);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
project('spa', 'c')
|
||||
|
||||
alsa_dep = dependency('alsa')
|
||||
v4l2_dep = dependency('libv4l2')
|
||||
dl_lib = find_library('dl', required : true)
|
||||
|
||||
inc = include_directories('include')
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
#include <pthread.h>
|
||||
|
||||
#include <spa/node.h>
|
||||
#include <spa/audio/raw.h>
|
||||
#include <spa/audio/format.h>
|
||||
|
||||
typedef struct _SpaALSASink SpaALSASink;
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#include <spa/node.h>
|
||||
#include <spa/audio/raw.h>
|
||||
#include <spa/audio/format.h>
|
||||
|
||||
#define MAX_PORTS 128
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
#include <string.h>
|
||||
|
||||
#include <spa/node.h>
|
||||
#include <spa/audio/raw.h>
|
||||
#include <spa/audio/format.h>
|
||||
|
||||
typedef struct _SpaAudioTestSrc SpaAudioTestSrc;
|
||||
|
||||
|
|
|
|||
|
|
@ -2,3 +2,4 @@ subdir('alsa')
|
|||
subdir('audiomixer')
|
||||
subdir('audiotestsrc')
|
||||
subdir('volume')
|
||||
subdir('v4l2')
|
||||
|
|
|
|||
9
spa/plugins/v4l2/meson.build
Normal file
9
spa/plugins/v4l2/meson.build
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
v4l2_sources = ['v4l2.c',
|
||||
'v4l2-source.c']
|
||||
|
||||
v4l2lib = shared_library('spa-v4l2',
|
||||
v4l2_sources,
|
||||
include_directories : inc,
|
||||
dependencies : v4l2_dep,
|
||||
link_with : spalib,
|
||||
install : true)
|
||||
528
spa/plugins/v4l2/v4l2-source.c
Normal file
528
spa/plugins/v4l2/v4l2-source.c
Normal file
|
|
@ -0,0 +1,528 @@
|
|||
/* Spa V4l2 Source
|
||||
* Copyright (C) 2016 Wim Taymans <wim.taymans@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <libv4l2.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include <spa/node.h>
|
||||
#include <spa/video/format.h>
|
||||
|
||||
typedef struct _SpaV4l2Source SpaV4l2Source;
|
||||
|
||||
static const char default_device[] = "/dev/video0";
|
||||
|
||||
typedef struct {
|
||||
SpaProps props;
|
||||
char device[64];
|
||||
char device_name[128];
|
||||
int device_fd;
|
||||
} SpaV4l2SourceProps;
|
||||
|
||||
static void
|
||||
reset_v4l2_source_props (SpaV4l2SourceProps *props)
|
||||
{
|
||||
strncpy (props->device, default_device, 64);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
int fd;
|
||||
pthread_t thread;
|
||||
bool running;
|
||||
} SpaV4l2State;
|
||||
|
||||
typedef struct _V4l2Buffer V4l2Buffer;
|
||||
|
||||
struct _V4l2Buffer {
|
||||
SpaBuffer buffer;
|
||||
SpaMeta meta[1];
|
||||
SpaMetaHeader header;
|
||||
SpaData data[1];
|
||||
V4l2Buffer *next;
|
||||
};
|
||||
|
||||
struct _SpaV4l2Source {
|
||||
SpaHandle handle;
|
||||
|
||||
SpaV4l2SourceProps tmp_props;
|
||||
SpaV4l2SourceProps props;
|
||||
|
||||
bool activated;
|
||||
|
||||
SpaEventCallback event_cb;
|
||||
void *user_data;
|
||||
|
||||
bool have_format;
|
||||
SpaVideoRawFormat query_format;
|
||||
SpaVideoRawFormat current_format;
|
||||
|
||||
SpaV4l2State state;
|
||||
|
||||
SpaPortInfo info;
|
||||
SpaPortStatus status;
|
||||
|
||||
V4l2Buffer buffer;
|
||||
};
|
||||
|
||||
#include "v4l2-utils.c"
|
||||
|
||||
static const uint32_t min_uint32 = 1;
|
||||
static const uint32_t max_uint32 = UINT32_MAX;
|
||||
|
||||
static const SpaPropRangeInfo uint32_range[] = {
|
||||
{ "min", "Minimum value", 4, &min_uint32 },
|
||||
{ "max", "Maximum value", 4, &max_uint32 },
|
||||
};
|
||||
|
||||
enum {
|
||||
PROP_ID_DEVICE,
|
||||
PROP_ID_DEVICE_NAME,
|
||||
PROP_ID_DEVICE_FD,
|
||||
PROP_ID_LAST,
|
||||
};
|
||||
|
||||
static const SpaPropInfo prop_info[] =
|
||||
{
|
||||
{ PROP_ID_DEVICE, "device", "V4l2 device location",
|
||||
SPA_PROP_FLAG_READWRITE,
|
||||
SPA_PROP_TYPE_STRING, 63,
|
||||
strlen (default_device)+1, default_device,
|
||||
SPA_PROP_RANGE_TYPE_NONE, 0, NULL,
|
||||
NULL,
|
||||
offsetof (SpaV4l2SourceProps, device),
|
||||
0, 0,
|
||||
NULL },
|
||||
{ PROP_ID_DEVICE_NAME, "device-name", "Human-readable name of the device",
|
||||
SPA_PROP_FLAG_READABLE,
|
||||
SPA_PROP_TYPE_STRING, 127,
|
||||
0, NULL,
|
||||
SPA_PROP_RANGE_TYPE_NONE, 0, NULL,
|
||||
NULL,
|
||||
offsetof (SpaV4l2SourceProps, device_name),
|
||||
0, 0,
|
||||
NULL },
|
||||
{ PROP_ID_DEVICE_FD, "device-fd", "Device file descriptor",
|
||||
SPA_PROP_FLAG_READABLE,
|
||||
SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
|
||||
0, NULL,
|
||||
SPA_PROP_RANGE_TYPE_NONE, 0, NULL,
|
||||
NULL,
|
||||
offsetof (SpaV4l2SourceProps, device_fd),
|
||||
0, 0,
|
||||
NULL },
|
||||
};
|
||||
|
||||
static SpaResult
|
||||
spa_v4l2_source_node_get_props (SpaHandle *handle,
|
||||
SpaProps **props)
|
||||
{
|
||||
SpaV4l2Source *this = (SpaV4l2Source *) handle;
|
||||
|
||||
if (handle == NULL || props == NULL)
|
||||
return SPA_RESULT_INVALID_ARGUMENTS;
|
||||
|
||||
memcpy (&this->tmp_props, &this->props, sizeof (this->props));
|
||||
*props = &this->tmp_props.props;
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
static SpaResult
|
||||
spa_v4l2_source_node_set_props (SpaHandle *handle,
|
||||
const SpaProps *props)
|
||||
{
|
||||
SpaV4l2Source *this = (SpaV4l2Source *) handle;
|
||||
SpaV4l2SourceProps *p = &this->props;
|
||||
SpaResult res;
|
||||
|
||||
if (handle == NULL)
|
||||
return SPA_RESULT_INVALID_ARGUMENTS;
|
||||
|
||||
if (props == NULL) {
|
||||
reset_v4l2_source_props (p);
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
res = spa_props_copy (props, &p->props);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static SpaResult
|
||||
spa_v4l2_source_node_send_command (SpaHandle *handle,
|
||||
SpaCommand *command)
|
||||
{
|
||||
SpaV4l2Source *this = (SpaV4l2Source *) handle;
|
||||
|
||||
if (handle == NULL || command == NULL)
|
||||
return SPA_RESULT_INVALID_ARGUMENTS;
|
||||
|
||||
switch (command->type) {
|
||||
case SPA_COMMAND_INVALID:
|
||||
return SPA_RESULT_INVALID_COMMAND;
|
||||
|
||||
case SPA_COMMAND_ACTIVATE:
|
||||
if (!this->activated) {
|
||||
spa_v4l2_open (this);
|
||||
this->activated = true;
|
||||
}
|
||||
if (this->event_cb) {
|
||||
SpaEvent event;
|
||||
|
||||
event.refcount = 1;
|
||||
event.notify = NULL;
|
||||
event.type = SPA_EVENT_TYPE_ACTIVATED;
|
||||
event.port_id = -1;
|
||||
event.data = NULL;
|
||||
event.size = 0;
|
||||
|
||||
this->event_cb (handle, &event, this->user_data);
|
||||
}
|
||||
break;
|
||||
case SPA_COMMAND_DEACTIVATE:
|
||||
if (this->activated) {
|
||||
spa_v4l2_close (this);
|
||||
this->activated = false;
|
||||
}
|
||||
if (this->event_cb) {
|
||||
SpaEvent event;
|
||||
|
||||
event.refcount = 1;
|
||||
event.notify = NULL;
|
||||
event.type = SPA_EVENT_TYPE_DEACTIVATED;
|
||||
event.port_id = -1;
|
||||
event.data = NULL;
|
||||
event.size = 0;
|
||||
|
||||
this->event_cb (handle, &event, this->user_data);
|
||||
}
|
||||
break;
|
||||
case SPA_COMMAND_START:
|
||||
spa_v4l2_start (this);
|
||||
break;
|
||||
case SPA_COMMAND_STOP:
|
||||
spa_v4l2_stop (this);
|
||||
break;
|
||||
case SPA_COMMAND_FLUSH:
|
||||
case SPA_COMMAND_DRAIN:
|
||||
case SPA_COMMAND_MARKER:
|
||||
return SPA_RESULT_NOT_IMPLEMENTED;
|
||||
}
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
static SpaResult
|
||||
spa_v4l2_source_node_set_event_callback (SpaHandle *handle,
|
||||
SpaEventCallback event,
|
||||
void *user_data)
|
||||
{
|
||||
SpaV4l2Source *this = (SpaV4l2Source *) handle;
|
||||
|
||||
if (handle == NULL)
|
||||
return SPA_RESULT_INVALID_ARGUMENTS;
|
||||
|
||||
this->event_cb = event;
|
||||
this->user_data = user_data;
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
static SpaResult
|
||||
spa_v4l2_source_node_get_n_ports (SpaHandle *handle,
|
||||
unsigned int *n_input_ports,
|
||||
unsigned int *max_input_ports,
|
||||
unsigned int *n_output_ports,
|
||||
unsigned int *max_output_ports)
|
||||
{
|
||||
if (handle == NULL)
|
||||
return SPA_RESULT_INVALID_ARGUMENTS;
|
||||
|
||||
if (n_input_ports)
|
||||
*n_input_ports = 0;
|
||||
if (n_output_ports)
|
||||
*n_output_ports = 1;
|
||||
if (max_input_ports)
|
||||
*max_input_ports = 0;
|
||||
if (max_output_ports)
|
||||
*max_output_ports = 1;
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
static SpaResult
|
||||
spa_v4l2_source_node_get_port_ids (SpaHandle *handle,
|
||||
unsigned int n_input_ports,
|
||||
uint32_t *input_ids,
|
||||
unsigned int n_output_ports,
|
||||
uint32_t *output_ids)
|
||||
{
|
||||
if (handle == NULL)
|
||||
return SPA_RESULT_INVALID_ARGUMENTS;
|
||||
|
||||
if (n_output_ports > 0)
|
||||
output_ids[0] = 0;
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
|
||||
static SpaResult
|
||||
spa_v4l2_source_node_add_port (SpaHandle *handle,
|
||||
SpaDirection direction,
|
||||
uint32_t *port_id)
|
||||
{
|
||||
return SPA_RESULT_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
static SpaResult
|
||||
spa_v4l2_source_node_remove_port (SpaHandle *handle,
|
||||
uint32_t port_id)
|
||||
{
|
||||
return SPA_RESULT_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
static SpaResult
|
||||
spa_v4l2_source_node_enum_port_formats (SpaHandle *handle,
|
||||
uint32_t port_id,
|
||||
unsigned int index,
|
||||
SpaFormat **format)
|
||||
{
|
||||
SpaV4l2Source *this = (SpaV4l2Source *) handle;
|
||||
|
||||
if (handle == NULL || format == NULL)
|
||||
return SPA_RESULT_INVALID_ARGUMENTS;
|
||||
|
||||
if (port_id != 0)
|
||||
return SPA_RESULT_INVALID_PORT;
|
||||
|
||||
switch (index) {
|
||||
case 0:
|
||||
spa_video_raw_format_init (&this->query_format);
|
||||
break;
|
||||
default:
|
||||
return SPA_RESULT_ENUM_END;
|
||||
}
|
||||
*format = &this->query_format.format;
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
static SpaResult
|
||||
spa_v4l2_source_node_set_port_format (SpaHandle *handle,
|
||||
uint32_t port_id,
|
||||
int test_only,
|
||||
const SpaFormat *format)
|
||||
{
|
||||
SpaV4l2Source *this = (SpaV4l2Source *) handle;
|
||||
SpaResult res;
|
||||
|
||||
if (handle == NULL || format == NULL)
|
||||
return SPA_RESULT_INVALID_ARGUMENTS;
|
||||
|
||||
if (port_id != 0)
|
||||
return SPA_RESULT_INVALID_PORT;
|
||||
|
||||
if (format == NULL) {
|
||||
this->have_format = false;
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
if ((res = spa_video_raw_format_parse (format, &this->current_format)) < 0)
|
||||
return res;
|
||||
|
||||
this->have_format = true;
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
static SpaResult
|
||||
spa_v4l2_source_node_get_port_format (SpaHandle *handle,
|
||||
uint32_t port_id,
|
||||
const SpaFormat **format)
|
||||
{
|
||||
SpaV4l2Source *this = (SpaV4l2Source *) handle;
|
||||
|
||||
if (handle == NULL || format == NULL)
|
||||
return SPA_RESULT_INVALID_ARGUMENTS;
|
||||
|
||||
if (port_id != 0)
|
||||
return SPA_RESULT_INVALID_PORT;
|
||||
|
||||
if (!this->have_format)
|
||||
return SPA_RESULT_NO_FORMAT;
|
||||
|
||||
*format = &this->current_format.format;
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
static SpaResult
|
||||
spa_v4l2_source_node_get_port_info (SpaHandle *handle,
|
||||
uint32_t port_id,
|
||||
const SpaPortInfo **info)
|
||||
{
|
||||
SpaV4l2Source *this = (SpaV4l2Source *) handle;
|
||||
|
||||
if (handle == NULL || info == NULL)
|
||||
return SPA_RESULT_INVALID_ARGUMENTS;
|
||||
|
||||
if (port_id != 0)
|
||||
return SPA_RESULT_INVALID_PORT;
|
||||
|
||||
*info = &this->info;
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
static SpaResult
|
||||
spa_v4l2_source_node_get_port_props (SpaHandle *handle,
|
||||
uint32_t port_id,
|
||||
SpaProps **props)
|
||||
{
|
||||
return SPA_RESULT_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
static SpaResult
|
||||
spa_v4l2_source_node_set_port_props (SpaHandle *handle,
|
||||
uint32_t port_id,
|
||||
const SpaProps *props)
|
||||
{
|
||||
return SPA_RESULT_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
static SpaResult
|
||||
spa_v4l2_source_node_get_port_status (SpaHandle *handle,
|
||||
uint32_t port_id,
|
||||
const SpaPortStatus **status)
|
||||
{
|
||||
SpaV4l2Source *this = (SpaV4l2Source *) handle;
|
||||
|
||||
if (handle == NULL || status == NULL)
|
||||
return SPA_RESULT_INVALID_ARGUMENTS;
|
||||
|
||||
if (port_id != 0)
|
||||
return SPA_RESULT_INVALID_PORT;
|
||||
|
||||
*status = &this->status;
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
static SpaResult
|
||||
spa_v4l2_source_node_push_port_input (SpaHandle *handle,
|
||||
unsigned int n_info,
|
||||
SpaInputInfo *info)
|
||||
{
|
||||
return SPA_RESULT_INVALID_PORT;
|
||||
}
|
||||
|
||||
static SpaResult
|
||||
spa_v4l2_source_node_pull_port_output (SpaHandle *handle,
|
||||
unsigned int n_info,
|
||||
SpaOutputInfo *info)
|
||||
{
|
||||
SpaV4l2Source *this = (SpaV4l2Source *) handle;
|
||||
unsigned int i;
|
||||
bool have_error = false;
|
||||
|
||||
if (handle == NULL || n_info == 0 || info == NULL)
|
||||
return SPA_RESULT_INVALID_ARGUMENTS;
|
||||
|
||||
for (i = 0; i < n_info; i++) {
|
||||
if (info[i].port_id != 0) {
|
||||
info[i].status = SPA_RESULT_INVALID_PORT;
|
||||
have_error = true;
|
||||
continue;
|
||||
}
|
||||
if (!this->have_format) {
|
||||
info[i].status = SPA_RESULT_NO_FORMAT;
|
||||
have_error = true;
|
||||
continue;
|
||||
}
|
||||
info[i].status = SPA_RESULT_OK;
|
||||
}
|
||||
if (have_error)
|
||||
return SPA_RESULT_ERROR;
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
static const SpaNode v4l2source_node = {
|
||||
sizeof (SpaNode),
|
||||
spa_v4l2_source_node_get_props,
|
||||
spa_v4l2_source_node_set_props,
|
||||
spa_v4l2_source_node_send_command,
|
||||
spa_v4l2_source_node_set_event_callback,
|
||||
spa_v4l2_source_node_get_n_ports,
|
||||
spa_v4l2_source_node_get_port_ids,
|
||||
spa_v4l2_source_node_add_port,
|
||||
spa_v4l2_source_node_remove_port,
|
||||
spa_v4l2_source_node_enum_port_formats,
|
||||
spa_v4l2_source_node_set_port_format,
|
||||
spa_v4l2_source_node_get_port_format,
|
||||
spa_v4l2_source_node_get_port_info,
|
||||
spa_v4l2_source_node_get_port_props,
|
||||
spa_v4l2_source_node_set_port_props,
|
||||
spa_v4l2_source_node_get_port_status,
|
||||
spa_v4l2_source_node_push_port_input,
|
||||
spa_v4l2_source_node_pull_port_output,
|
||||
};
|
||||
|
||||
static SpaResult
|
||||
spa_v4l2_source_get_interface (SpaHandle *handle,
|
||||
uint32_t interface_id,
|
||||
const void **interface)
|
||||
{
|
||||
if (handle == NULL || interface == NULL)
|
||||
return SPA_RESULT_INVALID_ARGUMENTS;
|
||||
|
||||
switch (interface_id) {
|
||||
case SPA_INTERFACE_ID_NODE:
|
||||
*interface = &v4l2source_node;
|
||||
break;
|
||||
default:
|
||||
return SPA_RESULT_UNKNOWN_INTERFACE;
|
||||
}
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
SpaHandle *
|
||||
spa_v4l2_source_new (void)
|
||||
{
|
||||
SpaHandle *handle;
|
||||
SpaV4l2Source *this;
|
||||
|
||||
handle = calloc (1, sizeof (SpaV4l2Source));
|
||||
handle->get_interface = spa_v4l2_source_get_interface;
|
||||
|
||||
this = (SpaV4l2Source *) handle;
|
||||
this->props.props.n_prop_info = PROP_ID_LAST;
|
||||
this->props.props.prop_info = prop_info;
|
||||
this->props.props.set_prop = spa_props_generic_set_prop;
|
||||
this->props.props.get_prop = spa_props_generic_get_prop;
|
||||
reset_v4l2_source_props (&this->props);
|
||||
|
||||
this->info.flags = SPA_PORT_INFO_FLAG_NONE;
|
||||
this->status.flags = SPA_PORT_STATUS_FLAG_NONE;
|
||||
return handle;
|
||||
}
|
||||
82
spa/plugins/v4l2/v4l2-utils.c
Normal file
82
spa/plugins/v4l2/v4l2-utils.c
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sched.h>
|
||||
#include <errno.h>
|
||||
#include <getopt.h>
|
||||
#include <sys/time.h>
|
||||
#include <math.h>
|
||||
|
||||
#define CHECK(s,msg) if ((err = (s)) < 0) { printf (msg ": %s\n", snd_strerror(err)); return err; }
|
||||
|
||||
|
||||
static int
|
||||
spa_v4l2_open (SpaV4l2Source *this)
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
fprintf (stderr, "Playback device is '%s'\n", this->props.device);
|
||||
|
||||
if (stat (this->props.device, &st) < 0) {
|
||||
fprintf(stderr, "Cannot identify '%s': %d, %s\n",
|
||||
this->props.device, errno, strerror (errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!S_ISCHR (st.st_mode)) {
|
||||
fprintf(stderr, "%s is no device\n", this->props.device);
|
||||
return -1;
|
||||
}
|
||||
|
||||
this->state.fd = open (this->props.device, O_RDWR | O_NONBLOCK, 0);
|
||||
|
||||
if (this->state.fd == -1) {
|
||||
fprintf(stderr, "Cannot open '%s': %d, %s\n",
|
||||
this->props.device, errno, strerror (errno));
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
spa_v4l2_close (SpaV4l2Source *this)
|
||||
{
|
||||
if (close(this->state.fd))
|
||||
fprintf(stderr, "Cannot close %d, %s\n",
|
||||
errno, strerror (errno));
|
||||
|
||||
this->state.fd = -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void *
|
||||
v4l2_loop (void *user_data)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
spa_v4l2_start (SpaV4l2Source *this)
|
||||
{
|
||||
SpaV4l2State *state = &this->state;
|
||||
int err;
|
||||
|
||||
state->running = true;
|
||||
if ((err = pthread_create (&state->thread, NULL, v4l2_loop, this)) != 0) {
|
||||
printf ("can't create thread: %d", err);
|
||||
state->running = false;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
static int
|
||||
spa_v4l2_stop (SpaV4l2Source *this)
|
||||
{
|
||||
SpaV4l2State *state = &this->state;
|
||||
|
||||
if (state->running) {
|
||||
state->running = false;
|
||||
pthread_join (state->thread, NULL);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
78
spa/plugins/v4l2/v4l2.c
Normal file
78
spa/plugins/v4l2/v4l2.c
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
/* Spa V4l2 support
|
||||
* Copyright (C) 2016 Wim Taymans <wim.taymans@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <spa/plugin.h>
|
||||
#include <spa/node.h>
|
||||
|
||||
SpaHandle * spa_v4l2_source_new (void);
|
||||
|
||||
static SpaResult
|
||||
v4l2_source_instantiate (const SpaHandleFactory *factory,
|
||||
SpaHandle **handle)
|
||||
{
|
||||
if (factory == NULL || handle == NULL)
|
||||
return SPA_RESULT_INVALID_ARGUMENTS;
|
||||
|
||||
*handle = spa_v4l2_source_new ();
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
static const SpaInterfaceInfo v4l2_source_interfaces[] =
|
||||
{
|
||||
{ SPA_INTERFACE_ID_NODE,
|
||||
SPA_INTERFACE_ID_NODE_NAME,
|
||||
SPA_INTERFACE_ID_NODE_DESCRIPTION,
|
||||
},
|
||||
};
|
||||
|
||||
static SpaResult
|
||||
v4l2_source_enum_interface_info (const SpaHandleFactory *factory,
|
||||
unsigned int index,
|
||||
const SpaInterfaceInfo **info)
|
||||
{
|
||||
if (index >= 1)
|
||||
return SPA_RESULT_ENUM_END;
|
||||
|
||||
*info = &v4l2_source_interfaces[index];
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
static const SpaHandleFactory factories[] =
|
||||
{
|
||||
{ "v4l2-source",
|
||||
NULL,
|
||||
v4l2_source_instantiate,
|
||||
v4l2_source_enum_interface_info,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
SpaResult
|
||||
spa_enum_handle_factory (unsigned int index,
|
||||
const SpaHandleFactory **factory)
|
||||
{
|
||||
if (index >= 1)
|
||||
return SPA_RESULT_ENUM_END;
|
||||
|
||||
*factory = &factories[index];
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
|
@ -21,7 +21,7 @@
|
|||
#include <stddef.h>
|
||||
|
||||
#include <spa/node.h>
|
||||
#include <spa/audio/raw.h>
|
||||
#include <spa/audio/format.h>
|
||||
|
||||
typedef struct _SpaVolume SpaVolume;
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
#include <dlfcn.h>
|
||||
|
||||
#include <spa/node.h>
|
||||
#include <spa/audio/raw.h>
|
||||
#include <spa/audio/format.h>
|
||||
|
||||
typedef struct {
|
||||
SpaHandle *sink;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue