651 lines
19 KiB
Diff
651 lines
19 KiB
Diff
From ebb197aacf8cb21a79704851b045d28592848953 Mon Sep 17 00:00:00 2001
|
|
From: Benjamin Gaignard <benjamin.gaignard@collabora.com>
|
|
Date: Mon, 16 Jan 2023 17:34:10 +0100
|
|
Subject: [PATCH 1/5] codecs: Add base class for stateless vp8 encoder
|
|
|
|
Add stateless vp8 encoder base class and vp8 frame structure.
|
|
---
|
|
gst-libs/gst/codecs/gstvp8encoder.c | 351 ++++++++++++++++++++++++++++
|
|
gst-libs/gst/codecs/gstvp8encoder.h | 81 +++++++
|
|
gst-libs/gst/codecs/gstvp8frame.c | 66 ++++++
|
|
gst-libs/gst/codecs/gstvp8frame.h | 70 ++++++
|
|
gst-libs/gst/codecs/meson.build | 7 +-
|
|
5 files changed, 574 insertions(+), 1 deletion(-)
|
|
create mode 100644 gst-libs/gst/codecs/gstvp8encoder.c
|
|
create mode 100644 gst-libs/gst/codecs/gstvp8encoder.h
|
|
create mode 100644 gst-libs/gst/codecs/gstvp8frame.c
|
|
create mode 100644 gst-libs/gst/codecs/gstvp8frame.h
|
|
|
|
diff --git a/gst-libs/gst/codecs/gstvp8encoder.c b/gst-libs/gst/codecs/gstvp8encoder.c
|
|
new file mode 100644
|
|
index 0000000..b105786
|
|
--- /dev/null
|
|
+++ b/gst-libs/gst/codecs/gstvp8encoder.c
|
|
@@ -0,0 +1,351 @@
|
|
+/* GStreamer
|
|
+ * Copyright (C) 2022 Benjamin Gaignard <benjamin.gaignard@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 "gstvp8encoder.h"
|
|
+
|
|
+#include <gst/video/video.h>
|
|
+#include <gst/video/gstvideometa.h>
|
|
+#include <gst/base/base.h>
|
|
+
|
|
+GST_DEBUG_CATEGORY (gst_vp8_encoder_debug);
|
|
+#define GST_CAT_DEFAULT gst_vp8_encoder_debug
|
|
+
|
|
+#define VP8ENC_DEFAULT_KEYFRAME_INTERVAL 30
|
|
+
|
|
+#define VP8_MAX_QUALITY 63
|
|
+#define VP8_MIN_QUALITY 0
|
|
+
|
|
+#define VP8_DEFAULT_BITRATE 100000
|
|
+
|
|
+enum
|
|
+{
|
|
+ PROP_0,
|
|
+ PROP_KEYFRAME_INTERVAL,
|
|
+ PROP_MAX_QUALITY,
|
|
+ PROP_MIN_QUALITY,
|
|
+ PROP_BITRATE,
|
|
+};
|
|
+
|
|
+struct _GstVp8EncoderPrivate
|
|
+{
|
|
+ gint keyframe_interval;
|
|
+
|
|
+ guint32 last_keyframe;
|
|
+
|
|
+ guint64 targeted_bitrate;
|
|
+ gint max_quality;
|
|
+ gint min_quality;
|
|
+ gint current_quality;
|
|
+ guint64 used_bytes;
|
|
+ guint64 nb_frames;
|
|
+};
|
|
+
|
|
+#define parent_class gst_vp8_encoder_parent_class
|
|
+G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GstVp8Encoder, gst_vp8_encoder,
|
|
+ GST_TYPE_VIDEO_ENCODER,
|
|
+ G_ADD_PRIVATE (GstVp8Encoder);
|
|
+ GST_DEBUG_CATEGORY_INIT (gst_vp8_encoder_debug, "vp8encoder", 0,
|
|
+ "Vp8 Video Encoder"));
|
|
+
|
|
+static void
|
|
+gst_vp8_encoder_init (GstVp8Encoder * self)
|
|
+{
|
|
+ self->priv = gst_vp8_encoder_get_instance_private (self);
|
|
+}
|
|
+
|
|
+static void
|
|
+gst_vp8_encoder_finalize (GObject * object)
|
|
+{
|
|
+ G_OBJECT_CLASS (parent_class)->finalize (object);
|
|
+}
|
|
+
|
|
+static gboolean
|
|
+gst_vp8_encoder_start (GstVideoEncoder * encoder)
|
|
+{
|
|
+ GstVp8Encoder *self = GST_VP8_ENCODER (encoder);
|
|
+ GstVp8EncoderPrivate *priv = self->priv;
|
|
+
|
|
+ priv->last_keyframe = 0;
|
|
+ priv->current_quality = priv->min_quality;
|
|
+ priv->used_bytes = 0;
|
|
+ priv->nb_frames = 0;
|
|
+
|
|
+ return TRUE;
|
|
+}
|
|
+
|
|
+static gboolean
|
|
+gst_vp8_encoder_stop (GstVideoEncoder * encoder)
|
|
+{
|
|
+ return TRUE;
|
|
+}
|
|
+
|
|
+static gboolean
|
|
+gst_vp8_encoder_set_format (GstVideoEncoder * encoder,
|
|
+ GstVideoCodecState * state)
|
|
+{
|
|
+ return TRUE;
|
|
+}
|
|
+
|
|
+static GstFlowReturn
|
|
+gst_vp8_encoder_set_quality (GstVp8Encoder * self, GstVp8Frame * vp8_frame)
|
|
+{
|
|
+ GstVp8EncoderPrivate *priv = self->priv;
|
|
+ GstVideoEncoder *encoder = GST_VIDEO_ENCODER (self);
|
|
+ GstVideoCodecState *output_state =
|
|
+ gst_video_encoder_get_output_state (encoder);
|
|
+ gint qp = priv->current_quality;
|
|
+ guint64 bitrate = 0;
|
|
+ guint fps_n = 30, fps_d = 1;
|
|
+
|
|
+ if (output_state == NULL)
|
|
+ return qp;
|
|
+
|
|
+ if (GST_VIDEO_INFO_FPS_N (&output_state->info) != 0) {
|
|
+ fps_n = GST_VIDEO_INFO_FPS_N (&output_state->info);
|
|
+ fps_d = GST_VIDEO_INFO_FPS_D (&output_state->info);
|
|
+ }
|
|
+ gst_video_codec_state_unref (output_state);
|
|
+
|
|
+ bitrate = (priv->used_bytes * 8 * fps_n) / (priv->nb_frames * fps_d);
|
|
+ if (bitrate > priv->targeted_bitrate) {
|
|
+ qp++;
|
|
+ }
|
|
+
|
|
+ if (bitrate < priv->targeted_bitrate) {
|
|
+ qp--;
|
|
+ }
|
|
+
|
|
+ if (qp > priv->max_quality)
|
|
+ qp = priv->max_quality;
|
|
+ if (qp < priv->min_quality)
|
|
+ qp = priv->min_quality;
|
|
+
|
|
+ vp8_frame->quality = qp;
|
|
+
|
|
+ return GST_FLOW_OK;
|
|
+}
|
|
+
|
|
+static GstFlowReturn
|
|
+gst_vp8_encoder_set_frame_type (GstVp8Encoder * self, GstVp8Frame * vp8_frame)
|
|
+{
|
|
+ GstVp8EncoderPrivate *priv = self->priv;
|
|
+ GstVideoCodecFrame *frame = vp8_frame->frame;
|
|
+
|
|
+ if (GST_VIDEO_CODEC_FRAME_IS_FORCE_KEYFRAME (frame)) {
|
|
+ vp8_frame->type = GstVp8Keyframe;
|
|
+ return GST_FLOW_OK;
|
|
+ }
|
|
+
|
|
+ if ((frame->system_frame_number - priv->last_keyframe) >
|
|
+ priv->keyframe_interval || frame->system_frame_number == 0) {
|
|
+ /* Generate a keyframe */
|
|
+ GST_DEBUG_OBJECT (self, "Generate a keyframe");
|
|
+ vp8_frame->type = GstVp8Keyframe;
|
|
+ return GST_FLOW_OK;
|
|
+ }
|
|
+
|
|
+ /* Generate a interframe */
|
|
+ GST_DEBUG_OBJECT (self, "Generate a interframe");
|
|
+ vp8_frame->type = GstVp8Inter;
|
|
+ return GST_FLOW_OK;
|
|
+}
|
|
+
|
|
+static void
|
|
+gst_vp8_encoder_mark_frame (GstVp8Encoder * self, GstVp8Frame * vp8_frame)
|
|
+{
|
|
+ GstVideoCodecFrame *frame = vp8_frame->frame;
|
|
+ GstVp8EncoderPrivate *priv = self->priv;
|
|
+
|
|
+ switch (vp8_frame->type) {
|
|
+ case GstVp8Keyframe:
|
|
+ priv->last_keyframe = frame->system_frame_number;
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ priv->current_quality = vp8_frame->quality;
|
|
+ priv->used_bytes += gst_buffer_get_size (frame->output_buffer);
|
|
+ priv->nb_frames++;
|
|
+}
|
|
+
|
|
+static GstFlowReturn
|
|
+gst_vp8_encoder_handle_frame (GstVideoEncoder * encoder,
|
|
+ GstVideoCodecFrame * frame)
|
|
+{
|
|
+ GstVp8Encoder *self = GST_VP8_ENCODER (encoder);
|
|
+ GstVp8EncoderClass *klass = GST_VP8_ENCODER_GET_CLASS (self);
|
|
+ GstFlowReturn ret = GST_FLOW_OK;
|
|
+ GstVp8Frame *vp8_frame = gst_vp8_frame_new (frame);
|
|
+
|
|
+ ret = gst_vp8_encoder_set_frame_type (self, vp8_frame);
|
|
+ if (ret != GST_FLOW_OK)
|
|
+ return ret;
|
|
+
|
|
+ ret = gst_vp8_encoder_set_quality (self, vp8_frame);
|
|
+ if (ret != GST_FLOW_OK)
|
|
+ return ret;
|
|
+
|
|
+ /* TODO: add encoding parameters management here
|
|
+ * for now just send the frame to encode */
|
|
+ if (klass->encode_frame) {
|
|
+ ret = klass->encode_frame (self, vp8_frame);
|
|
+ if (ret == GST_FLOW_OK)
|
|
+ gst_vp8_encoder_mark_frame (self, vp8_frame);
|
|
+ }
|
|
+
|
|
+ gst_vp8_frame_unref (vp8_frame);
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+static void
|
|
+gst_vp8_encoder_get_property (GObject * object, guint property_id,
|
|
+ GValue * value, GParamSpec * pspec)
|
|
+{
|
|
+ GstVp8Encoder *self = GST_VP8_ENCODER (object);
|
|
+ GstVp8EncoderPrivate *priv = self->priv;
|
|
+
|
|
+ switch (property_id) {
|
|
+ case PROP_KEYFRAME_INTERVAL:
|
|
+ GST_OBJECT_LOCK (self);
|
|
+ g_value_set_int (value, priv->keyframe_interval);
|
|
+ GST_OBJECT_UNLOCK (self);
|
|
+ break;
|
|
+ case PROP_MAX_QUALITY:
|
|
+ GST_OBJECT_LOCK (self);
|
|
+ g_value_set_int (value, priv->max_quality);
|
|
+ GST_OBJECT_UNLOCK (self);
|
|
+ break;
|
|
+ case PROP_MIN_QUALITY:
|
|
+ GST_OBJECT_LOCK (self);
|
|
+ g_value_set_int (value, priv->min_quality);
|
|
+ GST_OBJECT_UNLOCK (self);
|
|
+ break;
|
|
+ case PROP_BITRATE:
|
|
+ GST_OBJECT_LOCK (self);
|
|
+ g_value_set_uint64 (value, priv->targeted_bitrate);
|
|
+ GST_OBJECT_UNLOCK (self);
|
|
+ break;
|
|
+ default:
|
|
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
|
+ break;
|
|
+ }
|
|
+}
|
|
+
|
|
+static void
|
|
+gst_vp8_encoder_set_property (GObject * object, guint property_id,
|
|
+ const GValue * value, GParamSpec * pspec)
|
|
+{
|
|
+ GstVp8Encoder *self = GST_VP8_ENCODER (object);
|
|
+ GstVp8EncoderPrivate *priv = self->priv;
|
|
+
|
|
+ switch (property_id) {
|
|
+ case PROP_KEYFRAME_INTERVAL:
|
|
+ GST_OBJECT_LOCK (self);
|
|
+ priv->keyframe_interval = g_value_get_int (value);
|
|
+ GST_OBJECT_UNLOCK (self);
|
|
+ break;
|
|
+ case PROP_MAX_QUALITY:
|
|
+ GST_OBJECT_LOCK (self);
|
|
+ priv->max_quality = g_value_get_int (value);
|
|
+ GST_OBJECT_UNLOCK (self);
|
|
+ break;
|
|
+ case PROP_MIN_QUALITY:
|
|
+ GST_OBJECT_LOCK (self);
|
|
+ priv->min_quality = g_value_get_int (value);
|
|
+ GST_OBJECT_UNLOCK (self);
|
|
+ break;
|
|
+ case PROP_BITRATE:
|
|
+ GST_OBJECT_LOCK (self);
|
|
+ priv->targeted_bitrate = g_value_get_uint64 (value);
|
|
+ GST_OBJECT_UNLOCK (self);
|
|
+ break;
|
|
+ default:
|
|
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
|
+ break;
|
|
+ }
|
|
+}
|
|
+
|
|
+static void
|
|
+gst_vp8_encoder_class_init (GstVp8EncoderClass * klass)
|
|
+{
|
|
+ GstVideoEncoderClass *encoder_class = GST_VIDEO_ENCODER_CLASS (klass);
|
|
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
+
|
|
+ object_class->finalize = GST_DEBUG_FUNCPTR (gst_vp8_encoder_finalize);
|
|
+ object_class->get_property = gst_vp8_encoder_get_property;
|
|
+ object_class->set_property = gst_vp8_encoder_set_property;
|
|
+
|
|
+ encoder_class->start = GST_DEBUG_FUNCPTR (gst_vp8_encoder_start);
|
|
+ encoder_class->stop = GST_DEBUG_FUNCPTR (gst_vp8_encoder_stop);
|
|
+ encoder_class->set_format = GST_DEBUG_FUNCPTR (gst_vp8_encoder_set_format);
|
|
+ encoder_class->handle_frame =
|
|
+ GST_DEBUG_FUNCPTR (gst_vp8_encoder_handle_frame);
|
|
+
|
|
+ /**
|
|
+ * GstVp8Encoder:keyframe-interval:
|
|
+ *
|
|
+ *
|
|
+ * Since: 1.2x
|
|
+ */
|
|
+ g_object_class_install_property (object_class, PROP_KEYFRAME_INTERVAL,
|
|
+ g_param_spec_int ("keyframe-interval", "Keyframe Interval",
|
|
+ "Interval between keyframes",
|
|
+ 0, G_MAXINT, VP8ENC_DEFAULT_KEYFRAME_INTERVAL,
|
|
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT));
|
|
+
|
|
+ /**
|
|
+ * GstVp8Encoder:max-quality:
|
|
+ *
|
|
+ *
|
|
+ * Since: 1.2x
|
|
+ */
|
|
+ g_object_class_install_property (object_class, PROP_MAX_QUALITY,
|
|
+ g_param_spec_int ("max-quality", "Max Quality Level",
|
|
+ "Set upper quality limit (lower number equates to higher quality but more bits)",
|
|
+ VP8_MIN_QUALITY, VP8_MAX_QUALITY, VP8_MAX_QUALITY,
|
|
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT));
|
|
+
|
|
+ /**
|
|
+ * GstVp8Encoder:min-quality:
|
|
+ *
|
|
+ *
|
|
+ * Since: 1.2x
|
|
+ */
|
|
+ g_object_class_install_property (object_class, PROP_MIN_QUALITY,
|
|
+ g_param_spec_int ("min-quality", "Min Quality Level",
|
|
+ "Set lower quality limit (lower number equates to higher quality but more bits)",
|
|
+ VP8_MIN_QUALITY, VP8_MAX_QUALITY, VP8_MIN_QUALITY,
|
|
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT));
|
|
+
|
|
+ /**
|
|
+ * GstVp8Encoder:bitrate:
|
|
+ *
|
|
+ *
|
|
+ * Since: 1.2x
|
|
+ */
|
|
+ g_object_class_install_property (object_class, PROP_BITRATE,
|
|
+ g_param_spec_uint64 ("bitrate", "Targeted bitrate",
|
|
+ "Set bitrate target",
|
|
+ 0, UINT_MAX, VP8_DEFAULT_BITRATE,
|
|
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT));
|
|
+}
|
|
diff --git a/gst-libs/gst/codecs/gstvp8encoder.h b/gst-libs/gst/codecs/gstvp8encoder.h
|
|
new file mode 100644
|
|
index 0000000..3999ed3
|
|
--- /dev/null
|
|
+++ b/gst-libs/gst/codecs/gstvp8encoder.h
|
|
@@ -0,0 +1,81 @@
|
|
+/* GStreamer
|
|
+ * Copyright (C) 2022 Benjamin Gaignard <benjamin.gaignard@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_VP8_ENCODER_H__
|
|
+#define __GST_VP8_ENCODER_H__
|
|
+
|
|
+#include <gst/codecs/codecs-prelude.h>
|
|
+
|
|
+#include <gst/video/video.h>
|
|
+#include <gst/video/gstvideoencoder.h>
|
|
+
|
|
+#include "gstvp8frame.h"
|
|
+
|
|
+G_BEGIN_DECLS
|
|
+#define GST_TYPE_VP8_ENCODER (gst_vp8_encoder_get_type())
|
|
+#define GST_VP8_ENCODER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VP8_ENCODER,GstVp8Encoder))
|
|
+#define GST_VP8_ENCODER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_VP8_ENCODER,GstVp8EncoderClass))
|
|
+#define GST_VP8_ENCODER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj),GST_TYPE_VP8_ENCODER,GstVp8EncoderClass))
|
|
+#define GST_IS_VP8_ENCODER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VP8_ENCODER))
|
|
+#define GST_IS_VP8_ENCODER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VP8_ENCODER))
|
|
+#define GST_VP8_ENCODER_CAST(obj) ((GstVp8Encoder*)obj)
|
|
+typedef struct _GstVp8Encoder GstVp8Encoder;
|
|
+typedef struct _GstVp8EncoderClass GstVp8EncoderClass;
|
|
+typedef struct _GstVp8EncoderPrivate GstVp8EncoderPrivate;
|
|
+
|
|
+/**
|
|
+ * GstVp8Encoder:
|
|
+ *
|
|
+ * The opaque #GstVp8Encoder data structure.
|
|
+ */
|
|
+struct _GstVp8Encoder
|
|
+{
|
|
+ /*< private > */
|
|
+ GstVideoEncoder parent;
|
|
+
|
|
+ /*< private > */
|
|
+ GstVp8EncoderPrivate *priv;
|
|
+ gpointer padding[GST_PADDING_LARGE];
|
|
+};
|
|
+
|
|
+/**
|
|
+ * GstVp8EncoderClass:
|
|
+ */
|
|
+struct _GstVp8EncoderClass
|
|
+{
|
|
+ GstVideoEncoderClass parent_class;
|
|
+
|
|
+ /**
|
|
+ * GstVp8EncoderClass::encode_frame:
|
|
+ * @encoder: a #GstVp8Encoder
|
|
+ * @frame: a #GstVp8Frame
|
|
+ *
|
|
+ * Provide the frame to be encoded with the encode parameters (to be defined)
|
|
+ */
|
|
+ GstFlowReturn (*encode_frame) (GstVp8Encoder * encoder,
|
|
+ GstVp8Frame * frame);
|
|
+ /*< private > */
|
|
+ gpointer padding[GST_PADDING_LARGE];
|
|
+};
|
|
+
|
|
+G_DEFINE_AUTOPTR_CLEANUP_FUNC (GstVp8Encoder, gst_object_unref)
|
|
+ GST_CODECS_API GType gst_vp8_encoder_get_type (void);
|
|
+
|
|
+G_END_DECLS
|
|
+#endif /* __GST_VP8_ENCODER_H__ */
|
|
diff --git a/gst-libs/gst/codecs/gstvp8frame.c b/gst-libs/gst/codecs/gstvp8frame.c
|
|
new file mode 100644
|
|
index 0000000..6f26bd5
|
|
--- /dev/null
|
|
+++ b/gst-libs/gst/codecs/gstvp8frame.c
|
|
@@ -0,0 +1,66 @@
|
|
+/* GStreamer
|
|
+ * Copyright (C) 2022 Benjamin Gaignard <benjamin.gaignard@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 "gstvp8frame.h"
|
|
+
|
|
+GST_DEBUG_CATEGORY_EXTERN (gst_vp8_encoder_debug);
|
|
+#define GST_CAT_DEFAULT gst_vp8_encoder_debug
|
|
+
|
|
+GST_DEFINE_MINI_OBJECT_TYPE (GstVp8Frame, gst_vp8_frame);
|
|
+
|
|
+static void
|
|
+_gst_vp8_frame_free (GstVp8Frame * frame)
|
|
+{
|
|
+ GST_TRACE ("Free frame %p", frame);
|
|
+
|
|
+ gst_video_codec_frame_unref (frame->frame);
|
|
+
|
|
+ g_free (frame);
|
|
+}
|
|
+
|
|
+/**
|
|
+ * gst_vp8_frame_new:
|
|
+ *
|
|
+ * Create new #GstVp8Frame
|
|
+ *
|
|
+ * Returns: a new #GstVp8Frame
|
|
+ */
|
|
+GstVp8Frame *
|
|
+gst_vp8_frame_new (GstVideoCodecFrame * f)
|
|
+{
|
|
+ GstVp8Frame *frame;
|
|
+
|
|
+ if (!f)
|
|
+ return NULL;
|
|
+
|
|
+ frame = g_new0 (GstVp8Frame, 1);
|
|
+
|
|
+ gst_mini_object_init (GST_MINI_OBJECT_CAST (frame), 0,
|
|
+ GST_TYPE_VP8_FRAME, NULL, NULL,
|
|
+ (GstMiniObjectFreeFunction) _gst_vp8_frame_free);
|
|
+
|
|
+ frame->frame = gst_video_codec_frame_ref (f);
|
|
+
|
|
+ GST_TRACE ("New frame %p", frame);
|
|
+
|
|
+ return frame;
|
|
+}
|
|
diff --git a/gst-libs/gst/codecs/gstvp8frame.h b/gst-libs/gst/codecs/gstvp8frame.h
|
|
new file mode 100644
|
|
index 0000000..a3d5c21
|
|
--- /dev/null
|
|
+++ b/gst-libs/gst/codecs/gstvp8frame.h
|
|
@@ -0,0 +1,70 @@
|
|
+/* GStreamer
|
|
+ * Copyright (C) 2022 Benjamin Gaignard <benjamin.gaignard@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 __GTS_VP8_FRAME_H__
|
|
+#define __GTS_VP8_FRAME_H__
|
|
+
|
|
+#include <gst/codecs/codecs-prelude.h>
|
|
+#include <gst/video/video.h>
|
|
+
|
|
+G_BEGIN_DECLS
|
|
+
|
|
+#define GST_TYPE_VP8_FRAME (gst_vp8_frame_get_type())
|
|
+#define GST_IS_VP8_FRAME(obj) (GST_IS_MINI_OBJECT_TYPE(obj, GST_TYPE_VP8_FRAME))
|
|
+#define GST_VP8_FRAME(obj) ((GstVp8Frame *)obj)
|
|
+#define GST_VP8_FRAME_CAST(obj) (GST_VP8_FRAME(obj))
|
|
+
|
|
+typedef struct _GstVp8Frame GstVp8Frame;
|
|
+
|
|
+enum
|
|
+{
|
|
+ GstVp8Keyframe,
|
|
+ GstVp8Inter,
|
|
+};
|
|
+
|
|
+struct _GstVp8Frame
|
|
+{
|
|
+ GstMiniObject parent;
|
|
+ gint type;
|
|
+ gint quality;
|
|
+
|
|
+ GstVideoCodecFrame *frame;
|
|
+};
|
|
+
|
|
+GST_CODECS_API
|
|
+GType gst_vp8_frame_get_type (void);
|
|
+
|
|
+GST_CODECS_API
|
|
+GstVp8Frame * gst_vp8_frame_new (GstVideoCodecFrame *f);
|
|
+
|
|
+static inline GstVp8Frame *
|
|
+gst_vp8_frame_ref (GstVp8Frame * frame)
|
|
+{
|
|
+ return (GstVp8Frame *) gst_mini_object_ref (GST_MINI_OBJECT_CAST (frame));
|
|
+}
|
|
+
|
|
+static inline void
|
|
+gst_vp8_frame_unref (GstVp8Frame * frame)
|
|
+{
|
|
+ gst_mini_object_unref (GST_MINI_OBJECT_CAST (frame));
|
|
+}
|
|
+
|
|
+G_END_DECLS
|
|
+
|
|
+#endif /* __GTS_VP8_FRAME_H__ */
|
|
diff --git a/gst-libs/gst/codecs/meson.build b/gst-libs/gst/codecs/meson.build
|
|
index f2bec85..458d90d 100644
|
|
--- a/gst-libs/gst/codecs/meson.build
|
|
+++ b/gst-libs/gst/codecs/meson.build
|
|
@@ -12,6 +12,8 @@ codecs_sources = files(
|
|
'gstav1decoder.c',
|
|
'gstav1picture.c',
|
|
'gstvp9statefulparser.c',
|
|
+ 'gstvp8encoder.c',
|
|
+ 'gstvp8frame.c',
|
|
)
|
|
|
|
codecs_headers = files(
|
|
@@ -28,6 +30,8 @@ codecs_headers = files(
|
|
'gstav1decoder.h',
|
|
'gstav1picture.h',
|
|
'gstvp9statefulparser.h',
|
|
+ 'gstvp8encoder.h',
|
|
+ 'gstvp8frame.h',
|
|
)
|
|
|
|
cp_args = [
|
|
@@ -66,6 +70,7 @@ if build_gir
|
|
'--c-include=gst/codecs/gstvp9decoder.h',
|
|
'--c-include=gst/codecs/gstvp8decoder.h',
|
|
'--c-include=gst/codecs/gstmpeg2decoder.h',
|
|
+ '--c-include=gst/codecs/gstvp8encoder.h',
|
|
],
|
|
'dependencies' : [gstvideo_dep, gstcodecparsers_dep]
|
|
}
|
|
@@ -81,4 +86,4 @@ gstcodecs_dep = declare_dependency(link_with : gstcodecs,
|
|
include_directories : [libsinc],
|
|
sources: gen_sources,
|
|
dependencies : [gstvideo_dep, gstcodecparsers_dep])
|
|
-meson.override_dependency(pkg_name, gstcodecs_dep)
|
|
\ No newline at end of file
|
|
+meson.override_dependency(pkg_name, gstcodecs_dep)
|
|
--
|
|
2.25.1
|
|
|