1 /* GStreamer
2 * Copyright (C) 2021 Collabora Ltd.
3 * Author: Nicolas Dufresne <nicolas.dufresne@collabora.com>
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 */
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include "gstvideocodecalphameta.h"
25
26 /**
27 * SECTION:gstvideocodecalphameta
28 * @title: GstVideoCodecAlphaMeta
29 * @short_description: GstMeta that can carry an extra buffer holding an
30 * encoded a frame whith luma that can be used as an alpha channel.
31 *
32 * This meta is primarily for internal use in GStreamer elements to support
33 * VP8/VP9 transparent video stored into WebM or Matroska containers, or
34 * transparent static AV1 images. Nothing prevents you from using this meta
35 * for custom purposes, but it generally can't be used to easily to add support
36 * for alpha channels to CODECs or formats that don't support that out of the
37 * box.
38 *
39 * Since: 1.20
40 */
41
42 /**
43 * gst_video_codec_alpha_meta_api_get_type:
44 *
45 * Returns: #GType for the #GstVideoCodecAlphaMeta structure.
46 *
47 * Since: 1.20
48 */
49 GType
gst_video_codec_alpha_meta_api_get_type(void)50 gst_video_codec_alpha_meta_api_get_type (void)
51 {
52 static GType type = 0;
53 static const gchar *tags[] = { GST_META_TAG_VIDEO_STR, NULL };
54
55 if (g_once_init_enter (&type)) {
56 GType _type =
57 gst_meta_api_type_register ("GstVideoCodecAlphaMetaAPI", tags);
58 g_once_init_leave (&type, _type);
59 }
60 return type;
61 }
62
63 static gboolean
gst_video_codec_alpha_meta_transform(GstBuffer * dest,GstMeta * meta,GstBuffer * buffer,GQuark type,gpointer data)64 gst_video_codec_alpha_meta_transform (GstBuffer * dest,
65 GstMeta * meta, GstBuffer * buffer, GQuark type, gpointer data)
66 {
67 GstVideoCodecAlphaMeta *dmeta, *smeta;
68
69 smeta = (GstVideoCodecAlphaMeta *) meta;
70
71 if (GST_META_TRANSFORM_IS_COPY (type)) {
72 dmeta =
73 (GstVideoCodecAlphaMeta *) gst_buffer_add_meta (dest,
74 GST_VIDEO_CODEC_ALPHA_META_INFO, NULL);
75
76 if (!dmeta)
77 return FALSE;
78
79 dmeta->buffer = gst_buffer_ref (smeta->buffer);
80 }
81 return TRUE;
82 }
83
84 static gboolean
gst_video_codec_alpha_meta_init(GstMeta * meta,gpointer params,GstBuffer * buffer)85 gst_video_codec_alpha_meta_init (GstMeta * meta, gpointer params,
86 GstBuffer * buffer)
87 {
88 GstVideoCodecAlphaMeta *ca_meta = (GstVideoCodecAlphaMeta *) meta;
89
90 /* the buffer ownership is transfered to the Meta */
91 ca_meta->buffer = (GstBuffer *) params;
92
93 return TRUE;
94 }
95
96 static void
gst_video_codec_alpha_meta_free(GstMeta * meta,GstBuffer * buffer)97 gst_video_codec_alpha_meta_free (GstMeta * meta, GstBuffer * buffer)
98 {
99 GstVideoCodecAlphaMeta *ca_meta = (GstVideoCodecAlphaMeta *) meta;
100 gst_clear_buffer (&ca_meta->buffer);
101 }
102
103 /**
104 * gst_video_codec_alpha_meta_get_info:
105 *
106 * Returns: #GstMetaInfo pointer that describes #GstVideoCodecAlphaMeta.
107 *
108 * Since: 1.20
109 */
110 const GstMetaInfo *
gst_video_codec_alpha_meta_get_info(void)111 gst_video_codec_alpha_meta_get_info (void)
112 {
113 static const GstMetaInfo *info = NULL;
114
115 if (g_once_init_enter ((GstMetaInfo **) & info)) {
116 const GstMetaInfo *meta =
117 gst_meta_register (GST_VIDEO_CODEC_ALPHA_META_API_TYPE,
118 "GstVideoCodecAlphaMeta",
119 sizeof (GstVideoCodecAlphaMeta),
120 gst_video_codec_alpha_meta_init,
121 gst_video_codec_alpha_meta_free,
122 gst_video_codec_alpha_meta_transform);
123 g_once_init_leave ((GstMetaInfo **) & info, (GstMetaInfo *) meta);
124 }
125
126 return info;
127 }
128
129 /**
130 * gst_buffer_add_video_codec_alpha_meta:
131 * @buffer: (transfer none): a #GstBuffer
132 * @alpha_buffer: (transfer full): a #GstBuffer
133 *
134 * Attaches a #GstVideoCodecAlphaMeta metadata to @buffer with
135 * the given alpha buffer.
136 *
137 * Returns: (transfer none): the #GstVideoCodecAlphaMeta on @buffer.
138 *
139 * Since: 1.20
140 */
141 GstVideoCodecAlphaMeta *
gst_buffer_add_video_codec_alpha_meta(GstBuffer * buffer,GstBuffer * alpha_buffer)142 gst_buffer_add_video_codec_alpha_meta (GstBuffer * buffer,
143 GstBuffer * alpha_buffer)
144 {
145 GstVideoCodecAlphaMeta *meta;
146
147 g_return_val_if_fail (buffer != NULL, NULL);
148 g_return_val_if_fail (alpha_buffer != NULL, NULL);
149
150 meta =
151 (GstVideoCodecAlphaMeta *) gst_buffer_add_meta (buffer,
152 GST_VIDEO_CODEC_ALPHA_META_INFO, alpha_buffer);
153
154 return meta;
155 }
156