From 5c8d8723d2d04f9503126b43bd386bf5c67ceb45 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Fri, 27 Sep 2019 08:46:22 +0200 Subject: [PATCH] v4l2: Add MPEG-2 profile and level support Add support for V4L2 MPEG-2 decoders reporting supported profiles and levels. --- sys/v4l2/Makefile.am | 1 + sys/v4l2/gstv4l2mpeg2codec.c | 127 +++++++++++++++++++++++++++++++++++ sys/v4l2/gstv4l2mpeg2codec.h | 32 +++++++++ sys/v4l2/gstv4l2videodec.c | 2 + sys/v4l2/meson.build | 1 + 5 files changed, 163 insertions(+) create mode 100644 sys/v4l2/gstv4l2mpeg2codec.c create mode 100644 sys/v4l2/gstv4l2mpeg2codec.h diff --git a/sys/v4l2/Makefile.am b/sys/v4l2/Makefile.am index 1c311018b8..cd478481ed 100644 --- a/sys/v4l2/Makefile.am +++ b/sys/v4l2/Makefile.am @@ -23,6 +23,7 @@ libgstvideo4linux2_la_SOURCES = gstv4l2.c \ gstv4l2h265codec.c \ gstv4l2h265enc.c \ gstv4l2jpegenc.c \ + gstv4l2mpeg2codec.c \ gstv4l2mpeg4enc.c \ gstv4l2mpeg4codec.c \ gstv4l2vidorient.c \ diff --git a/sys/v4l2/gstv4l2mpeg2codec.c b/sys/v4l2/gstv4l2mpeg2codec.c new file mode 100644 index 0000000000..2106acfb9e --- /dev/null +++ b/sys/v4l2/gstv4l2mpeg2codec.c @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2019 Philipp Zabel + * + * 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 "gstv4l2mpeg2codec.h" + +#include +#include "ext/v4l2-controls.h" + +static gint +v4l2_profile_from_string (const gchar * profile) +{ + gint v4l2_profile = -1; + + if (g_str_equal (profile, "simple")) + v4l2_profile = V4L2_MPEG_VIDEO_MPEG2_PROFILE_SIMPLE; + else if (g_str_equal (profile, "main")) + v4l2_profile = V4L2_MPEG_VIDEO_MPEG2_PROFILE_MAIN; + else if (g_str_equal (profile, "snr")) + v4l2_profile = V4L2_MPEG_VIDEO_MPEG2_PROFILE_SNR_SCALABLE; + else if (g_str_equal (profile, "spatial")) + v4l2_profile = V4L2_MPEG_VIDEO_MPEG2_PROFILE_SPATIALLY_SCALABLE; + else if (g_str_equal (profile, "high")) + v4l2_profile = V4L2_MPEG_VIDEO_MPEG2_PROFILE_HIGH; + else if (g_str_equal (profile, "multiview")) + v4l2_profile = V4L2_MPEG_VIDEO_MPEG2_PROFILE_MULTIVIEW; + else + GST_WARNING ("Unsupported profile string '%s'", profile); + + return v4l2_profile; +} + +static const gchar * +v4l2_profile_to_string (gint v4l2_profile) +{ + switch (v4l2_profile) { + case V4L2_MPEG_VIDEO_MPEG2_PROFILE_SIMPLE: + return "simple"; + case V4L2_MPEG_VIDEO_MPEG2_PROFILE_MAIN: + return "main"; + case V4L2_MPEG_VIDEO_MPEG2_PROFILE_SNR_SCALABLE: + return "snr"; + case V4L2_MPEG_VIDEO_MPEG2_PROFILE_SPATIALLY_SCALABLE: + return "spatial"; + case V4L2_MPEG_VIDEO_MPEG2_PROFILE_HIGH: + return "high"; + case V4L2_MPEG_VIDEO_MPEG2_PROFILE_MULTIVIEW: + return "multiview"; + default: + GST_WARNING ("Unsupported V4L2 profile %i", v4l2_profile); + break; + } + + return NULL; +} + +static gint +v4l2_level_from_string (const gchar * level) +{ + gint v4l2_level = -1; + + if (g_str_equal (level, "low")) + v4l2_level = V4L2_MPEG_VIDEO_MPEG2_LEVEL_LOW; + else if (g_str_equal (level, "main")) + v4l2_level = V4L2_MPEG_VIDEO_MPEG2_LEVEL_MAIN; + else if (g_str_equal (level, "high-1440")) + v4l2_level = V4L2_MPEG_VIDEO_MPEG2_LEVEL_HIGH_1440; + else if (g_str_equal (level, "high")) + v4l2_level = V4L2_MPEG_VIDEO_MPEG2_LEVEL_HIGH; + else + GST_WARNING ("Unsupported level '%s'", level); + + return v4l2_level; +} + +static const gchar * +v4l2_level_to_string (gint v4l2_level) +{ + switch (v4l2_level) { + case V4L2_MPEG_VIDEO_MPEG2_LEVEL_LOW: + return "low"; + case V4L2_MPEG_VIDEO_MPEG2_LEVEL_MAIN: + return "main"; + case V4L2_MPEG_VIDEO_MPEG2_LEVEL_HIGH_1440: + return "high-1440"; + case V4L2_MPEG_VIDEO_MPEG2_LEVEL_HIGH: + return "high"; + default: + GST_WARNING ("Unsupported V4L2 level %i", v4l2_level); + break; + } + + return NULL; +} + +const GstV4l2Codec * +gst_v4l2_mpeg2_get_codec (void) +{ + static GstV4l2Codec *codec = NULL; + if (g_once_init_enter (&codec)) { + static GstV4l2Codec c; + c.profile_cid = V4L2_CID_MPEG_VIDEO_MPEG2_PROFILE; + c.profile_to_string = v4l2_profile_to_string; + c.profile_from_string = v4l2_profile_from_string; + c.level_cid = V4L2_CID_MPEG_VIDEO_MPEG2_LEVEL; + c.level_to_string = v4l2_level_to_string; + c.level_from_string = v4l2_level_from_string; + g_once_init_leave (&codec, &c); + } + return codec; +} diff --git a/sys/v4l2/gstv4l2mpeg2codec.h b/sys/v4l2/gstv4l2mpeg2codec.h new file mode 100644 index 0000000000..9adfd40607 --- /dev/null +++ b/sys/v4l2/gstv4l2mpeg2codec.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2019 Philipp Zabel + * + * 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 __GST_V4L2_MPEG2_CODEC_H__ +#define __GST_V4L2_MPEG2_CODEC_H__ + +#include "gstv4l2codec.h" + +G_BEGIN_DECLS + +const GstV4l2Codec * gst_v4l2_mpeg2_get_codec (void); + +G_END_DECLS + +#endif diff --git a/sys/v4l2/gstv4l2videodec.c b/sys/v4l2/gstv4l2videodec.c index 85f3ee6674..4e50c841c9 100644 --- a/sys/v4l2/gstv4l2videodec.c +++ b/sys/v4l2/gstv4l2videodec.c @@ -34,6 +34,7 @@ #include "gstv4l2h264codec.h" #include "gstv4l2h265codec.h" +#include "gstv4l2mpeg2codec.h" #include "gstv4l2mpeg4codec.h" #include "gstv4l2vp8codec.h" #include "gstv4l2vp9codec.h" @@ -1085,6 +1086,7 @@ G_STMT_START { \ if (mpegversion == 2) { SET_META ("MPEG2"); + cdata->codec = gst_v4l2_mpeg2_get_codec (); } else { SET_META ("MPEG4"); cdata->codec = gst_v4l2_mpeg4_get_codec (); diff --git a/sys/v4l2/meson.build b/sys/v4l2/meson.build index bae955a3d6..a1222f0d94 100644 --- a/sys/v4l2/meson.build +++ b/sys/v4l2/meson.build @@ -20,6 +20,7 @@ v4l2_sources = [ 'gstv4l2h265codec.c', 'gstv4l2h265enc.c', 'gstv4l2jpegenc.c', + 'gstv4l2mpeg2codec.c', 'gstv4l2mpeg4codec.c', 'gstv4l2mpeg4enc.c', 'gstv4l2vidorient.c', -- 2.34.1