• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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