mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-23 10:11:08 +00:00
v4l2: Profile and level probing support for encoders and decoders
There used to be some profile/level support in encoders. This code was moved to GstV4l2Codecs and is now also used for decoders. The caps templates for the H.264, H.265, MPEG4, VP8 and VP9 encoders and decoders should now reflect the profiles and levels advertised by the kernel.
This commit is contained in:
parent
7bd1909f4f
commit
6ce195e9d1
32 changed files with 1166 additions and 544 deletions
|
@ -5,6 +5,7 @@ include $(top_srcdir)/common/gst-glib-gen.mak
|
|||
libgstvideo4linux2_la_SOURCES = gstv4l2.c \
|
||||
gstv4l2allocator.c \
|
||||
gstv4l2colorbalance.c \
|
||||
gstv4l2codec.c \
|
||||
gstv4l2deviceprovider.c \
|
||||
gstv4l2object.c \
|
||||
gstv4l2bufferpool.c \
|
||||
|
@ -18,11 +19,16 @@ libgstvideo4linux2_la_SOURCES = gstv4l2.c \
|
|||
gstv4l2fwhtenc.c \
|
||||
gstv4l2h263enc.c \
|
||||
gstv4l2h264enc.c \
|
||||
gstv4l2h264codec.c \
|
||||
gstv4l2h265codec.c \
|
||||
gstv4l2h265enc.c \
|
||||
gstv4l2jpegenc.c \
|
||||
gstv4l2mpeg4enc.c \
|
||||
gstv4l2mpeg4codec.c \
|
||||
gstv4l2vidorient.c \
|
||||
gstv4l2vp8codec.c \
|
||||
gstv4l2vp8enc.c \
|
||||
gstv4l2vp9codec.c \
|
||||
gstv4l2vp9enc.c \
|
||||
v4l2_calls.c \
|
||||
v4l2-utils.c \
|
||||
|
@ -64,14 +70,20 @@ noinst_HEADERS = \
|
|||
gstv4l2transform.h \
|
||||
gstv4l2videodec.h \
|
||||
gstv4l2videoenc.h \
|
||||
gstv4l2codec.h \
|
||||
gstv4l2fwhtenc.h \
|
||||
gstv4l2h264codec.h \
|
||||
gstv4l2h263enc.h \
|
||||
gstv4l2h264enc.h \
|
||||
gstv4l2h265codec.h \
|
||||
gstv4l2h265enc.h \
|
||||
gstv4l2jpegenc.h \
|
||||
gstv4l2mpeg4enc.h \
|
||||
gstv4l2mpeg4codec.h \
|
||||
gstv4l2vidorient.h \
|
||||
gstv4l2vp8codec.h \
|
||||
gstv4l2vp8enc.h \
|
||||
gstv4l2vp9codec.h \
|
||||
gstv4l2vp9enc.h \
|
||||
v4l2-utils.h \
|
||||
tuner.h \
|
||||
|
|
|
@ -192,7 +192,7 @@ gst_v4l2_probe_and_register (GstPlugin * plugin)
|
|||
|
||||
if (gst_v4l2_is_video_dec (sink_caps, src_caps)) {
|
||||
gst_v4l2_video_dec_register (plugin, basename, it->device_path,
|
||||
sink_caps, src_caps);
|
||||
video_fd, sink_caps, src_caps);
|
||||
} else if (gst_v4l2_is_video_enc (sink_caps, src_caps, NULL)) {
|
||||
if (gst_v4l2_is_fwht_enc (sink_caps, src_caps))
|
||||
gst_v4l2_fwht_enc_register (plugin, basename, it->device_path,
|
||||
|
@ -200,15 +200,15 @@ gst_v4l2_probe_and_register (GstPlugin * plugin)
|
|||
|
||||
if (gst_v4l2_is_h264_enc (sink_caps, src_caps))
|
||||
gst_v4l2_h264_enc_register (plugin, basename, it->device_path,
|
||||
sink_caps, src_caps);
|
||||
video_fd, sink_caps, src_caps);
|
||||
|
||||
if (gst_v4l2_is_h265_enc (sink_caps, src_caps))
|
||||
gst_v4l2_h265_enc_register (plugin, basename, it->device_path,
|
||||
sink_caps, src_caps);
|
||||
video_fd, sink_caps, src_caps);
|
||||
|
||||
if (gst_v4l2_is_mpeg4_enc (sink_caps, src_caps))
|
||||
gst_v4l2_mpeg4_enc_register (plugin, basename, it->device_path,
|
||||
sink_caps, src_caps);
|
||||
video_fd, sink_caps, src_caps);
|
||||
|
||||
if (gst_v4l2_is_h263_enc (sink_caps, src_caps))
|
||||
gst_v4l2_h263_enc_register (plugin, basename, it->device_path,
|
||||
|
@ -220,11 +220,11 @@ gst_v4l2_probe_and_register (GstPlugin * plugin)
|
|||
|
||||
if (gst_v4l2_is_vp8_enc (sink_caps, src_caps))
|
||||
gst_v4l2_vp8_enc_register (plugin, basename, it->device_path,
|
||||
sink_caps, src_caps);
|
||||
video_fd, sink_caps, src_caps);
|
||||
|
||||
if (gst_v4l2_is_vp9_enc (sink_caps, src_caps))
|
||||
gst_v4l2_vp9_enc_register (plugin, basename, it->device_path,
|
||||
sink_caps, src_caps);
|
||||
video_fd, sink_caps, src_caps);
|
||||
} else if (gst_v4l2_is_transform (sink_caps, src_caps)) {
|
||||
gst_v4l2_transform_register (plugin, basename, it->device_path,
|
||||
sink_caps, src_caps);
|
||||
|
|
125
sys/v4l2/gstv4l2codec.c
Normal file
125
sys/v4l2/gstv4l2codec.c
Normal file
|
@ -0,0 +1,125 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Igalia S.L.
|
||||
* Author: Philippe Normand <philn@igalia.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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "gstv4l2codec.h"
|
||||
#include "ext/videodev2.h"
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
static GValue *
|
||||
probe_controls (gint video_fd, guint32 cid,
|
||||
const gchar * (transform_control) (gint))
|
||||
{
|
||||
GValue *controls = NULL;
|
||||
struct v4l2_queryctrl query_ctrl;
|
||||
|
||||
memset (&query_ctrl, 0, sizeof (query_ctrl));
|
||||
query_ctrl.id = cid;
|
||||
|
||||
if (ioctl (video_fd, VIDIOC_QUERYCTRL, &query_ctrl) == 0) {
|
||||
if (query_ctrl.flags & V4L2_CTRL_FLAG_DISABLED) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (query_ctrl.type == V4L2_CTRL_TYPE_MENU) {
|
||||
struct v4l2_querymenu query_menu;
|
||||
|
||||
memset (&query_menu, 0, sizeof (query_menu));
|
||||
query_menu.id = query_ctrl.id;
|
||||
|
||||
controls = g_new0 (GValue, 1);
|
||||
g_value_init (controls, GST_TYPE_LIST);
|
||||
for (query_menu.index = query_ctrl.minimum;
|
||||
query_menu.index <= query_ctrl.maximum; query_menu.index++) {
|
||||
if (ioctl (video_fd, VIDIOC_QUERYMENU, &query_menu) >= 0) {
|
||||
GValue value = G_VALUE_INIT;
|
||||
|
||||
g_value_init (&value, G_TYPE_STRING);
|
||||
g_value_set_string (&value, transform_control (query_menu.index));
|
||||
gst_value_list_append_and_take_value (controls, &value);
|
||||
}
|
||||
}
|
||||
if (gst_value_list_get_size (controls) == 0) {
|
||||
g_value_unset (controls);
|
||||
controls = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return controls;
|
||||
}
|
||||
|
||||
GValue *
|
||||
gst_v4l2_codec_probe_profiles (const GstV4l2Codec * codec, gint video_fd)
|
||||
{
|
||||
return probe_controls (video_fd, codec->profile_cid,
|
||||
codec->profile_to_string);
|
||||
}
|
||||
|
||||
GValue *
|
||||
gst_v4l2_codec_probe_levels (const GstV4l2Codec * codec, gint video_fd)
|
||||
{
|
||||
GValue *controls = NULL;
|
||||
struct v4l2_queryctrl query_ctrl;
|
||||
|
||||
memset (&query_ctrl, 0, sizeof (query_ctrl));
|
||||
query_ctrl.id = codec->level_cid;
|
||||
|
||||
if (ioctl (video_fd, VIDIOC_QUERYCTRL, &query_ctrl) == 0) {
|
||||
if (query_ctrl.flags & V4L2_CTRL_FLAG_DISABLED) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (query_ctrl.type == V4L2_CTRL_TYPE_MENU) {
|
||||
struct v4l2_querymenu query_menu;
|
||||
|
||||
memset (&query_menu, 0, sizeof (query_menu));
|
||||
query_menu.id = query_ctrl.id;
|
||||
query_menu.index = query_ctrl.maximum;
|
||||
|
||||
if (ioctl (video_fd, VIDIOC_QUERYMENU, &query_menu) >= 0) {
|
||||
controls = g_new0 (GValue, 1);
|
||||
g_value_init (controls, GST_TYPE_LIST);
|
||||
|
||||
/* Assume that all levels below the highest one reported by the driver are supported. */
|
||||
for (gint32 i = query_ctrl.minimum; i <= query_ctrl.maximum; i++) {
|
||||
GValue value = G_VALUE_INIT;
|
||||
|
||||
g_value_init (&value, G_TYPE_STRING);
|
||||
g_value_set_string (&value, codec->level_to_string (i));
|
||||
gst_value_list_append_and_take_value (controls, &value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return controls;
|
||||
}
|
48
sys/v4l2/gstv4l2codec.h
Normal file
48
sys/v4l2/gstv4l2codec.h
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright (C) 2017 Collabora Inc.
|
||||
* Author: Nicolas Dufresne <nicolas.dufresne@collabora.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 __GST_V4L2_CODEC_H__
|
||||
#define __GST_V4L2_CODEC_H__
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GstV4l2Codec GstV4l2Codec;
|
||||
|
||||
struct _GstV4l2Codec {
|
||||
guint32 profile_cid;
|
||||
const gchar * (*profile_to_string) (gint v4l2_profile);
|
||||
gint (*profile_from_string) (const gchar * profile);
|
||||
|
||||
guint32 level_cid;
|
||||
const gchar * (*level_to_string) (gint v4l2_level);
|
||||
gint (*level_from_string) (const gchar * level);
|
||||
|
||||
};
|
||||
|
||||
GValue * gst_v4l2_codec_probe_profiles(const GstV4l2Codec * codec, gint video_fd);
|
||||
GValue * gst_v4l2_codec_probe_levels(const GstV4l2Codec * codec, gint video_fd);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_V4L2_CODEC_H__ */
|
|
@ -114,6 +114,6 @@ gst_v4l2_fwht_enc_register (GstPlugin * plugin, const gchar * basename,
|
|||
const gchar * device_path, GstCaps * sink_caps, GstCaps * src_caps)
|
||||
{
|
||||
gst_v4l2_video_enc_register (plugin, GST_TYPE_V4L2_FWHT_ENC,
|
||||
"fwht", basename, device_path, sink_caps,
|
||||
"fwht", basename, device_path, NULL, -1, sink_caps,
|
||||
gst_static_caps_get (&src_template_caps), src_caps);
|
||||
}
|
||||
|
|
|
@ -111,6 +111,6 @@ gst_v4l2_h263_enc_register (GstPlugin * plugin, const gchar * basename,
|
|||
const gchar * device_path, GstCaps * sink_caps, GstCaps * src_caps)
|
||||
{
|
||||
gst_v4l2_video_enc_register (plugin, GST_TYPE_V4L2_H263_ENC,
|
||||
"h263", basename, device_path, sink_caps,
|
||||
"h263", basename, device_path, NULL, -1, sink_caps,
|
||||
gst_static_caps_get (&src_template_caps), src_caps);
|
||||
}
|
||||
|
|
226
sys/v4l2/gstv4l2h264codec.c
Normal file
226
sys/v4l2/gstv4l2h264codec.c
Normal file
|
@ -0,0 +1,226 @@
|
|||
/*
|
||||
* Copyright (C) 2017 Collabora Inc.
|
||||
* Author: Nicolas Dufresne <nicolas.dufresne@collabora.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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "gstv4l2h264codec.h"
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include "ext/v4l2-controls.h"
|
||||
|
||||
|
||||
static gint
|
||||
v4l2_profile_from_string (const gchar * profile)
|
||||
{
|
||||
gint v4l2_profile = -1;
|
||||
|
||||
if (g_str_equal (profile, "baseline")) {
|
||||
v4l2_profile = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE;
|
||||
} else if (g_str_equal (profile, "constrained-baseline")) {
|
||||
v4l2_profile = V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE;
|
||||
} else if (g_str_equal (profile, "main")) {
|
||||
v4l2_profile = V4L2_MPEG_VIDEO_H264_PROFILE_MAIN;
|
||||
} else if (g_str_equal (profile, "extended")) {
|
||||
v4l2_profile = V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED;
|
||||
} else if (g_str_equal (profile, "high")) {
|
||||
v4l2_profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH;
|
||||
} else if (g_str_equal (profile, "high-10")) {
|
||||
v4l2_profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10;
|
||||
} else if (g_str_equal (profile, "high-4:2:2")) {
|
||||
v4l2_profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422;
|
||||
} else if (g_str_equal (profile, "high-4:4:4")) {
|
||||
v4l2_profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE;
|
||||
} else if (g_str_equal (profile, "high-10-intra")) {
|
||||
v4l2_profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10_INTRA;
|
||||
} else if (g_str_equal (profile, "high-4:2:2-intra")) {
|
||||
v4l2_profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422_INTRA;
|
||||
} else if (g_str_equal (profile, "high-4:4:4-intra")) {
|
||||
v4l2_profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_INTRA;
|
||||
} else if (g_str_equal (profile, "cavlc-4:4:4-intra")) {
|
||||
v4l2_profile = V4L2_MPEG_VIDEO_H264_PROFILE_CAVLC_444_INTRA;
|
||||
} else if (g_str_equal (profile, "scalable-baseline")) {
|
||||
v4l2_profile = V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_BASELINE;
|
||||
} else if (g_str_equal (profile, "scalable-high")) {
|
||||
v4l2_profile = V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_HIGH;
|
||||
} else if (g_str_equal (profile, "scalable-high-intra")) {
|
||||
v4l2_profile = V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_HIGH_INTRA;
|
||||
} else if (g_str_equal (profile, "stereo-high")) {
|
||||
v4l2_profile = V4L2_MPEG_VIDEO_H264_PROFILE_STEREO_HIGH;
|
||||
} else if (g_str_equal (profile, "multiview-high")) {
|
||||
v4l2_profile = V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH;
|
||||
} 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_H264_PROFILE_BASELINE:
|
||||
return "baseline";
|
||||
case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE:
|
||||
return "constrained-baseline";
|
||||
case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
|
||||
return "main";
|
||||
case V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED:
|
||||
return "extended";
|
||||
case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
|
||||
return "high";
|
||||
case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10:
|
||||
return "high-10";
|
||||
case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422:
|
||||
return "high-4:2:2";
|
||||
case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE:
|
||||
return "high-4:4:4";
|
||||
case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10_INTRA:
|
||||
return "high-10-intra";
|
||||
case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422_INTRA:
|
||||
return "high-4:2:2-intra";
|
||||
case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_INTRA:
|
||||
return "high-4:4:4-intra";
|
||||
case V4L2_MPEG_VIDEO_H264_PROFILE_CAVLC_444_INTRA:
|
||||
return "cavlc-4:4:4-intra";
|
||||
case V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_BASELINE:
|
||||
return "scalable-baseline";
|
||||
case V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_HIGH:
|
||||
return "scalable-high";
|
||||
case V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_HIGH_INTRA:
|
||||
return "scalable-high-intra";
|
||||
case V4L2_MPEG_VIDEO_H264_PROFILE_STEREO_HIGH:
|
||||
return "stereo-high";
|
||||
case V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH:
|
||||
return "multiview-high";
|
||||
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, "1"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_H264_LEVEL_1_0;
|
||||
else if (g_str_equal (level, "1b"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_H264_LEVEL_1B;
|
||||
else if (g_str_equal (level, "1.1"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_H264_LEVEL_1_1;
|
||||
else if (g_str_equal (level, "1.2"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_H264_LEVEL_1_2;
|
||||
else if (g_str_equal (level, "1.3"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_H264_LEVEL_1_3;
|
||||
else if (g_str_equal (level, "2"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_H264_LEVEL_2_0;
|
||||
else if (g_str_equal (level, "2.1"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_H264_LEVEL_2_1;
|
||||
else if (g_str_equal (level, "2.2"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_H264_LEVEL_2_2;
|
||||
else if (g_str_equal (level, "3"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_H264_LEVEL_3_0;
|
||||
else if (g_str_equal (level, "3.1"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_H264_LEVEL_3_1;
|
||||
else if (g_str_equal (level, "3.2"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_H264_LEVEL_3_2;
|
||||
else if (g_str_equal (level, "4"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_H264_LEVEL_4_0;
|
||||
else if (g_str_equal (level, "4.1"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_H264_LEVEL_4_1;
|
||||
else if (g_str_equal (level, "4.2"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_H264_LEVEL_4_2;
|
||||
else if (g_str_equal (level, "5"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_H264_LEVEL_5_0;
|
||||
else if (g_str_equal (level, "5.1"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_H264_LEVEL_5_1;
|
||||
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_H264_LEVEL_1_0:
|
||||
return "1";
|
||||
case V4L2_MPEG_VIDEO_H264_LEVEL_1B:
|
||||
return "1b";
|
||||
case V4L2_MPEG_VIDEO_H264_LEVEL_1_1:
|
||||
return "1.1";
|
||||
case V4L2_MPEG_VIDEO_H264_LEVEL_1_2:
|
||||
return "1.2";
|
||||
case V4L2_MPEG_VIDEO_H264_LEVEL_1_3:
|
||||
return "1.3";
|
||||
case V4L2_MPEG_VIDEO_H264_LEVEL_2_0:
|
||||
return "2";
|
||||
case V4L2_MPEG_VIDEO_H264_LEVEL_2_1:
|
||||
return "2.1";
|
||||
case V4L2_MPEG_VIDEO_H264_LEVEL_2_2:
|
||||
return "2.2";
|
||||
case V4L2_MPEG_VIDEO_H264_LEVEL_3_0:
|
||||
return "3.0";
|
||||
case V4L2_MPEG_VIDEO_H264_LEVEL_3_1:
|
||||
return "3.1";
|
||||
case V4L2_MPEG_VIDEO_H264_LEVEL_3_2:
|
||||
return "3.2";
|
||||
case V4L2_MPEG_VIDEO_H264_LEVEL_4_0:
|
||||
return "4";
|
||||
case V4L2_MPEG_VIDEO_H264_LEVEL_4_1:
|
||||
return "4.1";
|
||||
case V4L2_MPEG_VIDEO_H264_LEVEL_4_2:
|
||||
return "4.2";
|
||||
case V4L2_MPEG_VIDEO_H264_LEVEL_5_0:
|
||||
return "5";
|
||||
case V4L2_MPEG_VIDEO_H264_LEVEL_5_1:
|
||||
return "5.1";
|
||||
default:
|
||||
GST_WARNING ("Unsupported V4L2 level %i", v4l2_level);
|
||||
break;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const GstV4l2Codec *
|
||||
gst_v4l2_h264_get_codec (void)
|
||||
{
|
||||
static GstV4l2Codec *codec = NULL;
|
||||
if (g_once_init_enter (&codec)) {
|
||||
static GstV4l2Codec c;
|
||||
c.profile_cid = V4L2_CID_MPEG_VIDEO_H264_PROFILE;
|
||||
c.profile_to_string = v4l2_profile_to_string;
|
||||
c.profile_from_string = v4l2_profile_from_string;
|
||||
c.level_cid = V4L2_CID_MPEG_VIDEO_H264_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;
|
||||
}
|
34
sys/v4l2/gstv4l2h264codec.h
Normal file
34
sys/v4l2/gstv4l2h264codec.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright (C) 2014 SUMOMO Computer Association.
|
||||
* Author: ayaka <ayaka@soulik.info>
|
||||
* Factored out from gstv4l2h264enc by Philippe Normand <philn@igalia.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 __GST_V4L2_H264_CODEC_H__
|
||||
#define __GST_V4L2_H264_CODEC_H__
|
||||
|
||||
#include "gstv4l2codec.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
const GstV4l2Codec * gst_v4l2_h264_get_codec (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif
|
|
@ -31,6 +31,7 @@
|
|||
|
||||
#include "gstv4l2object.h"
|
||||
#include "gstv4l2h264enc.h"
|
||||
#include "gstv4l2h264codec.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <gst/gst-i18n-plugin.h>
|
||||
|
@ -88,185 +89,6 @@ gst_v4l2_h264_enc_get_property (GObject * object,
|
|||
/* TODO */
|
||||
}
|
||||
|
||||
static gint
|
||||
v4l2_profile_from_string (const gchar * profile)
|
||||
{
|
||||
gint v4l2_profile = -1;
|
||||
|
||||
if (g_str_equal (profile, "baseline")) {
|
||||
v4l2_profile = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE;
|
||||
} else if (g_str_equal (profile, "constrained-baseline")) {
|
||||
v4l2_profile = V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE;
|
||||
} else if (g_str_equal (profile, "main")) {
|
||||
v4l2_profile = V4L2_MPEG_VIDEO_H264_PROFILE_MAIN;
|
||||
} else if (g_str_equal (profile, "extended")) {
|
||||
v4l2_profile = V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED;
|
||||
} else if (g_str_equal (profile, "high")) {
|
||||
v4l2_profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH;
|
||||
} else if (g_str_equal (profile, "high-10")) {
|
||||
v4l2_profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10;
|
||||
} else if (g_str_equal (profile, "high-4:2:2")) {
|
||||
v4l2_profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422;
|
||||
} else if (g_str_equal (profile, "high-4:4:4")) {
|
||||
v4l2_profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE;
|
||||
} else if (g_str_equal (profile, "high-10-intra")) {
|
||||
v4l2_profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10_INTRA;
|
||||
} else if (g_str_equal (profile, "high-4:2:2-intra")) {
|
||||
v4l2_profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422_INTRA;
|
||||
} else if (g_str_equal (profile, "high-4:4:4-intra")) {
|
||||
v4l2_profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_INTRA;
|
||||
} else if (g_str_equal (profile, "cavlc-4:4:4-intra")) {
|
||||
v4l2_profile = V4L2_MPEG_VIDEO_H264_PROFILE_CAVLC_444_INTRA;
|
||||
} else if (g_str_equal (profile, "scalable-baseline")) {
|
||||
v4l2_profile = V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_BASELINE;
|
||||
} else if (g_str_equal (profile, "scalable-high")) {
|
||||
v4l2_profile = V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_HIGH;
|
||||
} else if (g_str_equal (profile, "scalable-high-intra")) {
|
||||
v4l2_profile = V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_HIGH_INTRA;
|
||||
} else if (g_str_equal (profile, "stereo-high")) {
|
||||
v4l2_profile = V4L2_MPEG_VIDEO_H264_PROFILE_STEREO_HIGH;
|
||||
} else if (g_str_equal (profile, "multiview-high")) {
|
||||
v4l2_profile = V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH;
|
||||
} 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_H264_PROFILE_BASELINE:
|
||||
return "baseline";
|
||||
case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE:
|
||||
return "constrained-baseline";
|
||||
case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
|
||||
return "main";
|
||||
case V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED:
|
||||
return "extended";
|
||||
case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
|
||||
return "high";
|
||||
case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10:
|
||||
return "high-10";
|
||||
case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422:
|
||||
return "high-4:2:2";
|
||||
case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE:
|
||||
return "high-4:4:4";
|
||||
case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10_INTRA:
|
||||
return "high-10-intra";
|
||||
case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422_INTRA:
|
||||
return "high-4:2:2-intra";
|
||||
case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_INTRA:
|
||||
return "high-4:4:4-intra";
|
||||
case V4L2_MPEG_VIDEO_H264_PROFILE_CAVLC_444_INTRA:
|
||||
return "cavlc-4:4:4-intra";
|
||||
case V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_BASELINE:
|
||||
return "scalable-baseline";
|
||||
case V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_HIGH:
|
||||
return "scalable-high";
|
||||
case V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_HIGH_INTRA:
|
||||
return "scalable-high-intra";
|
||||
case V4L2_MPEG_VIDEO_H264_PROFILE_STEREO_HIGH:
|
||||
return "stereo-high";
|
||||
case V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH:
|
||||
return "multiview-high";
|
||||
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, "1"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_H264_LEVEL_1_0;
|
||||
else if (g_str_equal (level, "1b"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_H264_LEVEL_1B;
|
||||
else if (g_str_equal (level, "1.1"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_H264_LEVEL_1_1;
|
||||
else if (g_str_equal (level, "1.2"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_H264_LEVEL_1_2;
|
||||
else if (g_str_equal (level, "1.3"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_H264_LEVEL_1_3;
|
||||
else if (g_str_equal (level, "2"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_H264_LEVEL_2_0;
|
||||
else if (g_str_equal (level, "2.1"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_H264_LEVEL_2_1;
|
||||
else if (g_str_equal (level, "2.2"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_H264_LEVEL_2_2;
|
||||
else if (g_str_equal (level, "3"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_H264_LEVEL_3_0;
|
||||
else if (g_str_equal (level, "3.1"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_H264_LEVEL_3_1;
|
||||
else if (g_str_equal (level, "3.2"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_H264_LEVEL_3_2;
|
||||
else if (g_str_equal (level, "4"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_H264_LEVEL_4_0;
|
||||
else if (g_str_equal (level, "4.1"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_H264_LEVEL_4_1;
|
||||
else if (g_str_equal (level, "4.2"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_H264_LEVEL_4_2;
|
||||
else if (g_str_equal (level, "5"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_H264_LEVEL_5_0;
|
||||
else if (g_str_equal (level, "5.1"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_H264_LEVEL_5_1;
|
||||
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_H264_LEVEL_1_0:
|
||||
return "1";
|
||||
case V4L2_MPEG_VIDEO_H264_LEVEL_1B:
|
||||
return "1b";
|
||||
case V4L2_MPEG_VIDEO_H264_LEVEL_1_1:
|
||||
return "1.1";
|
||||
case V4L2_MPEG_VIDEO_H264_LEVEL_1_2:
|
||||
return "1.2";
|
||||
case V4L2_MPEG_VIDEO_H264_LEVEL_1_3:
|
||||
return "1.3";
|
||||
case V4L2_MPEG_VIDEO_H264_LEVEL_2_0:
|
||||
return "2";
|
||||
case V4L2_MPEG_VIDEO_H264_LEVEL_2_1:
|
||||
return "2.1";
|
||||
case V4L2_MPEG_VIDEO_H264_LEVEL_2_2:
|
||||
return "2.2";
|
||||
case V4L2_MPEG_VIDEO_H264_LEVEL_3_0:
|
||||
return "3.0";
|
||||
case V4L2_MPEG_VIDEO_H264_LEVEL_3_1:
|
||||
return "3.1";
|
||||
case V4L2_MPEG_VIDEO_H264_LEVEL_3_2:
|
||||
return "3.2";
|
||||
case V4L2_MPEG_VIDEO_H264_LEVEL_4_0:
|
||||
return "4";
|
||||
case V4L2_MPEG_VIDEO_H264_LEVEL_4_1:
|
||||
return "4.1";
|
||||
case V4L2_MPEG_VIDEO_H264_LEVEL_4_2:
|
||||
return "4.2";
|
||||
case V4L2_MPEG_VIDEO_H264_LEVEL_5_0:
|
||||
return "5";
|
||||
case V4L2_MPEG_VIDEO_H264_LEVEL_5_1:
|
||||
return "5.1";
|
||||
default:
|
||||
GST_WARNING ("Unsupported V4L2 level %i", v4l2_level);
|
||||
break;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_v4l2_h264_enc_init (GstV4l2H264Enc * self)
|
||||
{
|
||||
|
@ -299,12 +121,6 @@ gst_v4l2_h264_enc_class_init (GstV4l2H264EncClass * klass)
|
|||
GST_DEBUG_FUNCPTR (gst_v4l2_h264_enc_get_property);
|
||||
|
||||
baseclass->codec_name = "H264";
|
||||
baseclass->profile_cid = V4L2_CID_MPEG_VIDEO_H264_PROFILE;
|
||||
baseclass->profile_to_string = v4l2_profile_to_string;
|
||||
baseclass->profile_from_string = v4l2_profile_from_string;
|
||||
baseclass->level_cid = V4L2_CID_MPEG_VIDEO_H264_LEVEL;
|
||||
baseclass->level_to_string = v4l2_level_to_string;
|
||||
baseclass->level_from_string = v4l2_level_from_string;
|
||||
}
|
||||
|
||||
/* Probing functions */
|
||||
|
@ -317,9 +133,11 @@ gst_v4l2_is_h264_enc (GstCaps * sink_caps, GstCaps * src_caps)
|
|||
|
||||
void
|
||||
gst_v4l2_h264_enc_register (GstPlugin * plugin, const gchar * basename,
|
||||
const gchar * device_path, GstCaps * sink_caps, GstCaps * src_caps)
|
||||
const gchar * device_path, gint video_fd, GstCaps * sink_caps,
|
||||
GstCaps * src_caps)
|
||||
{
|
||||
const GstV4l2Codec *codec = gst_v4l2_h264_get_codec ();
|
||||
gst_v4l2_video_enc_register (plugin, GST_TYPE_V4L2_H264_ENC,
|
||||
"h264", basename, device_path, sink_caps,
|
||||
"h264", basename, device_path, codec, video_fd, sink_caps,
|
||||
gst_static_caps_get (&src_template_caps), src_caps);
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ GType gst_v4l2_h264_enc_get_type (void);
|
|||
gboolean gst_v4l2_is_h264_enc (GstCaps * sink_caps, GstCaps * src_caps);
|
||||
|
||||
void gst_v4l2_h264_enc_register (GstPlugin * plugin, const gchar * basename,
|
||||
const gchar * device_path, GstCaps * sink_caps, GstCaps * src_caps);
|
||||
const gchar * device_path, gint video_fd, GstCaps * sink_caps, GstCaps * src_caps);
|
||||
|
||||
G_END_DECLS
|
||||
#endif /* __GST_V4L2_H264_ENC_H__ */
|
||||
|
|
158
sys/v4l2/gstv4l2h265codec.c
Normal file
158
sys/v4l2/gstv4l2h265codec.c
Normal file
|
@ -0,0 +1,158 @@
|
|||
/*
|
||||
* Copyright (C) 2018 NVIDIA CORPORATION.
|
||||
* Author: Amit Pandya <apandya@nvidia.com>
|
||||
* Factored out from gstv4l2h264enc by Philippe Normand <philn@igalia.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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "gstv4l2h265codec.h"
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include "ext/v4l2-controls.h"
|
||||
|
||||
|
||||
static gint
|
||||
v4l2_profile_from_string (const gchar * profile)
|
||||
{
|
||||
gint v4l2_profile = -1;
|
||||
|
||||
if (g_str_equal (profile, "main")) {
|
||||
v4l2_profile = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN;
|
||||
} else if (g_str_equal (profile, "mainstillpicture")) {
|
||||
v4l2_profile = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE;
|
||||
} else if (g_str_equal (profile, "main10")) {
|
||||
v4l2_profile = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10;
|
||||
} 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_HEVC_PROFILE_MAIN:
|
||||
return "main";
|
||||
case V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE:
|
||||
return "mainstillpicture";
|
||||
case V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10:
|
||||
return "main10";
|
||||
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, "1"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_HEVC_LEVEL_1;
|
||||
else if (g_str_equal (level, "2"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_HEVC_LEVEL_2;
|
||||
else if (g_str_equal (level, "2.1"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_HEVC_LEVEL_2_1;
|
||||
else if (g_str_equal (level, "3"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_HEVC_LEVEL_3;
|
||||
else if (g_str_equal (level, "3.1"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_HEVC_LEVEL_3_1;
|
||||
else if (g_str_equal (level, "4"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_HEVC_LEVEL_4;
|
||||
else if (g_str_equal (level, "4.1"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1;
|
||||
else if (g_str_equal (level, "5"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_HEVC_LEVEL_5;
|
||||
else if (g_str_equal (level, "5.1"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1;
|
||||
else if (g_str_equal (level, "5.2"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_HEVC_LEVEL_5_2;
|
||||
else if (g_str_equal (level, "6"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_HEVC_LEVEL_6;
|
||||
else if (g_str_equal (level, "6.1"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_HEVC_LEVEL_6_1;
|
||||
else if (g_str_equal (level, "6.2"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2;
|
||||
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_HEVC_LEVEL_1:
|
||||
return "1";
|
||||
case V4L2_MPEG_VIDEO_HEVC_LEVEL_2:
|
||||
return "2";
|
||||
case V4L2_MPEG_VIDEO_HEVC_LEVEL_2_1:
|
||||
return "2.1";
|
||||
case V4L2_MPEG_VIDEO_HEVC_LEVEL_3:
|
||||
return "3";
|
||||
case V4L2_MPEG_VIDEO_HEVC_LEVEL_3_1:
|
||||
return "3.1";
|
||||
case V4L2_MPEG_VIDEO_HEVC_LEVEL_4:
|
||||
return "4";
|
||||
case V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1:
|
||||
return "4.1";
|
||||
case V4L2_MPEG_VIDEO_HEVC_LEVEL_5:
|
||||
return "5";
|
||||
case V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1:
|
||||
return "5.1";
|
||||
case V4L2_MPEG_VIDEO_HEVC_LEVEL_5_2:
|
||||
return "5.2";
|
||||
case V4L2_MPEG_VIDEO_HEVC_LEVEL_6:
|
||||
return "6";
|
||||
case V4L2_MPEG_VIDEO_HEVC_LEVEL_6_1:
|
||||
return "6.1";
|
||||
case V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2:
|
||||
return "6.2";
|
||||
default:
|
||||
GST_WARNING ("Unsupported V4L2 level %i", v4l2_level);
|
||||
break;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const GstV4l2Codec *
|
||||
gst_v4l2_h265_get_codec (void)
|
||||
{
|
||||
static GstV4l2Codec *codec = NULL;
|
||||
if (g_once_init_enter (&codec)) {
|
||||
static GstV4l2Codec c;
|
||||
c.profile_cid = V4L2_CID_MPEG_VIDEO_HEVC_PROFILE;
|
||||
c.profile_to_string = v4l2_profile_to_string;
|
||||
c.profile_from_string = v4l2_profile_from_string;
|
||||
c.level_cid = V4L2_CID_MPEG_VIDEO_HEVC_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;
|
||||
}
|
34
sys/v4l2/gstv4l2h265codec.h
Normal file
34
sys/v4l2/gstv4l2h265codec.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright (C) 2018 NVIDIA CORPORATION.
|
||||
* Author: Amit Pandya <apandya@nvidia.com>
|
||||
* Factored out from gstv4l2h264enc by Philippe Normand <philn@igalia.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 __GST_V4L2_H265_CODEC_H__
|
||||
#define __GST_V4L2_H265_CODEC_H__
|
||||
|
||||
#include "gstv4l2codec.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
const GstV4l2Codec * gst_v4l2_h265_get_codec (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif
|
|
@ -31,6 +31,7 @@
|
|||
|
||||
#include "gstv4l2object.h"
|
||||
#include "gstv4l2h265enc.h"
|
||||
#include "gstv4l2h265codec.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <gst/gst-i18n-plugin.h>
|
||||
|
@ -66,116 +67,6 @@ gst_v4l2_h265_enc_get_property (GObject * object,
|
|||
/* TODO */
|
||||
}
|
||||
|
||||
static gint
|
||||
v4l2_profile_from_string (const gchar * profile)
|
||||
{
|
||||
gint v4l2_profile = -1;
|
||||
|
||||
if (g_str_equal (profile, "main")) {
|
||||
v4l2_profile = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN;
|
||||
} else if (g_str_equal (profile, "mainstillpicture")) {
|
||||
v4l2_profile = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE;
|
||||
} else if (g_str_equal (profile, "main10")) {
|
||||
v4l2_profile = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10;
|
||||
} 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_HEVC_PROFILE_MAIN:
|
||||
return "main";
|
||||
case V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE:
|
||||
return "mainstillpicture";
|
||||
case V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10:
|
||||
return "main10";
|
||||
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, "1"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_HEVC_LEVEL_1;
|
||||
else if (g_str_equal (level, "2"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_HEVC_LEVEL_2;
|
||||
else if (g_str_equal (level, "2.1"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_HEVC_LEVEL_2_1;
|
||||
else if (g_str_equal (level, "3"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_HEVC_LEVEL_3;
|
||||
else if (g_str_equal (level, "3.1"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_HEVC_LEVEL_3_1;
|
||||
else if (g_str_equal (level, "4"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_HEVC_LEVEL_4;
|
||||
else if (g_str_equal (level, "4.1"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1;
|
||||
else if (g_str_equal (level, "5"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_HEVC_LEVEL_5;
|
||||
else if (g_str_equal (level, "5.1"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1;
|
||||
else if (g_str_equal (level, "5.2"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_HEVC_LEVEL_5_2;
|
||||
else if (g_str_equal (level, "6"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_HEVC_LEVEL_6;
|
||||
else if (g_str_equal (level, "6.1"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_HEVC_LEVEL_6_1;
|
||||
else if (g_str_equal (level, "6.2"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2;
|
||||
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_HEVC_LEVEL_1:
|
||||
return "1";
|
||||
case V4L2_MPEG_VIDEO_HEVC_LEVEL_2:
|
||||
return "2";
|
||||
case V4L2_MPEG_VIDEO_HEVC_LEVEL_2_1:
|
||||
return "2.1";
|
||||
case V4L2_MPEG_VIDEO_HEVC_LEVEL_3:
|
||||
return "3";
|
||||
case V4L2_MPEG_VIDEO_HEVC_LEVEL_3_1:
|
||||
return "3.1";
|
||||
case V4L2_MPEG_VIDEO_HEVC_LEVEL_4:
|
||||
return "4";
|
||||
case V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1:
|
||||
return "4.1";
|
||||
case V4L2_MPEG_VIDEO_HEVC_LEVEL_5:
|
||||
return "5";
|
||||
case V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1:
|
||||
return "5.1";
|
||||
case V4L2_MPEG_VIDEO_HEVC_LEVEL_5_2:
|
||||
return "5.2";
|
||||
case V4L2_MPEG_VIDEO_HEVC_LEVEL_6:
|
||||
return "6";
|
||||
case V4L2_MPEG_VIDEO_HEVC_LEVEL_6_1:
|
||||
return "6.1";
|
||||
case V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2:
|
||||
return "6.2";
|
||||
default:
|
||||
GST_WARNING ("Unsupported V4L2 level %i", v4l2_level);
|
||||
break;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_v4l2_h265_enc_init (GstV4l2H265Enc * self)
|
||||
{
|
||||
|
@ -209,12 +100,6 @@ gst_v4l2_h265_enc_class_init (GstV4l2H265EncClass * klass)
|
|||
GST_DEBUG_FUNCPTR (gst_v4l2_h265_enc_get_property);
|
||||
|
||||
baseclass->codec_name = "H265";
|
||||
baseclass->profile_cid = V4L2_CID_MPEG_VIDEO_HEVC_PROFILE;
|
||||
baseclass->profile_to_string = v4l2_profile_to_string;
|
||||
baseclass->profile_from_string = v4l2_profile_from_string;
|
||||
baseclass->level_cid = V4L2_CID_MPEG_VIDEO_HEVC_LEVEL;
|
||||
baseclass->level_to_string = v4l2_level_to_string;
|
||||
baseclass->level_from_string = v4l2_level_from_string;
|
||||
}
|
||||
|
||||
/* Probing functions */
|
||||
|
@ -227,9 +112,11 @@ gst_v4l2_is_h265_enc (GstCaps * sink_caps, GstCaps * src_caps)
|
|||
|
||||
void
|
||||
gst_v4l2_h265_enc_register (GstPlugin * plugin, const gchar * basename,
|
||||
const gchar * device_path, GstCaps * sink_caps, GstCaps * src_caps)
|
||||
const gchar * device_path, gint video_fd, GstCaps * sink_caps,
|
||||
GstCaps * src_caps)
|
||||
{
|
||||
const GstV4l2Codec *codec = gst_v4l2_h265_get_codec ();
|
||||
gst_v4l2_video_enc_register (plugin, GST_TYPE_V4L2_H265_ENC,
|
||||
"h265", basename, device_path, sink_caps,
|
||||
"h265", basename, device_path, codec, video_fd, sink_caps,
|
||||
gst_static_caps_get (&src_template_caps), src_caps);
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ GType gst_v4l2_h265_enc_get_type (void);
|
|||
gboolean gst_v4l2_is_h265_enc (GstCaps * sink_caps, GstCaps * src_caps);
|
||||
|
||||
void gst_v4l2_h265_enc_register (GstPlugin * plugin, const gchar * basename,
|
||||
const gchar * device_path, GstCaps * sink_caps, GstCaps * src_caps);
|
||||
const gchar * device_path, gint video_fd, GstCaps * sink_caps, GstCaps * src_caps);
|
||||
|
||||
G_END_DECLS
|
||||
#endif /* __GST_V4L2_H265_ENC_H__ */
|
||||
|
|
|
@ -114,6 +114,6 @@ gst_v4l2_jpeg_enc_register (GstPlugin * plugin, const gchar * basename,
|
|||
const gchar * device_path, GstCaps * sink_caps, GstCaps * src_caps)
|
||||
{
|
||||
gst_v4l2_video_enc_register (plugin, GST_TYPE_V4L2_JPEG_ENC,
|
||||
"jpeg", basename, device_path, sink_caps,
|
||||
"jpeg", basename, device_path, NULL, -1, sink_caps,
|
||||
gst_static_caps_get (&src_template_caps), src_caps);
|
||||
}
|
||||
|
|
141
sys/v4l2/gstv4l2mpeg4codec.c
Normal file
141
sys/v4l2/gstv4l2mpeg4codec.c
Normal file
|
@ -0,0 +1,141 @@
|
|||
/*
|
||||
* Copyright (C) 2017 Collabora Inc.
|
||||
* Author: Nicolas Dufresne <nicolas.dufresne@collabora.com>
|
||||
* Factored out from gstv4l2mpeg4enc by Philippe Normand <philn@igalia.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 "gstv4l2mpeg4codec.h"
|
||||
|
||||
#include <gst/gst.h>
|
||||
#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_MPEG4_PROFILE_SIMPLE;
|
||||
else if (g_str_equal (profile, "advanced-simple"))
|
||||
v4l2_profile = V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE;
|
||||
else if (g_str_equal (profile, "core"))
|
||||
v4l2_profile = V4L2_MPEG_VIDEO_MPEG4_PROFILE_CORE;
|
||||
else if (g_str_equal (profile, "simple-scalable"))
|
||||
v4l2_profile = V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE_SCALABLE;
|
||||
else if (g_str_equal (profile, "advanced-coding-efficiency"))
|
||||
v4l2_profile = V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_CODING_EFFICIENCY;
|
||||
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_MPEG4_PROFILE_SIMPLE:
|
||||
return "simple";
|
||||
case V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE:
|
||||
return "advanced-simple";
|
||||
case V4L2_MPEG_VIDEO_MPEG4_PROFILE_CORE:
|
||||
return "core";
|
||||
case V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE_SCALABLE:
|
||||
return "simple-scalable";
|
||||
case V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_CODING_EFFICIENCY:
|
||||
return "advanced-coding-efficiency";
|
||||
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, "0"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_0;
|
||||
else if (g_str_equal (level, "0b"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B;
|
||||
else if (g_str_equal (level, "1"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_1;
|
||||
else if (g_str_equal (level, "2"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_2;
|
||||
else if (g_str_equal (level, "3"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_3;
|
||||
else if (g_str_equal (level, "3b"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_3B;
|
||||
else if (g_str_equal (level, "4"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_4;
|
||||
else if (g_str_equal (level, "5"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
|
||||
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_MPEG4_LEVEL_0:
|
||||
return "0";
|
||||
case V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B:
|
||||
return "0b";
|
||||
case V4L2_MPEG_VIDEO_MPEG4_LEVEL_1:
|
||||
return "1";
|
||||
case V4L2_MPEG_VIDEO_MPEG4_LEVEL_2:
|
||||
return "2";
|
||||
case V4L2_MPEG_VIDEO_MPEG4_LEVEL_3:
|
||||
return "3";
|
||||
case V4L2_MPEG_VIDEO_MPEG4_LEVEL_3B:
|
||||
return "3b";
|
||||
case V4L2_MPEG_VIDEO_MPEG4_LEVEL_4:
|
||||
return "4";
|
||||
case V4L2_MPEG_VIDEO_MPEG4_LEVEL_5:
|
||||
return "5";
|
||||
default:
|
||||
GST_WARNING ("Unsupported V4L2 level %i", v4l2_level);
|
||||
break;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const GstV4l2Codec *
|
||||
gst_v4l2_mpeg4_get_codec (void)
|
||||
{
|
||||
static GstV4l2Codec *codec = NULL;
|
||||
if (g_once_init_enter (&codec)) {
|
||||
static GstV4l2Codec c;
|
||||
c.profile_cid = V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE;
|
||||
c.profile_to_string = v4l2_profile_to_string;
|
||||
c.profile_from_string = v4l2_profile_from_string;
|
||||
c.level_cid = V4L2_CID_MPEG_VIDEO_MPEG4_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;
|
||||
}
|
34
sys/v4l2/gstv4l2mpeg4codec.h
Normal file
34
sys/v4l2/gstv4l2mpeg4codec.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright (C) 2017 Collabora Inc.
|
||||
* Author: Nicolas Dufresne <nicolas.dufresne@collabora.com>
|
||||
* Factored out from gstv4l2mpeg4enc by Philippe Normand <philn@igalia.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 __GST_V4L2_MPEG4_CODEC_H__
|
||||
#define __GST_V4L2_MPEG4_CODEC_H__
|
||||
|
||||
#include "gstv4l2codec.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
const GstV4l2Codec * gst_v4l2_mpeg4_get_codec (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif
|
|
@ -31,6 +31,7 @@
|
|||
|
||||
#include "gstv4l2object.h"
|
||||
#include "gstv4l2mpeg4enc.h"
|
||||
#include "gstv4l2mpeg4codec.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <gst/gst-i18n-plugin.h>
|
||||
|
@ -65,104 +66,6 @@ gst_v4l2_mpeg4_enc_get_property (GObject * object,
|
|||
/* TODO */
|
||||
}
|
||||
|
||||
static gint
|
||||
v4l2_profile_from_string (const gchar * profile)
|
||||
{
|
||||
gint v4l2_profile = -1;
|
||||
|
||||
if (g_str_equal (profile, "simple"))
|
||||
v4l2_profile = V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE;
|
||||
else if (g_str_equal (profile, "advanced-simple"))
|
||||
v4l2_profile = V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE;
|
||||
else if (g_str_equal (profile, "core"))
|
||||
v4l2_profile = V4L2_MPEG_VIDEO_MPEG4_PROFILE_CORE;
|
||||
else if (g_str_equal (profile, "simple-scalable"))
|
||||
v4l2_profile = V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE_SCALABLE;
|
||||
else if (g_str_equal (profile, "advanced-coding-efficiency"))
|
||||
v4l2_profile = V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_CODING_EFFICIENCY;
|
||||
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_MPEG4_PROFILE_SIMPLE:
|
||||
return "simple";
|
||||
case V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE:
|
||||
return "advanced-simple";
|
||||
case V4L2_MPEG_VIDEO_MPEG4_PROFILE_CORE:
|
||||
return "core";
|
||||
case V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE_SCALABLE:
|
||||
return "simple-scalable";
|
||||
case V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_CODING_EFFICIENCY:
|
||||
return "advanced-coding-efficiency";
|
||||
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, "0"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_0;
|
||||
else if (g_str_equal (level, "0b"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B;
|
||||
else if (g_str_equal (level, "1"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_1;
|
||||
else if (g_str_equal (level, "2"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_2;
|
||||
else if (g_str_equal (level, "3"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_3;
|
||||
else if (g_str_equal (level, "3b"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_3B;
|
||||
else if (g_str_equal (level, "4"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_4;
|
||||
else if (g_str_equal (level, "5"))
|
||||
v4l2_level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
|
||||
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_MPEG4_LEVEL_0:
|
||||
return "0";
|
||||
case V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B:
|
||||
return "0b";
|
||||
case V4L2_MPEG_VIDEO_MPEG4_LEVEL_1:
|
||||
return "1";
|
||||
case V4L2_MPEG_VIDEO_MPEG4_LEVEL_2:
|
||||
return "2";
|
||||
case V4L2_MPEG_VIDEO_MPEG4_LEVEL_3:
|
||||
return "3";
|
||||
case V4L2_MPEG_VIDEO_MPEG4_LEVEL_3B:
|
||||
return "3b";
|
||||
case V4L2_MPEG_VIDEO_MPEG4_LEVEL_4:
|
||||
return "4";
|
||||
case V4L2_MPEG_VIDEO_MPEG4_LEVEL_5:
|
||||
return "5";
|
||||
default:
|
||||
GST_WARNING ("Unsupported V4L2 level %i", v4l2_level);
|
||||
break;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_v4l2_mpeg4_enc_init (GstV4l2Mpeg4Enc * self)
|
||||
{
|
||||
|
@ -196,12 +99,6 @@ gst_v4l2_mpeg4_enc_class_init (GstV4l2Mpeg4EncClass * klass)
|
|||
GST_DEBUG_FUNCPTR (gst_v4l2_mpeg4_enc_get_property);
|
||||
|
||||
baseclass->codec_name = "MPEG4";
|
||||
baseclass->profile_cid = V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE;
|
||||
baseclass->profile_to_string = v4l2_profile_to_string;
|
||||
baseclass->profile_from_string = v4l2_profile_from_string;
|
||||
baseclass->level_cid = V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL;
|
||||
baseclass->level_to_string = v4l2_level_to_string;
|
||||
baseclass->level_from_string = v4l2_level_from_string;
|
||||
}
|
||||
|
||||
/* Probing functions */
|
||||
|
@ -214,9 +111,11 @@ gst_v4l2_is_mpeg4_enc (GstCaps * sink_caps, GstCaps * src_caps)
|
|||
|
||||
void
|
||||
gst_v4l2_mpeg4_enc_register (GstPlugin * plugin, const gchar * basename,
|
||||
const gchar * device_path, GstCaps * sink_caps, GstCaps * src_caps)
|
||||
const gchar * device_path, gint video_fd, GstCaps * sink_caps,
|
||||
GstCaps * src_caps)
|
||||
{
|
||||
const GstV4l2Codec *codec = gst_v4l2_mpeg4_get_codec ();
|
||||
gst_v4l2_video_enc_register (plugin, GST_TYPE_V4L2_MPEG4_ENC,
|
||||
"mpeg4", basename, device_path, sink_caps,
|
||||
"mpeg4", basename, device_path, codec, video_fd, sink_caps,
|
||||
gst_static_caps_get (&src_template_caps), src_caps);
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ GType gst_v4l2_mpeg4_enc_get_type (void);
|
|||
gboolean gst_v4l2_is_mpeg4_enc (GstCaps * sink_caps, GstCaps * src_caps);
|
||||
|
||||
void gst_v4l2_mpeg4_enc_register (GstPlugin * plugin, const gchar * basename,
|
||||
const gchar * device_path, GstCaps * sink_caps, GstCaps * src_caps);
|
||||
const gchar * device_path, gint video_fd, GstCaps * sink_caps, GstCaps * src_caps);
|
||||
|
||||
G_END_DECLS
|
||||
#endif /* __GST_V4L2_MPEG4_ENC_H__ */
|
||||
|
|
|
@ -32,6 +32,12 @@
|
|||
#include "gstv4l2object.h"
|
||||
#include "gstv4l2videodec.h"
|
||||
|
||||
#include "gstv4l2h264codec.h"
|
||||
#include "gstv4l2h265codec.h"
|
||||
#include "gstv4l2mpeg4codec.h"
|
||||
#include "gstv4l2vp8codec.h"
|
||||
#include "gstv4l2vp9codec.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <gst/gst-i18n-plugin.h>
|
||||
|
||||
|
@ -45,6 +51,7 @@ typedef struct
|
|||
GstCaps *src_caps;
|
||||
const gchar *longname;
|
||||
const gchar *description;
|
||||
const GstV4l2Codec *codec;
|
||||
} GstV4l2VideoDecCData;
|
||||
|
||||
enum
|
||||
|
@ -1081,6 +1088,7 @@ G_STMT_START { \
|
|||
SET_META ("MPEG2");
|
||||
} else {
|
||||
SET_META ("MPEG4");
|
||||
cdata->codec = gst_v4l2_mpeg4_get_codec ();
|
||||
}
|
||||
} else if (gst_structure_has_name (s, "video/x-h263")) {
|
||||
SET_META ("H263");
|
||||
|
@ -1088,14 +1096,18 @@ G_STMT_START { \
|
|||
SET_META ("FWHT");
|
||||
} else if (gst_structure_has_name (s, "video/x-h264")) {
|
||||
SET_META ("H264");
|
||||
cdata->codec = gst_v4l2_h264_get_codec ();
|
||||
} else if (gst_structure_has_name (s, "video/x-h265")) {
|
||||
SET_META ("H265");
|
||||
cdata->codec = gst_v4l2_h265_get_codec ();
|
||||
} else if (gst_structure_has_name (s, "video/x-wmv")) {
|
||||
SET_META ("VC1");
|
||||
} else if (gst_structure_has_name (s, "video/x-vp8")) {
|
||||
SET_META ("VP8");
|
||||
cdata->codec = gst_v4l2_vp8_get_codec ();
|
||||
} else if (gst_structure_has_name (s, "video/x-vp9")) {
|
||||
SET_META ("VP9");
|
||||
cdata->codec = gst_v4l2_vp9_get_codec ();
|
||||
} else if (gst_structure_has_name (s, "video/x-bayer")) {
|
||||
SET_META ("BAYER");
|
||||
} else if (gst_structure_has_name (s, "video/x-sonix")) {
|
||||
|
@ -1130,7 +1142,8 @@ G_STMT_START { \
|
|||
|
||||
void
|
||||
gst_v4l2_video_dec_register (GstPlugin * plugin, const gchar * basename,
|
||||
const gchar * device_path, GstCaps * sink_caps, GstCaps * src_caps)
|
||||
const gchar * device_path, gint video_fd, GstCaps * sink_caps,
|
||||
GstCaps * src_caps)
|
||||
{
|
||||
gint i;
|
||||
|
||||
|
@ -1157,6 +1170,20 @@ gst_v4l2_video_dec_register (GstPlugin * plugin, const gchar * basename,
|
|||
continue;
|
||||
}
|
||||
|
||||
if (cdata->codec != NULL) {
|
||||
GValue *value = gst_v4l2_codec_probe_levels (cdata->codec, video_fd);
|
||||
if (value != NULL) {
|
||||
gst_caps_set_value (cdata->sink_caps, "level", value);
|
||||
g_value_unset (value);
|
||||
}
|
||||
|
||||
value = gst_v4l2_codec_probe_profiles (cdata->codec, video_fd);
|
||||
if (value != NULL) {
|
||||
gst_caps_set_value (cdata->sink_caps, "profile", value);
|
||||
g_value_unset (value);
|
||||
}
|
||||
}
|
||||
|
||||
type = gst_v4l2_video_dec_get_type ();
|
||||
g_type_query (type, &type_query);
|
||||
memset (&type_info, 0, sizeof (type_info));
|
||||
|
|
|
@ -76,7 +76,7 @@ GType gst_v4l2_video_dec_get_type (void);
|
|||
gboolean gst_v4l2_is_video_dec (GstCaps * sink_caps, GstCaps * src_caps);
|
||||
void gst_v4l2_video_dec_register (GstPlugin * plugin,
|
||||
const gchar *basename,
|
||||
const gchar *device_path,
|
||||
const gchar *device_path, gint video_fd,
|
||||
GstCaps * sink_caps, GstCaps * src_caps);
|
||||
|
||||
G_END_DECLS
|
||||
|
|
|
@ -45,6 +45,7 @@ typedef struct
|
|||
gchar *device;
|
||||
GstCaps *sink_caps;
|
||||
GstCaps *src_caps;
|
||||
const GstV4l2Codec *codec;
|
||||
} GstV4l2VideoEncCData;
|
||||
|
||||
enum
|
||||
|
@ -419,8 +420,9 @@ negotiate_profile_and_level (GstCapsFeatures * features, GstStructure * s,
|
|||
GQueue profiles = G_QUEUE_INIT;
|
||||
GQueue levels = G_QUEUE_INIT;
|
||||
gboolean failed = FALSE;
|
||||
const GstV4l2Codec *codec = klass->codec;
|
||||
|
||||
if (klass->profile_cid && get_string_list (s, "profile", &profiles)) {
|
||||
if (codec->profile_cid && get_string_list (s, "profile", &profiles)) {
|
||||
GList *l;
|
||||
|
||||
for (l = profiles.head; l; l = l->next) {
|
||||
|
@ -430,8 +432,9 @@ negotiate_profile_and_level (GstCapsFeatures * features, GstStructure * s,
|
|||
|
||||
GST_TRACE_OBJECT (ctx->self, "Trying profile %s", profile);
|
||||
|
||||
control.id = klass->profile_cid;
|
||||
control.value = v4l2_profile = klass->profile_from_string (profile);
|
||||
control.id = codec->profile_cid;
|
||||
|
||||
control.value = v4l2_profile = codec->profile_from_string (profile);
|
||||
|
||||
if (control.value < 0)
|
||||
continue;
|
||||
|
@ -442,7 +445,7 @@ negotiate_profile_and_level (GstCapsFeatures * features, GstStructure * s,
|
|||
break;
|
||||
}
|
||||
|
||||
profile = klass->profile_to_string (control.value);
|
||||
profile = codec->profile_to_string (control.value);
|
||||
|
||||
if (control.value == v4l2_profile) {
|
||||
ctx->profile = profile;
|
||||
|
@ -462,7 +465,7 @@ negotiate_profile_and_level (GstCapsFeatures * features, GstStructure * s,
|
|||
g_queue_clear (&profiles);
|
||||
}
|
||||
|
||||
if (!failed && klass->level_cid && get_string_list (s, "level", &levels)) {
|
||||
if (!failed && codec->level_cid && get_string_list (s, "level", &levels)) {
|
||||
GList *l;
|
||||
|
||||
for (l = levels.head; l; l = l->next) {
|
||||
|
@ -472,8 +475,8 @@ negotiate_profile_and_level (GstCapsFeatures * features, GstStructure * s,
|
|||
|
||||
GST_TRACE_OBJECT (ctx->self, "Trying level %s", level);
|
||||
|
||||
control.id = klass->level_cid;
|
||||
control.value = v4l2_level = klass->level_from_string (level);
|
||||
control.id = codec->level_cid;
|
||||
control.value = v4l2_level = codec->level_from_string (level);
|
||||
|
||||
if (control.value < 0)
|
||||
continue;
|
||||
|
@ -484,7 +487,7 @@ negotiate_profile_and_level (GstCapsFeatures * features, GstStructure * s,
|
|||
break;
|
||||
}
|
||||
|
||||
level = klass->level_to_string (control.value);
|
||||
level = codec->level_to_string (control.value);
|
||||
|
||||
if (control.value == v4l2_level) {
|
||||
ctx->level = level;
|
||||
|
@ -518,6 +521,7 @@ gst_v4l2_video_enc_negotiate (GstVideoEncoder * encoder)
|
|||
struct ProfileLevelCtx ctx = { self, NULL, NULL };
|
||||
GstVideoCodecState *state;
|
||||
GstStructure *s;
|
||||
const GstV4l2Codec *codec = klass->codec;
|
||||
|
||||
GST_DEBUG_OBJECT (self, "Negotiating %s profile and level.",
|
||||
klass->codec_name);
|
||||
|
@ -543,26 +547,26 @@ gst_v4l2_video_enc_negotiate (GstVideoEncoder * encoder)
|
|||
}
|
||||
}
|
||||
|
||||
if (klass->profile_cid && !ctx.profile) {
|
||||
if (codec->profile_cid && !ctx.profile) {
|
||||
struct v4l2_control control = { 0, };
|
||||
|
||||
control.id = klass->profile_cid;
|
||||
control.id = codec->profile_cid;
|
||||
|
||||
if (v4l2object->ioctl (v4l2object->video_fd, VIDIOC_G_CTRL, &control) < 0)
|
||||
goto g_ctrl_failed;
|
||||
|
||||
ctx.profile = klass->profile_to_string (control.value);
|
||||
ctx.profile = codec->profile_to_string (control.value);
|
||||
}
|
||||
|
||||
if (klass->level_cid && !ctx.level) {
|
||||
if (codec->level_cid && !ctx.level) {
|
||||
struct v4l2_control control = { 0, };
|
||||
|
||||
control.id = klass->level_cid;
|
||||
control.id = codec->level_cid;
|
||||
|
||||
if (v4l2object->ioctl (v4l2object->video_fd, VIDIOC_G_CTRL, &control) < 0)
|
||||
goto g_ctrl_failed;
|
||||
|
||||
ctx.level = klass->level_to_string (control.value);
|
||||
ctx.level = codec->level_to_string (control.value);
|
||||
}
|
||||
|
||||
GST_DEBUG_OBJECT (self, "Selected %s profile %s at level %s",
|
||||
|
@ -571,10 +575,10 @@ gst_v4l2_video_enc_negotiate (GstVideoEncoder * encoder)
|
|||
state = gst_video_encoder_get_output_state (encoder);
|
||||
s = gst_caps_get_structure (state->caps, 0);
|
||||
|
||||
if (klass->profile_cid)
|
||||
if (codec->profile_cid)
|
||||
gst_structure_set (s, "profile", G_TYPE_STRING, ctx.profile, NULL);
|
||||
|
||||
if (klass->level_cid)
|
||||
if (codec->level_cid)
|
||||
gst_structure_set (s, "level", G_TYPE_STRING, ctx.level, NULL);
|
||||
|
||||
if (!GST_VIDEO_ENCODER_CLASS (parent_class)->negotiate (encoder))
|
||||
|
@ -1122,6 +1126,7 @@ gst_v4l2_video_enc_subclass_init (gpointer g_class, gpointer data)
|
|||
GstV4l2VideoEncCData *cdata = data;
|
||||
|
||||
klass->default_device = cdata->device;
|
||||
klass->codec = cdata->codec;
|
||||
|
||||
/* Note: gst_pad_template_new() take the floating ref from the caps */
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
|
@ -1160,8 +1165,9 @@ gst_v4l2_is_video_enc (GstCaps * sink_caps, GstCaps * src_caps,
|
|||
|
||||
void
|
||||
gst_v4l2_video_enc_register (GstPlugin * plugin, GType type,
|
||||
const char *codec, const gchar * basename, const gchar * device_path,
|
||||
GstCaps * sink_caps, GstCaps * codec_caps, GstCaps * src_caps)
|
||||
const char *codec_name, const gchar * basename, const gchar * device_path,
|
||||
const GstV4l2Codec * codec, gint video_fd, GstCaps * sink_caps,
|
||||
GstCaps * codec_caps, GstCaps * src_caps)
|
||||
{
|
||||
GstCaps *filtered_caps;
|
||||
GTypeQuery type_query;
|
||||
|
@ -1170,12 +1176,27 @@ gst_v4l2_video_enc_register (GstPlugin * plugin, GType type,
|
|||
gchar *type_name;
|
||||
GstV4l2VideoEncCData *cdata;
|
||||
|
||||
if (codec != NULL && video_fd != -1) {
|
||||
GValue *value = gst_v4l2_codec_probe_levels (codec, video_fd);
|
||||
if (value != NULL) {
|
||||
gst_caps_set_value (src_caps, "level", value);
|
||||
g_value_unset (value);
|
||||
}
|
||||
|
||||
value = gst_v4l2_codec_probe_profiles (codec, video_fd);
|
||||
if (value != NULL) {
|
||||
gst_caps_set_value (src_caps, "profile", value);
|
||||
g_value_unset (value);
|
||||
}
|
||||
}
|
||||
|
||||
filtered_caps = gst_caps_intersect (src_caps, codec_caps);
|
||||
|
||||
cdata = g_new0 (GstV4l2VideoEncCData, 1);
|
||||
cdata->device = g_strdup (device_path);
|
||||
cdata->sink_caps = gst_caps_ref (sink_caps);
|
||||
cdata->src_caps = gst_caps_ref (filtered_caps);
|
||||
cdata->codec = codec;
|
||||
|
||||
g_type_query (type, &type_query);
|
||||
memset (&type_info, 0, sizeof (type_info));
|
||||
|
@ -1189,11 +1210,11 @@ gst_v4l2_video_enc_register (GstPlugin * plugin, GType type,
|
|||
* v4l2h264enc, for any additional encoders, we create unique names. Encoder
|
||||
* names may change between boots, so this should help gain stable names for
|
||||
* the most common use cases. */
|
||||
type_name = g_strdup_printf ("v4l2%senc", codec);
|
||||
type_name = g_strdup_printf ("v4l2%senc", codec_name);
|
||||
|
||||
if (g_type_from_name (type_name) != 0) {
|
||||
g_free (type_name);
|
||||
type_name = g_strdup_printf ("v4l2%s%senc", basename, codec);
|
||||
type_name = g_strdup_printf ("v4l2%s%senc", basename, codec_name);
|
||||
}
|
||||
|
||||
subtype = g_type_register_static (type, type_name, &type_info, 0);
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
#include <gstv4l2object.h>
|
||||
#include <gstv4l2bufferpool.h>
|
||||
#include <gstv4l2codec.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
#define GST_TYPE_V4L2_VIDEO_ENC \
|
||||
|
@ -73,14 +74,7 @@ struct _GstV4l2VideoEncClass
|
|||
|
||||
gchar *default_device;
|
||||
const char *codec_name;
|
||||
|
||||
guint32 profile_cid;
|
||||
const gchar * (*profile_to_string) (gint v4l2_profile);
|
||||
gint (*profile_from_string) (const gchar * profile);
|
||||
|
||||
guint32 level_cid;
|
||||
const gchar * (*level_to_string) (gint v4l2_level);
|
||||
gint (*level_from_string) (const gchar * level);
|
||||
const GstV4l2Codec *codec;
|
||||
};
|
||||
|
||||
GType gst_v4l2_video_enc_get_type (void);
|
||||
|
@ -90,7 +84,8 @@ gboolean gst_v4l2_is_video_enc (GstCaps * sink_caps, GstCaps * src_caps,
|
|||
GstCaps * codec_caps);
|
||||
|
||||
void gst_v4l2_video_enc_register (GstPlugin * plugin, GType type,
|
||||
const char *codec, const gchar * basename, const gchar * device_path,
|
||||
const char *codec_name, const gchar * basename, const gchar * device_path,
|
||||
const GstV4l2Codec * codec, gint video_fd,
|
||||
GstCaps * sink_caps, GstCaps *codec_caps, GstCaps * src_caps);
|
||||
|
||||
G_END_DECLS
|
||||
|
|
83
sys/v4l2/gstv4l2vp8codec.c
Normal file
83
sys/v4l2/gstv4l2vp8codec.c
Normal file
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* Copyright (C) 2017 Collabora Inc.
|
||||
* Author: Nicolas Dufresne <nicolas.dufresne@collabora.com>
|
||||
* Factored out from gstv4l2vp8enc by Philippe Normand <philn@igalia.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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "gstv4l2vp8codec.h"
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include "ext/v4l2-controls.h"
|
||||
|
||||
static gint
|
||||
v4l2_profile_from_string (const gchar * profile)
|
||||
{
|
||||
gint v4l2_profile = -1;
|
||||
|
||||
if (g_str_equal (profile, "0"))
|
||||
v4l2_profile = 0;
|
||||
else if (g_str_equal (profile, "1"))
|
||||
v4l2_profile = 1;
|
||||
else if (g_str_equal (profile, "2"))
|
||||
v4l2_profile = 2;
|
||||
else if (g_str_equal (profile, "3"))
|
||||
v4l2_profile = 3;
|
||||
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 0:
|
||||
return "0";
|
||||
case 1:
|
||||
return "1";
|
||||
case 2:
|
||||
return "2";
|
||||
case 3:
|
||||
return "3";
|
||||
default:
|
||||
GST_WARNING ("Unsupported V4L2 profile %i", v4l2_profile);
|
||||
break;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const GstV4l2Codec *
|
||||
gst_v4l2_vp8_get_codec (void)
|
||||
{
|
||||
static GstV4l2Codec *codec = NULL;
|
||||
if (g_once_init_enter (&codec)) {
|
||||
static GstV4l2Codec c;
|
||||
c.profile_cid = V4L2_CID_MPEG_VIDEO_VPX_PROFILE;
|
||||
c.profile_to_string = v4l2_profile_to_string;
|
||||
c.profile_from_string = v4l2_profile_from_string;
|
||||
g_once_init_leave (&codec, &c);
|
||||
}
|
||||
return codec;
|
||||
}
|
34
sys/v4l2/gstv4l2vp8codec.h
Normal file
34
sys/v4l2/gstv4l2vp8codec.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright (C) 2017 Collabora Inc.
|
||||
* Author: Nicolas Dufresne <nicolas.dufresne@collabora.com>
|
||||
* Factored out from gstv4l2vp8enc by Philippe Normand <philn@igalia.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 __GST_V4L2_VP8_CODEC_H__
|
||||
#define __GST_V4L2_VP8_CODEC_H__
|
||||
|
||||
#include "gstv4l2codec.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
const GstV4l2Codec * gst_v4l2_vp8_get_codec (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif
|
|
@ -31,6 +31,7 @@
|
|||
|
||||
#include "gstv4l2object.h"
|
||||
#include "gstv4l2vp8enc.h"
|
||||
#include "gstv4l2vp8codec.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <gst/gst-i18n-plugin.h>
|
||||
|
@ -65,45 +66,6 @@ gst_v4l2_vp8_enc_get_property (GObject * object,
|
|||
/* TODO */
|
||||
}
|
||||
|
||||
static gint
|
||||
v4l2_profile_from_string (const gchar * profile)
|
||||
{
|
||||
gint v4l2_profile = -1;
|
||||
|
||||
if (g_str_equal (profile, "0"))
|
||||
v4l2_profile = 0;
|
||||
else if (g_str_equal (profile, "1"))
|
||||
v4l2_profile = 1;
|
||||
else if (g_str_equal (profile, "2"))
|
||||
v4l2_profile = 2;
|
||||
else if (g_str_equal (profile, "3"))
|
||||
v4l2_profile = 3;
|
||||
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 0:
|
||||
return "0";
|
||||
case 1:
|
||||
return "1";
|
||||
case 2:
|
||||
return "2";
|
||||
case 3:
|
||||
return "3";
|
||||
default:
|
||||
GST_WARNING ("Unsupported V4L2 profile %i", v4l2_profile);
|
||||
break;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_v4l2_vp8_enc_init (GstV4l2Vp8Enc * self)
|
||||
{
|
||||
|
@ -138,9 +100,6 @@ gst_v4l2_vp8_enc_class_init (GstV4l2Vp8EncClass * klass)
|
|||
GST_DEBUG_FUNCPTR (gst_v4l2_vp8_enc_get_property);
|
||||
|
||||
baseclass->codec_name = "VP8";
|
||||
baseclass->profile_cid = V4L2_CID_MPEG_VIDEO_VPX_PROFILE;
|
||||
baseclass->profile_to_string = v4l2_profile_to_string;
|
||||
baseclass->profile_from_string = v4l2_profile_from_string;
|
||||
}
|
||||
|
||||
/* Probing functions */
|
||||
|
@ -153,9 +112,11 @@ gst_v4l2_is_vp8_enc (GstCaps * sink_caps, GstCaps * src_caps)
|
|||
|
||||
void
|
||||
gst_v4l2_vp8_enc_register (GstPlugin * plugin, const gchar * basename,
|
||||
const gchar * device_path, GstCaps * sink_caps, GstCaps * src_caps)
|
||||
const gchar * device_path, gint video_fd, GstCaps * sink_caps,
|
||||
GstCaps * src_caps)
|
||||
{
|
||||
const GstV4l2Codec *codec = gst_v4l2_vp8_get_codec ();
|
||||
gst_v4l2_video_enc_register (plugin, GST_TYPE_V4L2_VP8_ENC,
|
||||
"vp8", basename, device_path, sink_caps,
|
||||
"vp8", basename, device_path, codec, video_fd, sink_caps,
|
||||
gst_static_caps_get (&src_template_caps), src_caps);
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ GType gst_v4l2_vp8_enc_get_type (void);
|
|||
gboolean gst_v4l2_is_vp8_enc (GstCaps * sink_caps, GstCaps * src_caps);
|
||||
|
||||
void gst_v4l2_vp8_enc_register (GstPlugin * plugin, const gchar * basename,
|
||||
const gchar * device_path, GstCaps * sink_caps, GstCaps * src_caps);
|
||||
const gchar * device_path, gint video_fd, GstCaps * sink_caps, GstCaps * src_caps);
|
||||
|
||||
G_END_DECLS
|
||||
#endif /* __GST_V4L2_VP8_ENC_H__ */
|
||||
|
|
84
sys/v4l2/gstv4l2vp9codec.c
Normal file
84
sys/v4l2/gstv4l2vp9codec.c
Normal file
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* Copyright (C) 2017 Collabora Inc.
|
||||
* Author: Nicolas Dufresne <nicolas.dufresne@collabora.com>
|
||||
* Factored out from gstv4l2vp9enc by Philippe Normand <philn@igalia.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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "gstv4l2vp9codec.h"
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include "ext/v4l2-controls.h"
|
||||
|
||||
|
||||
static gint
|
||||
v4l2_profile_from_string (const gchar * profile)
|
||||
{
|
||||
gint v4l2_profile = -1;
|
||||
|
||||
if (g_str_equal (profile, "0"))
|
||||
v4l2_profile = 0;
|
||||
else if (g_str_equal (profile, "1"))
|
||||
v4l2_profile = 1;
|
||||
else if (g_str_equal (profile, "2"))
|
||||
v4l2_profile = 2;
|
||||
else if (g_str_equal (profile, "3"))
|
||||
v4l2_profile = 3;
|
||||
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 0:
|
||||
return "0";
|
||||
case 1:
|
||||
return "1";
|
||||
case 2:
|
||||
return "2";
|
||||
case 3:
|
||||
return "3";
|
||||
default:
|
||||
GST_WARNING ("Unsupported V4L2 profile %i", v4l2_profile);
|
||||
break;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const GstV4l2Codec *
|
||||
gst_v4l2_vp9_get_codec (void)
|
||||
{
|
||||
static GstV4l2Codec *codec = NULL;
|
||||
if (g_once_init_enter (&codec)) {
|
||||
static GstV4l2Codec c;
|
||||
c.profile_cid = V4L2_CID_MPEG_VIDEO_VPX_PROFILE;
|
||||
c.profile_to_string = v4l2_profile_to_string;
|
||||
c.profile_from_string = v4l2_profile_from_string;
|
||||
g_once_init_leave (&codec, &c);
|
||||
}
|
||||
return codec;
|
||||
}
|
34
sys/v4l2/gstv4l2vp9codec.h
Normal file
34
sys/v4l2/gstv4l2vp9codec.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright (C) 2017 Collabora Inc.
|
||||
* Author: Nicolas Dufresne <nicolas.dufresne@collabora.com>
|
||||
* Factored out from gstv4l2vp9enc by Philippe Normand <philn@igalia.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 __GST_V4L2_VP9_CODEC_H__
|
||||
#define __GST_V4L2_VP9_CODEC_H__
|
||||
|
||||
#include "gstv4l2codec.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
const GstV4l2Codec * gst_v4l2_vp9_get_codec (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif
|
|
@ -31,6 +31,7 @@
|
|||
|
||||
#include "gstv4l2object.h"
|
||||
#include "gstv4l2vp9enc.h"
|
||||
#include "gstv4l2vp9codec.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <gst/gst-i18n-plugin.h>
|
||||
|
@ -65,45 +66,6 @@ gst_v4l2_vp9_enc_get_property (GObject * object,
|
|||
/* TODO */
|
||||
}
|
||||
|
||||
static gint
|
||||
v4l2_profile_from_string (const gchar * profile)
|
||||
{
|
||||
gint v4l2_profile = -1;
|
||||
|
||||
if (g_str_equal (profile, "0"))
|
||||
v4l2_profile = 0;
|
||||
else if (g_str_equal (profile, "1"))
|
||||
v4l2_profile = 1;
|
||||
else if (g_str_equal (profile, "2"))
|
||||
v4l2_profile = 2;
|
||||
else if (g_str_equal (profile, "3"))
|
||||
v4l2_profile = 3;
|
||||
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 0:
|
||||
return "0";
|
||||
case 1:
|
||||
return "1";
|
||||
case 2:
|
||||
return "2";
|
||||
case 3:
|
||||
return "3";
|
||||
default:
|
||||
GST_WARNING ("Unsupported V4L2 profile %i", v4l2_profile);
|
||||
break;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_v4l2_vp9_enc_init (GstV4l2Vp9Enc * self)
|
||||
{
|
||||
|
@ -137,9 +99,6 @@ gst_v4l2_vp9_enc_class_init (GstV4l2Vp9EncClass * klass)
|
|||
GST_DEBUG_FUNCPTR (gst_v4l2_vp9_enc_get_property);
|
||||
|
||||
baseclass->codec_name = "VP9";
|
||||
baseclass->profile_cid = V4L2_CID_MPEG_VIDEO_VPX_PROFILE;
|
||||
baseclass->profile_to_string = v4l2_profile_to_string;
|
||||
baseclass->profile_from_string = v4l2_profile_from_string;
|
||||
}
|
||||
|
||||
/* Probing functions */
|
||||
|
@ -152,9 +111,11 @@ gst_v4l2_is_vp9_enc (GstCaps * sink_caps, GstCaps * src_caps)
|
|||
|
||||
void
|
||||
gst_v4l2_vp9_enc_register (GstPlugin * plugin, const gchar * basename,
|
||||
const gchar * device_path, GstCaps * sink_caps, GstCaps * src_caps)
|
||||
const gchar * device_path, gint video_fd, GstCaps * sink_caps,
|
||||
GstCaps * src_caps)
|
||||
{
|
||||
const GstV4l2Codec *codec = gst_v4l2_vp9_get_codec ();
|
||||
gst_v4l2_video_enc_register (plugin, GST_TYPE_V4L2_VP9_ENC,
|
||||
"vp9", basename, device_path, sink_caps,
|
||||
"vp9", basename, device_path, codec, video_fd, sink_caps,
|
||||
gst_static_caps_get (&src_template_caps), src_caps);
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ GType gst_v4l2_vp9_enc_get_type (void);
|
|||
gboolean gst_v4l2_is_vp9_enc (GstCaps * sink_caps, GstCaps * src_caps);
|
||||
|
||||
void gst_v4l2_vp9_enc_register (GstPlugin * plugin, const gchar * basename,
|
||||
const gchar * device_path, GstCaps * sink_caps, GstCaps * src_caps);
|
||||
const gchar * device_path, gint video_fd, GstCaps * sink_caps, GstCaps * src_caps);
|
||||
|
||||
G_END_DECLS
|
||||
#endif /* __GST_V4L2_VP9_ENC_H__ */
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
v4l2_sources = [
|
||||
'gstv4l2.c',
|
||||
'gstv4l2allocator.c',
|
||||
'gstv4l2codec.c',
|
||||
'gstv4l2colorbalance.c',
|
||||
'gstv4l2deviceprovider.c',
|
||||
'gstv4l2object.c',
|
||||
|
@ -14,12 +15,17 @@ v4l2_sources = [
|
|||
'gstv4l2videoenc.c',
|
||||
'gstv4l2fwhtenc.c',
|
||||
'gstv4l2h263enc.c',
|
||||
'gstv4l2h264codec.c',
|
||||
'gstv4l2h264enc.c',
|
||||
'gstv4l2h265codec.c',
|
||||
'gstv4l2h265enc.c',
|
||||
'gstv4l2jpegenc.c',
|
||||
'gstv4l2mpeg4codec.c',
|
||||
'gstv4l2mpeg4enc.c',
|
||||
'gstv4l2vidorient.c',
|
||||
'gstv4l2vp8codec.c',
|
||||
'gstv4l2vp8enc.c',
|
||||
'gstv4l2vp9codec.c',
|
||||
'gstv4l2vp9enc.c',
|
||||
'v4l2_calls.c',
|
||||
'v4l2-utils.c',
|
||||
|
|
Loading…
Reference in a new issue