mirror of
https://gitlab.uni-freiburg.de/opensourcevdi/spice
synced 2025-12-26 14:41:25 +00:00
gstreamer-encoder: Map the drm format to appropriate Gstreamer format
We need to convert the scanout's drm format to the correct Gstreamer format while configuring the pipeline. This can be done using gst_video_dma_drm_fourcc_to_format() API, which will take the drm fourcc value and return the appropriate Gst format. Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
This commit is contained in:
parent
ddc3358818
commit
c8d2012a5a
@ -1790,6 +1790,7 @@ static void red_marshall_gl_draw_stream(DisplayChannelClient *dcc,
|
||||
}
|
||||
|
||||
dmabuf_data->drm_dma_buf_fd = scanout->drm_dma_buf_fd;
|
||||
dmabuf_data->drm_fourcc_format = scanout->drm_fourcc_format;
|
||||
dmabuf_data->width = stream->width;
|
||||
dmabuf_data->height = stream->height;
|
||||
dmabuf_data->stride = stream->stride;
|
||||
|
||||
@ -31,6 +31,7 @@
|
||||
#include <gst/app/gstappsrc.h>
|
||||
#include <gst/app/gstappsink.h>
|
||||
#include <gst/video/video.h>
|
||||
#include <gst/video/video-info-dma.h>
|
||||
#include <orc/orcprogram.h>
|
||||
#if defined(__GNUC__) && (__GNUC__ >= 6)
|
||||
# pragma GCC diagnostic pop
|
||||
@ -40,19 +41,26 @@
|
||||
#include "video-encoder.h"
|
||||
#include "utils.h"
|
||||
#include "common/udev.h"
|
||||
|
||||
#include "drm/drm_fourcc.h"
|
||||
|
||||
#define SPICE_GST_DEFAULT_FPS 30
|
||||
|
||||
typedef struct {
|
||||
SpiceBitmapFmt spice_format;
|
||||
uint32_t drm_format;
|
||||
uint32_t bpp;
|
||||
char format[8];
|
||||
GstVideoFormat gst_format;
|
||||
} SpiceFormatForGStreamer;
|
||||
|
||||
#define __FMT_DESC(spice_format, drm_format, bpp, format, gst_format) \
|
||||
{ spice_format, drm_format, bpp, format, gst_format }
|
||||
|
||||
#define FMT_DESC(spice_format, bpp, format, gst_format) \
|
||||
{ spice_format, bpp, format, gst_format }
|
||||
__FMT_DESC(spice_format, DRM_FORMAT_INVALID, bpp, format, gst_format)
|
||||
|
||||
#define DRM_FMT_DESC(drm_format, bpp) \
|
||||
__FMT_DESC(SPICE_BITMAP_FMT_INVALID, drm_format, bpp, "", GST_VIDEO_FORMAT_UNKNOWN)
|
||||
|
||||
typedef struct SpiceGstVideoBuffer {
|
||||
VideoBuffer base;
|
||||
@ -93,6 +101,7 @@ typedef struct SpiceGstEncoder {
|
||||
uint32_t height;
|
||||
const SpiceFormatForGStreamer *format;
|
||||
SpiceBitmapFmt spice_format;
|
||||
uint32_t drm_format;
|
||||
|
||||
/* Number of consecutive frame encoding errors. */
|
||||
uint32_t errors;
|
||||
@ -784,6 +793,47 @@ static const SpiceFormatForGStreamer *map_format(SpiceBitmapFmt format)
|
||||
return GSTREAMER_FORMAT_INVALID;
|
||||
}
|
||||
|
||||
static SpiceFormatForGStreamer drm_format_map[] = {
|
||||
DRM_FMT_DESC(DRM_FORMAT_INVALID, 0),
|
||||
DRM_FMT_DESC(DRM_FORMAT_XRGB8888, 32),
|
||||
DRM_FMT_DESC(DRM_FORMAT_XBGR8888, 32),
|
||||
DRM_FMT_DESC(DRM_FORMAT_RGBX8888, 32),
|
||||
DRM_FMT_DESC(DRM_FORMAT_BGRX8888, 32),
|
||||
DRM_FMT_DESC(DRM_FORMAT_ARGB8888, 32),
|
||||
DRM_FMT_DESC(DRM_FORMAT_ABGR8888, 32),
|
||||
DRM_FMT_DESC(DRM_FORMAT_RGBA8888, 32),
|
||||
DRM_FMT_DESC(DRM_FORMAT_BGRA8888, 32),
|
||||
};
|
||||
#define GSTREAMER_DRM_FORMAT_INVALID (&drm_format_map[0])
|
||||
|
||||
static const SpiceFormatForGStreamer *map_drm_format(uint32_t fourcc)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS(drm_format_map); i++) {
|
||||
if (drm_format_map[i].drm_format == fourcc) {
|
||||
if (drm_format_map[i].gst_format == GST_VIDEO_FORMAT_UNKNOWN) {
|
||||
int format_size = sizeof(drm_format_map[i].format);
|
||||
GstVideoFormat gst_format;
|
||||
|
||||
gst_format = gst_video_dma_drm_fourcc_to_format(fourcc);
|
||||
if (gst_format == GST_VIDEO_FORMAT_UNKNOWN) {
|
||||
break;
|
||||
}
|
||||
|
||||
drm_format_map[i].gst_format = gst_format;
|
||||
strncpy(drm_format_map[i].format,
|
||||
gst_video_format_to_string(gst_format),
|
||||
format_size - 1);
|
||||
drm_format_map[i].format[format_size - 1] = '\0';
|
||||
}
|
||||
return &drm_format_map[i];
|
||||
}
|
||||
}
|
||||
|
||||
return GSTREAMER_DRM_FORMAT_INVALID;
|
||||
}
|
||||
|
||||
static void set_appsrc_caps(SpiceGstEncoder *encoder)
|
||||
{
|
||||
if (encoder->src_caps) {
|
||||
@ -1561,26 +1611,41 @@ static void spice_gst_encoder_add_frame(SpiceGstEncoder *encoder,
|
||||
static VideoEncodeResults
|
||||
spice_gst_encoder_configure_pipeline(SpiceGstEncoder *encoder,
|
||||
uint32_t width, uint32_t height,
|
||||
const SpiceBitmap *bitmap,
|
||||
SpiceBitmapFmt spice_format,
|
||||
uint32_t drm_format,
|
||||
uint32_t frame_mm_time)
|
||||
{
|
||||
SpiceBitmapFmt format = bitmap ? (SpiceBitmapFmt) bitmap->format :
|
||||
SPICE_BITMAP_FMT_32BIT;
|
||||
const SpiceFormatForGStreamer *format = GSTREAMER_FORMAT_INVALID;
|
||||
|
||||
if (spice_format != SPICE_BITMAP_FMT_INVALID) {
|
||||
format = map_format(spice_format);
|
||||
} else if (drm_format != DRM_FORMAT_INVALID) {
|
||||
format = map_drm_format(drm_format);
|
||||
}
|
||||
|
||||
if (format == GSTREAMER_FORMAT_INVALID ||
|
||||
format == GSTREAMER_DRM_FORMAT_INVALID) {
|
||||
spice_warning("unable to map format type %d or %u",
|
||||
spice_format, drm_format);
|
||||
encoder->errors = 4;
|
||||
return VIDEO_ENCODER_FRAME_UNSUPPORTED;
|
||||
}
|
||||
|
||||
if (width != encoder->width || height != encoder->height ||
|
||||
encoder->spice_format != format) {
|
||||
spice_debug("video format change: width %d -> %d, height %d -> %d, format %d -> %d",
|
||||
encoder->spice_format != spice_format ||
|
||||
encoder->drm_format != drm_format) {
|
||||
spice_debug("video format change: width %d -> %d, height %d -> %d,"
|
||||
"spice format %d -> %d, drm format %u -> %u",
|
||||
encoder->width, width, encoder->height, height,
|
||||
encoder->spice_format, format);
|
||||
encoder->format = map_format(format);
|
||||
if (encoder->format == GSTREAMER_FORMAT_INVALID) {
|
||||
spice_warning("unable to map format type %d", format);
|
||||
encoder->errors = 4;
|
||||
return VIDEO_ENCODER_FRAME_UNSUPPORTED;
|
||||
}
|
||||
encoder->spice_format = format;
|
||||
encoder->spice_format, spice_format,
|
||||
encoder->drm_format, drm_format);
|
||||
|
||||
encoder->format = format;
|
||||
encoder->spice_format = spice_format;
|
||||
encoder->drm_format = drm_format;
|
||||
encoder->width = width;
|
||||
encoder->height = height;
|
||||
|
||||
if (encoder->bit_rate == 0) {
|
||||
encoder->history[0].mm_time = frame_mm_time;
|
||||
encoder->max_bit_rate = get_bit_rate_cap(encoder);
|
||||
@ -1640,7 +1705,9 @@ spice_gst_encoder_encode_frame(VideoEncoder *video_encoder,
|
||||
uint32_t height = src->bottom - src->top;
|
||||
|
||||
rc = spice_gst_encoder_configure_pipeline(encoder, width, height,
|
||||
bitmap, frame_mm_time);
|
||||
bitmap->format,
|
||||
DRM_FORMAT_INVALID,
|
||||
frame_mm_time);
|
||||
if (rc != VIDEO_ENCODER_FRAME_ENCODE_DONE) {
|
||||
return rc;
|
||||
}
|
||||
@ -1691,7 +1758,9 @@ spice_gst_encoder_encode_dmabuf(VideoEncoder *video_encoder,
|
||||
VideoEncodeResults rc;
|
||||
|
||||
rc = spice_gst_encoder_configure_pipeline(encoder, dmabuf_data->width,
|
||||
dmabuf_data->height, NULL,
|
||||
dmabuf_data->height,
|
||||
SPICE_BITMAP_FMT_INVALID,
|
||||
dmabuf_data->drm_fourcc_format,
|
||||
frame_mm_time);
|
||||
if (rc != VIDEO_ENCODER_FRAME_ENCODE_DONE) {
|
||||
return rc;
|
||||
|
||||
@ -61,6 +61,7 @@ typedef struct VideoEncoderDmabufData {
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
uint32_t stride;
|
||||
uint32_t drm_fourcc_format;
|
||||
void *dcc;
|
||||
void (*free)(struct VideoEncoderDmabufData*);
|
||||
} VideoEncoderDmabufData;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user