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