Skip to content

Commit

Permalink
Merge pull request #40 from zouxiaoh/icamerasrc_slim_api
Browse files Browse the repository at this point in the history
Release to support drm dma buffer for gstreamer 1.22
  • Loading branch information
zouxiaoh authored Mar 21, 2024
2 parents 528a6f1 + aeb10c0 commit 086aa9f
Show file tree
Hide file tree
Showing 12 changed files with 980 additions and 20 deletions.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,13 @@ sudo make install
# build rpm package and then install
make rpm
rpm -ivh --force --nodeps icamerasrc-*.rpm

NOTE:
For gstreamer version > 1.22.0, add support for drm dma buffer.
It depends on libdrm, please install it when build icamerasrc,
if user wants to enable drm dma buffer.

sudo apt install libdrm-dev
```
## Pipeline examples
Expand Down Expand Up @@ -65,4 +72,5 @@ sudo -E gst-launch-1.0 icamerasrc device-name=ov13858-uf af-mode=2 ! video/x-raw
* Sensor ar0234
```
sudo -E gst-launch-1.0 icamerasrc device-name=ar0234 ! video/x-raw,format=NV12,width=1280,height=960 ! videoconvert ! glimagesink
sudo -E gst-launch-1.0 icamerasrc device-name=ar0234 io-mode=dma_mode ! 'video/x-raw(memory:DMABuf),drm-format=NV12,width=1280,height=960' ! glimagesink
```
23 changes: 22 additions & 1 deletion configure.ac
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#
# GStreamer
# Copyright (C) 2015-2023 Intel Corporation
# Copyright (C) 2015-2024 Intel Corporation
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
Expand Down Expand Up @@ -194,6 +194,27 @@ PKG_CHECK_MODULES(LIBDRM, [libdrm libdrm_intel], [
AC_MSG_ERROR([Cannot find libdrm pkgconfig])
])

PKG_CHECK_MODULES(LIBGSTREAMERVA, [gstreamer-va-1.0], [
AC_SUBST(LIBGSTREAMERVA_CFLAGS)
AC_SUBST(LIBGSTREAMERVA_LIBS)
], [
AC_MSG_WARN([Cannot find gstreamer-va-1.0 pkgconfig])
])

PKG_CHECK_MODULES(LIBVA, [libva], [
AC_SUBST(LIBVA_CFLAGS)
AC_SUBST(LIBVA_LIBS)
], [
AC_MSG_WARN([Cannot find libva pkgconfig])
])

PKG_CHECK_MODULES(LIBVA_DRM, [libva-drm], [
AC_SUBST(LIBVA_DRM_CFLAGS)
AC_SUBST(LIBVA_DRM_LIBS)
], [
AC_MSG_WARN([Cannot find libva-drm pkgconfig])
])

dnl check if compiler understands -Wall (if yes, add -Wall to GST_CFLAGS)
AC_MSG_CHECKING([to see if compiler understands -Wall])
save_CFLAGS="$CFLAGS"
Expand Down
8 changes: 7 additions & 1 deletion src/Makefile.am
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#
# GStreamer
# Copyright (C) 2015-2023 Intel Corporation
# Copyright (C) 2015-2024 Intel Corporation
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
Expand Down Expand Up @@ -73,6 +73,9 @@ libgsticamerasrc_la_CPPFLAGS = \
$(GST_CFLAGS) \
$(CAMHAL_CFLAGS) \
$(LIBDRM_CFLAGS) \
$(LIBVA_CFLAGS) \
$(LIBVA_DRM_CFLAGS) \
$(LIBGSTREAMERVA_CFLAGS) \
-std=c++11 \
-Werror \
$(LIBUTILS_CFLAGS) \
Expand All @@ -91,6 +94,9 @@ libgsticamerasrc_la_LIBADD = $(GST_LIBS) \
-lgstvideo-$(GST_API_VERSION) \
interfaces/libgsticamerainterface-$(GST_API_VERSION).la \
$(LIBDRM_LIBS) \
$(LIBVA_LIBS) \
$(LIBVA_DRM_LIBS) \
$(LIBGSTREAMERVA_LIBS) \
$(CAMHAL_LIBS)

libgsticamerasrc_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
Expand Down
18 changes: 17 additions & 1 deletion src/gstcambasesrc.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* GStreamer
* Copyright (C) 2015-2021 Intel Corporation
* Copyright (C) 2015-2024 Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
Expand Down Expand Up @@ -447,6 +447,9 @@ gst_cam_base_src_init(GstCamBaseSrc *basesrc, GstCamBaseSrcClass *klass)
gst_video_info_init(&basesrc->srcpad_info);
basesrc->is_info_change = FALSE;
#endif
#if GST_VERSION_MINOR >= 22
basesrc->is_dma_drm_caps = FALSE;
#endif

basesrc->blocksize = DEFAULT_BLOCKSIZE;
basesrc->clock_id = NULL;
Expand Down Expand Up @@ -3734,9 +3737,17 @@ gst_cam_base_src_negotiate (GstCamBaseSrc * basesrc, GstPad *pad)

caps = gst_pad_get_current_caps (pad);

#if GST_VERSION_MINOR >= 22
basesrc->is_dma_drm_caps = gst_video_is_dma_drm_caps(caps);
#endif

#if GST_VERSION_MINOR >= 18
if (basesrc->is_info_change) {
#if GST_VERSION_MINOR >= 22
if (!CameraSrcUtils::gst_video_info_from_dma_drm_caps(&vinfo, caps))
#else
if (!gst_video_info_from_caps(&vinfo, caps))
#endif
GST_DEBUG_OBJECT (basesrc, "Failed to get video info from caps.");
else {
if (!gst_video_info_is_equal(&basesrc->srcpad_info, &vinfo))
Expand All @@ -3750,6 +3761,11 @@ gst_cam_base_src_negotiate (GstCamBaseSrc * basesrc, GstPad *pad)
#endif
result = gst_cam_base_src_prepare_allocation (basesrc, caps, pad);

#if GST_VERSION_MINOR >= 18
if (tmp_caps)
gst_caps_unref (tmp_caps);
#endif

if (caps)
gst_caps_unref (caps);
}
Expand Down
6 changes: 5 additions & 1 deletion src/gstcambasesrc.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* GStreamer
* Copyright (C) 2015-2021 Intel Corporation
* Copyright (C) 2015-2024 Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
Expand Down Expand Up @@ -135,6 +135,10 @@ struct _GstCamBaseSrc {
GstVideoInfo srcpad_info;
gboolean is_info_change;
#endif
#if GST_VERSION_MINOR >= 22
/* indicate current caps is dma_drm type for io_mode=dma_mode. */
bool is_dma_drm_caps;
#endif

/* available to subclass implementations */
/* MT-protected (with LIVE_LOCK) */
Expand Down
93 changes: 91 additions & 2 deletions src/gstcameraformat.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* GStreamer
* Copyright (C) 2015-2021 Intel Corporation
* Copyright (C) 2015-2024 Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
Expand Down Expand Up @@ -93,7 +93,13 @@ static void update_main_resolution(int format,
cameraSrc_Res_Range res_range,
vector <cameraSrc_Main_Res_Range> &main_res_range);
static GstStructure *create_structure (guint32 fourcc);
#if GST_VERSION_MINOR >= 22
static void
set_structure_to_caps(vector<cameraSrc_Main_Res_Range> main_res_range,
GstCaps **caps, GstVaDisplay *display_drm);
#else
static void set_structure_to_caps(vector <cameraSrc_Main_Res_Range> main_res_range, GstCaps **caps);
#endif

static GstStructure *
create_structure (guint32 fourcc)
Expand Down Expand Up @@ -173,11 +179,59 @@ create_structure (guint32 fourcc)
* Merge all structures into caps
*/
#define GST_CAPS_FEATURE_MEMORY_DMABUF "memory:DMABuf"
#if GST_VERSION_MINOR >= 22
static void
set_structure_to_caps(vector<cameraSrc_Main_Res_Range> main_res_range,
GstCaps **caps, GstVaDisplay *display_drm)
#else
static void
set_structure_to_caps(vector <cameraSrc_Main_Res_Range> main_res_range, GstCaps **caps)
#endif
{
GstStructure *structure = NULL;
int feature_index = 0;
#if GST_VERSION_MINOR >= 22
/* Set caps with dmabuffer */
for (auto &res_range : main_res_range) {
structure = create_structure(res_range.format);
if (structure) {
const gchar *fmt_str = gst_structure_get_string(structure, "format");
GstVideoFormat fmt = gst_video_format_from_string(fmt_str);
GValue dma_drm_fmts = G_VALUE_INIT;
g_value_init(&dma_drm_fmts, GST_TYPE_LIST);
if (!CameraSrcUtils::_dma_fmt_to_dma_drm_fmts(display_drm, fmt,
&dma_drm_fmts) ||
gst_value_list_get_size(&dma_drm_fmts) <= 0) {
gst_structure_free(structure);
g_value_unset(&dma_drm_fmts);
continue;
}
gst_structure_set(structure, "format", G_TYPE_STRING, "DMA_DRM", NULL);
gst_structure_set_value(structure, "drm-format", &dma_drm_fmts);
g_value_unset(&dma_drm_fmts);
/* If has only one resolution */
if (res_range.range.max_w == res_range.range.min_w &&
res_range.range.max_h == res_range.range.min_h)
gst_structure_set(structure, "width", G_TYPE_INT, res_range.range.max_w,
"height", G_TYPE_INT, res_range.range.max_h,
"framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT,
1, "pixel-aspect-ratio", GST_TYPE_FRACTION, 1, 1,
NULL);
else
gst_structure_set(structure, "width", GST_TYPE_INT_RANGE,
res_range.range.min_w, res_range.range.max_w,
"height", GST_TYPE_INT_RANGE, res_range.range.min_h,
res_range.range.max_h, "framerate",
GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1,
"pixel-aspect-ratio", GST_TYPE_FRACTION, 1, 1, NULL);
*caps = gst_caps_merge_structure(*caps, structure);
gst_caps_set_features(
*caps, feature_index,
gst_caps_features_new(GST_CAPS_FEATURE_MEMORY_DMABUF, NULL));
feature_index++;
}
}
#else
/* Set caps with dmabuffer */
for (auto&res_range : main_res_range) {
structure = create_structure (res_range.format);
Expand All @@ -204,6 +258,7 @@ set_structure_to_caps(vector <cameraSrc_Main_Res_Range> main_res_range, GstCaps
feature_index++;
}
}
#endif
/* Set caps with userptr */
for (auto&res_range : main_res_range) {
structure = create_structure (res_range.format);
Expand Down Expand Up @@ -329,7 +384,19 @@ GstCaps *gst_camerasrc_get_all_caps ()
vector <camera_resolution_t> fmt_res;
vector <cameraSrc_Main_Res_Range> main_res_range;

static GstCaps *caps = gst_caps_new_empty ();
static GstCaps *caps = NULL;
if (caps != NULL) {
return gst_caps_simplify(caps);
}
caps = gst_caps_new_empty();
#if GST_VERSION_MINOR >= 22
GstVaDisplay *display_drm = NULL;
display_drm = gst_va_display_drm_new_from_path("/dev/dri/renderD128");
if (NULL == display_drm) {
GST_ERROR("Couldn't create a VA DRM display");
return NULL;
}
#endif
int count = get_number_of_cameras();

for(int i = 0; i < count; i++) {
Expand All @@ -341,6 +408,12 @@ GstCaps *gst_camerasrc_get_all_caps ()
if (ret != 0) {
GST_ERROR("failed to get camera info from libcamhal");
gst_caps_unref(caps);
#if GST_VERSION_MINOR >= 22
if (display_drm) {
gst_object_unref(display_drm);
display_drm = NULL;
}
#endif
return NULL;
}
info.capability->getSupportedStreamConfig(configs);
Expand All @@ -349,12 +422,28 @@ GstCaps *gst_camerasrc_get_all_caps ()
if (ret != 0) {
GST_ERROR("failed to get format info from libcamhal");
gst_caps_unref(caps);
#if GST_VERSION_MINOR >= 22
if (display_drm) {
gst_object_unref(display_drm);
display_drm = NULL;
}
#endif
return NULL;
}
}

#if GST_VERSION_MINOR >= 22
set_structure_to_caps(main_res_range, &caps, display_drm);
#else
set_structure_to_caps(main_res_range, &caps);
#endif
main_res_range.clear();
#if GST_VERSION_MINOR >= 22
if (display_drm) {
gst_object_unref(display_drm);
display_drm = NULL;
}
#endif

return gst_caps_simplify(caps);
}
37 changes: 31 additions & 6 deletions src/gstcamerasrc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* GStreamer
* Copyright (C) 2005 Thomas Vander Stichele <thomas@apestaart.org>
* Copyright (C) 2005 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
* Copyright (C) 2015-2023 Intel Corporation
* Copyright (C) 2015-2024 Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
Expand Down Expand Up @@ -1296,6 +1296,10 @@ gst_camerasrc_init (Gstcamerasrc * camerasrc)
camerasrc->streams[GST_CAMERASRC_MAIN_STREAM_ID].stream_config_done = FALSE;
camerasrc->streams[GST_CAMERASRC_MAIN_STREAM_ID].activated = TRUE;
camerasrc->streams[GST_CAMERASRC_MAIN_STREAM_ID].stream_usage = DEFAULT_PROP_SRC_STREAM_USAGE;
#if GST_VERSION_MINOR >= 22
camerasrc->streams[GST_CAMERASRC_MAIN_STREAM_ID].drm_modifier =
DRM_FORMAT_MOD_LINEAR;
#endif

/* set default value for 3A manual control*/
camerasrc->param = new Parameters;
Expand Down Expand Up @@ -2490,12 +2494,29 @@ gst_camerasrc_get_caps_info (Gstcamerasrc* camerasrc, GstCaps * caps, int stream
GstStructure *structure = gst_caps_get_structure (caps, 0);
const gchar *mimetype = gst_structure_get_name (structure);

/* raw caps, parse into video info */
if (!gst_video_info_from_caps (&info, caps)) {
GST_ERROR("CameraId=%d, StreamId=%d Caps can't be parsed",
camerasrc->device_id, stream_id);
return FALSE;
#if GST_VERSION_MINOR >= 22
if (!gst_video_is_dma_drm_caps(caps)) {
#endif
/* raw caps, parse into video info */
if (!gst_video_info_from_caps(&info, caps)) {
GST_ERROR("CameraId=%d, StreamId=%d Caps can't be parsed",
camerasrc->device_id, stream_id);
return FALSE;
}
#if GST_VERSION_MINOR >= 22
} else {
GstVideoInfoDmaDrm drm_info;
if (!gst_video_info_dma_drm_from_caps(&drm_info, caps)) {
GST_ERROR("CameraId=%d, StreamId=%d Caps[dma_drm] can't be parsed",
camerasrc->device_id, stream_id);
return FALSE;
}
camerasrc->streams[stream_id].drm_modifier = drm_info.drm_modifier;
if (!gst_video_info_dma_drm_to_video_info(&drm_info, &info)) {
return FALSE;
}
}
#endif
GstVideoFormat gst_fmt = GST_VIDEO_INFO_FORMAT (&info);

/* parse format from caps */
Expand Down Expand Up @@ -2676,7 +2697,11 @@ gst_camerasrc_set_caps(GstCamBaseSrc *src, GstPad *pad, GstCaps *caps)

#if GST_VERSION_MINOR >= 18
if (camerasrc->io_mode == GST_CAMERASRC_IO_MODE_DMA_MODE) {
#if GST_VERSION_MINOR >= 22
if (CameraSrcUtils::gst_video_info_from_dma_drm_caps(&vinfo, caps)) {
#else
if (gst_video_info_from_caps(&vinfo, caps)) {
#endif
gst_camerasrc_set_video_alignment(&vinfo, 0, 0, &align);
gst_video_info_align(&vinfo, &align);
GST_CAM_BASE_SRC_CLASS(parent_class)->add_video_info(src, &vinfo, TRUE);
Expand Down
6 changes: 5 additions & 1 deletion src/gstcamerasrc.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* GStreamer
* Copyright (C) 2005 Thomas Vander Stichele <thomas@apestaart.org>
* Copyright (C) 2005 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
* Copyright (C) 2015-2021 Intel Corporation
* Copyright (C) 2015-2024 Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
Expand Down Expand Up @@ -463,6 +463,10 @@ struct _GstStreamInfo
/* Buffer config */
guint bpl;
GstVideoInfo info;
#if GST_VERSION_MINOR >= 22
/* drm modifier used currently after negotiated. */
guint64 drm_modifier;
#endif
const char *fmt_name;
camera_info_t cam_info;

Expand Down
Loading

0 comments on commit 086aa9f

Please sign in to comment.