1 /* GStreamer
2 * Copyright (C) 2019 Seungha Yang <seungha.yang@navercorp.com>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19
20 #ifdef HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23
24 #include "gstvp9picture.h"
25
26 GST_DEBUG_CATEGORY_EXTERN (gst_vp9_decoder_debug);
27 #define GST_CAT_DEFAULT gst_vp9_decoder_debug
28
29 GST_DEFINE_MINI_OBJECT_TYPE (GstVp9Picture, gst_vp9_picture);
30
31 static void
_gst_vp9_picture_free(GstVp9Picture * picture)32 _gst_vp9_picture_free (GstVp9Picture * picture)
33 {
34 GST_TRACE ("Free picture %p", picture);
35
36 if (picture->notify)
37 picture->notify (picture->user_data);
38
39 g_free (picture);
40 }
41
42 /**
43 * gst_vp9_picture_new:
44 *
45 * Create new #GstVp9Picture
46 *
47 * Returns: a new #GstVp9Picture
48 */
49 GstVp9Picture *
gst_vp9_picture_new(void)50 gst_vp9_picture_new (void)
51 {
52 GstVp9Picture *pic;
53
54 pic = g_new0 (GstVp9Picture, 1);
55
56 gst_mini_object_init (GST_MINI_OBJECT_CAST (pic), 0,
57 GST_TYPE_VP9_PICTURE, NULL, NULL,
58 (GstMiniObjectFreeFunction) _gst_vp9_picture_free);
59
60 GST_TRACE ("New picture %p", pic);
61
62 return pic;
63 }
64
65 /**
66 * gst_vp9_picture_set_user_data:
67 * @picture: a #GstVp9Picture
68 * @user_data: private data
69 * @notify: (closure user_data): a #GDestroyNotify
70 *
71 * Sets @user_data on the picture and the #GDestroyNotify that will be called when
72 * the picture is freed.
73 *
74 * If a @user_data was previously set, then the previous set @notify will be called
75 * before the @user_data is replaced.
76 */
77 void
gst_vp9_picture_set_user_data(GstVp9Picture * picture,gpointer user_data,GDestroyNotify notify)78 gst_vp9_picture_set_user_data (GstVp9Picture * picture, gpointer user_data,
79 GDestroyNotify notify)
80 {
81 g_return_if_fail (GST_IS_VP9_PICTURE (picture));
82
83 if (picture->notify)
84 picture->notify (picture->user_data);
85
86 picture->user_data = user_data;
87 picture->notify = notify;
88 }
89
90 /**
91 * gst_vp9_picture_get_user_data:
92 * @picture: a #GstVp9Picture
93 *
94 * Gets private data set on the picture via
95 * gst_vp9_picture_set_user_data() previously.
96 *
97 * Returns: (transfer none): The previously set user_data
98 */
99 gpointer
gst_vp9_picture_get_user_data(GstVp9Picture * picture)100 gst_vp9_picture_get_user_data (GstVp9Picture * picture)
101 {
102 return picture->user_data;
103 }
104
105 /**
106 * gst_vp9_dpb_new: (skip)
107 *
108 * Create new #GstVp9Dpb
109 *
110 * Returns: a new #GstVp9Dpb
111 */
112 GstVp9Dpb *
gst_vp9_dpb_new(void)113 gst_vp9_dpb_new (void)
114 {
115 GstVp9Dpb *dpb;
116
117 dpb = g_new0 (GstVp9Dpb, 1);
118
119 return dpb;
120 }
121
122 /**
123 * gst_vp9_dpb_free:
124 * @dpb: a #GstVp9Dpb to free
125 *
126 * Free the @dpb
127 */
128 void
gst_vp9_dpb_free(GstVp9Dpb * dpb)129 gst_vp9_dpb_free (GstVp9Dpb * dpb)
130 {
131 g_return_if_fail (dpb != NULL);
132
133 gst_vp9_dpb_clear (dpb);
134 g_free (dpb);
135 }
136
137 /**
138 * gst_vp9_dpb_clear:
139 * @dpb: a #GstVp9Dpb
140 *
141 * Clear all stored #GstVp9Picture
142 */
143 void
gst_vp9_dpb_clear(GstVp9Dpb * dpb)144 gst_vp9_dpb_clear (GstVp9Dpb * dpb)
145 {
146 gint i;
147
148 g_return_if_fail (dpb != NULL);
149
150 for (i = 0; i < GST_VP9_REF_FRAMES; i++)
151 gst_vp9_picture_clear (&dpb->pic_list[i]);
152 }
153
154 /**
155 * gst_vp9_dpb_add:
156 * @dpb: a #GstVp9Dpb
157 * @picture: (transfer full): a #GstVp9Picture
158 *
159 * Store the @picture
160 */
161 void
gst_vp9_dpb_add(GstVp9Dpb * dpb,GstVp9Picture * picture)162 gst_vp9_dpb_add (GstVp9Dpb * dpb, GstVp9Picture * picture)
163 {
164 guint8 refresh_frame_flags;
165 gint i;
166
167 g_return_if_fail (dpb != NULL);
168 g_return_if_fail (GST_IS_VP9_PICTURE (picture));
169
170 if (picture->frame_hdr.frame_type == GST_VP9_KEY_FRAME) {
171 refresh_frame_flags = (1 << GST_VP9_REF_FRAMES) - 1;
172 GST_TRACE ("keyframe, fill to all pictures");
173 } else {
174 refresh_frame_flags = picture->frame_hdr.refresh_frame_flags;
175 GST_TRACE ("non-keyframe, refresh frame flags 0x%x", refresh_frame_flags);
176 }
177
178 for (i = 0; i < GST_VP9_REF_FRAMES; i++) {
179 if (refresh_frame_flags & 0x1) {
180 gst_vp9_picture_replace (&dpb->pic_list[i], picture);
181 }
182
183 refresh_frame_flags >>= 1;
184 }
185
186 gst_vp9_picture_unref (picture);
187 }
188