spa: video: Add H.265 as a format

Quite similar to H.264.

Fixes: https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/4674
This commit is contained in:
Arun Raghavan 2025-04-29 16:26:05 -04:00 committed by Wim Taymans
parent 92643f77f9
commit 39e079d8ac
4 changed files with 132 additions and 0 deletions

View file

@ -67,6 +67,7 @@ enum spa_media_subtype {
SPA_MEDIA_SUBTYPE_vp8,
SPA_MEDIA_SUBTYPE_vp9,
SPA_MEDIA_SUBTYPE_bayer,
SPA_MEDIA_SUBTYPE_h265,
SPA_MEDIA_SUBTYPE_START_Image = 0x30000,
SPA_MEDIA_SUBTYPE_jpeg,
@ -132,6 +133,8 @@ enum spa_format {
SPA_FORMAT_VIDEO_level, /**< (Int) */
SPA_FORMAT_VIDEO_H264_streamFormat, /**< (Id enum spa_h264_stream_format) */
SPA_FORMAT_VIDEO_H264_alignment, /**< (Id enum spa_h264_alignment) */
SPA_FORMAT_VIDEO_H265_streamFormat, /**< (Id enum spa_h265_stream_format) */
SPA_FORMAT_VIDEO_H265_alignment, /**< (Id enum spa_h265_alignment) */
/* Image Format keys */
SPA_FORMAT_START_Image = 0x30000,

View file

@ -14,6 +14,7 @@ extern "C" {
#include <spa/param/video/raw-utils.h>
#include <spa/param/video/dsp-utils.h>
#include <spa/param/video/h264-utils.h>
#include <spa/param/video/h265-utils.h>
#include <spa/param/video/mjpg-utils.h>
#ifndef SPA_API_VIDEO_FORMAT_UTILS

View file

@ -0,0 +1,79 @@
/* Simple Plugin API */
/* SPDX-FileCopyrightText: Copyright © 2025 Wim Taymans */
/* SPDX-FileCopyrightText: Copyright © 2025 Arun Raghavan */
/* SPDX-License-Identifier: MIT */
#ifndef SPA_VIDEO_H265_UTILS_H
#define SPA_VIDEO_H265_UTILS_H
#ifdef __cplusplus
extern "C" {
#endif
/**
* \addtogroup spa_param
* \{
*/
#include <spa/pod/parser.h>
#include <spa/pod/builder.h>
#include <spa/param/video/h265.h>
#ifndef SPA_API_VIDEO_H265_UTILS
#ifdef SPA_API_IMPL
#define SPA_API_VIDEO_H265_UTILS SPA_API_IMPL
#else
#define SPA_API_VIDEO_H265_UTILS static inline
#endif
#endif
SPA_API_VIDEO_H265_UTILS int
spa_format_video_h265_parse(const struct spa_pod *format,
struct spa_video_info_h265 *info)
{
return spa_pod_parse_object(format,
SPA_TYPE_OBJECT_Format, NULL,
SPA_FORMAT_VIDEO_size, SPA_POD_OPT_Rectangle(&info->size),
SPA_FORMAT_VIDEO_framerate, SPA_POD_OPT_Fraction(&info->framerate),
SPA_FORMAT_VIDEO_maxFramerate, SPA_POD_OPT_Fraction(&info->max_framerate),
SPA_FORMAT_VIDEO_H265_streamFormat, SPA_POD_OPT_Id(&info->stream_format),
SPA_FORMAT_VIDEO_H265_alignment, SPA_POD_OPT_Id(&info->alignment));
}
SPA_API_VIDEO_H265_UTILS struct spa_pod *
spa_format_video_h265_build(struct spa_pod_builder *builder, uint32_t id,
const struct spa_video_info_h265 *info)
{
struct spa_pod_frame f;
spa_pod_builder_push_object(builder, &f, SPA_TYPE_OBJECT_Format, id);
spa_pod_builder_add(builder,
SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_video),
SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_h265),
0);
if (info->size.width != 0 && info->size.height != 0)
spa_pod_builder_add(builder,
SPA_FORMAT_VIDEO_size, SPA_POD_Rectangle(&info->size), 0);
if (info->framerate.denom != 0)
spa_pod_builder_add(builder,
SPA_FORMAT_VIDEO_framerate, SPA_POD_Fraction(&info->framerate), 0);
if (info->max_framerate.denom != 0)
spa_pod_builder_add(builder,
SPA_FORMAT_VIDEO_maxFramerate, SPA_POD_Fraction(&info->max_framerate), 0);
if (info->stream_format != 0)
spa_pod_builder_add(builder,
SPA_FORMAT_VIDEO_H265_streamFormat, SPA_POD_Id(info->stream_format), 0);
if (info->alignment != 0)
spa_pod_builder_add(builder,
SPA_FORMAT_VIDEO_H265_alignment, SPA_POD_Id(info->alignment), 0);
return (struct spa_pod*)spa_pod_builder_pop(builder, &f);
}
/**
* \}
*/
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* SPA_VIDEO_H265_UTILS_H */

View file

@ -0,0 +1,49 @@
/* Simple Plugin API */
/* SPDX-FileCopyrightText: Copyright © 2025 Wim Taymans */
/* SPDX-FileCopyrightText: Copyright © 2025 Arun Raghavan */
/* SPDX-License-Identifier: MIT */
#ifndef SPA_VIDEO_H265_H
#define SPA_VIDEO_H265_H
#ifdef __cplusplus
extern "C" {
#endif
/**
* \addtogroup spa_param
* \{
*/
#include <spa/param/format.h>
enum spa_h265_stream_format {
SPA_H265_STREAM_FORMAT_UNKNOWN = 0,
SPA_H265_STREAM_FORMAT_HVC1,
SPA_H265_STREAM_FORMAT_HEV1,
SPA_H265_STREAM_FORMAT_BYTESTREAM
};
enum spa_h265_alignment {
SPA_H265_ALIGNMENT_UNKNOWN = 0,
SPA_H265_ALIGNMENT_AU,
SPA_H265_ALIGNMENT_NAL
};
struct spa_video_info_h265 {
struct spa_rectangle size;
struct spa_fraction framerate;
struct spa_fraction max_framerate;
enum spa_h265_stream_format stream_format;
enum spa_h265_alignment alignment;
};
/**
* \}
*/
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* SPA_VIDEO_H265_H */