• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* GStreamer
2  * Copyright (C) 2008 David Schleef <ds@schleef.org>
3  * Copyright (C) 2012 Collabora Ltd.
4  *	Author : Edward Hervey <edward@collabora.com>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20  */
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24 
25 #include <gst/video/video.h>
26 #include "gstvideoutils.h"
27 
28 /**
29  * SECTION:gstvideoutils
30  * @title: GstVideo Codec utility function
31  * @short_description: Extra utility functions for video codecs
32  */
33 
34 #include <string.h>
35 
36 G_DEFINE_BOXED_TYPE (GstVideoCodecFrame, gst_video_codec_frame,
37     (GBoxedCopyFunc) gst_video_codec_frame_ref,
38     (GBoxedFreeFunc) gst_video_codec_frame_unref);
39 
40 static void
_gst_video_codec_frame_free(GstVideoCodecFrame * frame)41 _gst_video_codec_frame_free (GstVideoCodecFrame * frame)
42 {
43   g_return_if_fail (frame != NULL);
44 
45   GST_DEBUG ("free frame %p", frame);
46 
47   if (frame->input_buffer) {
48     gst_buffer_unref (frame->input_buffer);
49   }
50 
51   if (frame->output_buffer) {
52     gst_buffer_unref (frame->output_buffer);
53   }
54 
55   g_list_free_full (frame->events, (GDestroyNotify) gst_event_unref);
56   frame->events = NULL;
57 
58   if (frame->user_data_destroy_notify)
59     frame->user_data_destroy_notify (frame->user_data);
60 
61   g_slice_free (GstVideoCodecFrame, frame);
62 }
63 
64 /**
65  * gst_video_codec_frame_set_user_data:
66  * @frame: a #GstVideoCodecFrame
67  * @user_data: private data
68  * @notify: (closure user_data): a #GDestroyNotify
69  *
70  * Sets @user_data on the frame and the #GDestroyNotify that will be called when
71  * the frame is freed. Allows to attach private data by the subclass to frames.
72  *
73  * If a @user_data was previously set, then the previous set @notify will be called
74  * before the @user_data is replaced.
75  */
76 void
gst_video_codec_frame_set_user_data(GstVideoCodecFrame * frame,gpointer user_data,GDestroyNotify notify)77 gst_video_codec_frame_set_user_data (GstVideoCodecFrame * frame,
78     gpointer user_data, GDestroyNotify notify)
79 {
80   if (frame->user_data_destroy_notify)
81     frame->user_data_destroy_notify (frame->user_data);
82 
83   frame->user_data = user_data;
84   frame->user_data_destroy_notify = notify;
85 }
86 
87 /**
88  * gst_video_codec_frame_get_user_data:
89  * @frame: a #GstVideoCodecFrame
90  *
91  * Gets private data set on the frame by the subclass via
92  * gst_video_codec_frame_set_user_data() previously.
93  *
94  * Returns: (transfer none): The previously set user_data
95  */
96 gpointer
gst_video_codec_frame_get_user_data(GstVideoCodecFrame * frame)97 gst_video_codec_frame_get_user_data (GstVideoCodecFrame * frame)
98 {
99   return frame->user_data;
100 }
101 
102 /**
103  * gst_video_codec_frame_ref:
104  * @frame: a #GstVideoCodecFrame
105  *
106  * Increases the refcount of the given frame by one.
107  *
108  * Returns: @buf
109  */
110 GstVideoCodecFrame *
gst_video_codec_frame_ref(GstVideoCodecFrame * frame)111 gst_video_codec_frame_ref (GstVideoCodecFrame * frame)
112 {
113   g_return_val_if_fail (frame != NULL, NULL);
114 
115   GST_TRACE ("%p ref %d->%d", frame, frame->ref_count, frame->ref_count + 1);
116 
117   g_atomic_int_inc (&frame->ref_count);
118 
119   return frame;
120 }
121 
122 /**
123  * gst_video_codec_frame_unref:
124  * @frame: a #GstVideoCodecFrame
125  *
126  * Decreases the refcount of the frame. If the refcount reaches 0, the frame
127  * will be freed.
128  */
129 void
gst_video_codec_frame_unref(GstVideoCodecFrame * frame)130 gst_video_codec_frame_unref (GstVideoCodecFrame * frame)
131 {
132   g_return_if_fail (frame != NULL);
133   g_return_if_fail (frame->ref_count > 0);
134 
135   GST_TRACE ("%p unref %d->%d", frame, frame->ref_count, frame->ref_count - 1);
136 
137   if (g_atomic_int_dec_and_test (&frame->ref_count)) {
138     _gst_video_codec_frame_free (frame);
139   }
140 }
141 
142 
143 /**
144  * gst_video_codec_state_ref:
145  * @state: a #GstVideoCodecState
146  *
147  * Increases the refcount of the given state by one.
148  *
149  * Returns: @buf
150  */
151 GstVideoCodecState *
gst_video_codec_state_ref(GstVideoCodecState * state)152 gst_video_codec_state_ref (GstVideoCodecState * state)
153 {
154   g_return_val_if_fail (state != NULL, NULL);
155 
156   GST_TRACE ("%p ref %d->%d", state, state->ref_count, state->ref_count + 1);
157 
158   g_atomic_int_inc (&state->ref_count);
159 
160   return state;
161 }
162 
163 static void
_gst_video_codec_state_free(GstVideoCodecState * state)164 _gst_video_codec_state_free (GstVideoCodecState * state)
165 {
166   GST_DEBUG ("free state %p", state);
167 
168   if (state->caps)
169     gst_caps_unref (state->caps);
170   if (state->allocation_caps)
171     gst_caps_unref (state->allocation_caps);
172   if (state->codec_data)
173     gst_buffer_unref (state->codec_data);
174   if (state->mastering_display_info)
175     g_slice_free (GstVideoMasteringDisplayInfo, state->mastering_display_info);
176   if (state->content_light_level)
177     g_slice_free (GstVideoContentLightLevel, state->content_light_level);
178   g_slice_free (GstVideoCodecState, state);
179 }
180 
181 /**
182  * gst_video_codec_state_unref:
183  * @state: a #GstVideoCodecState
184  *
185  * Decreases the refcount of the state. If the refcount reaches 0, the state
186  * will be freed.
187  */
188 void
gst_video_codec_state_unref(GstVideoCodecState * state)189 gst_video_codec_state_unref (GstVideoCodecState * state)
190 {
191   g_return_if_fail (state != NULL);
192   g_return_if_fail (state->ref_count > 0);
193 
194   GST_TRACE ("%p unref %d->%d", state, state->ref_count, state->ref_count - 1);
195 
196   if (g_atomic_int_dec_and_test (&state->ref_count)) {
197     _gst_video_codec_state_free (state);
198   }
199 }
200 
201 G_DEFINE_BOXED_TYPE (GstVideoCodecState, gst_video_codec_state,
202     (GBoxedCopyFunc) gst_video_codec_state_ref,
203     (GBoxedFreeFunc) gst_video_codec_state_unref);
204